import * as PIXI from 'pixi.js'; 
 | 
import * as TWEEDLE from 'tweedle.js'; 
 | 
import Http from '@/utils/http'; 
 | 
import { message } from 'antd'; 
 | 
import { API_TIMEOUT } from '@/config/setting' 
 | 
  
 | 
import agv from '/public/img/map/agv.svg' 
 | 
import shelf from '/public/img/map/shelf.png' 
 | 
import conveyor from '/public/img/map/conveyor.png' 
 | 
import point from '/public/img/map/point.svg' 
 | 
import shuttle from '/public/img/map/shuttle.svg' 
 | 
  
 | 
let app = null; 
 | 
let mapContainer = null; 
 | 
let notify = null; 
 | 
let selectedSprite, effectTick, effectHalfCircle, effectRectangle; 
 | 
  
 | 
export function syncApp(param) { 
 | 
    app = param; 
 | 
} 
 | 
  
 | 
export function syncMapContainer(param) { 
 | 
    mapContainer = param; 
 | 
} 
 | 
  
 | 
export function syncNotify(param) { 
 | 
    notify = param; 
 | 
} 
 | 
  
 | 
export function getMapContainer() { 
 | 
    return mapContainer; 
 | 
} 
 | 
  
 | 
export const MapEvent = Object.freeze({ 
 | 
    SELECTION_BOX: Symbol.for(0), 
 | 
}) 
 | 
  
 | 
export const SENSOR_TYPE = Object.freeze({ 
 | 
    SHELF: "SHELF", 
 | 
    SHUTTLE: "SHUTTLE", 
 | 
    LIFT: "LIFT", 
 | 
    CONVEYOR: "CONVEYOR", 
 | 
    POINT: "POINT", 
 | 
    AGV: "AGV", 
 | 
}) 
 | 
  
 | 
export const SENSOR_ZINDEX = Object.freeze({ 
 | 
    SHELF: 1, 
 | 
    CONVEYOR: 1, 
 | 
    POINT: 1, 
 | 
    TRAVEL_PATH: 80, 
 | 
    SHUTTLE: 100, 
 | 
    AGV: 100, 
 | 
}) 
 | 
  
 | 
export const SHELF_TYPE = Object.freeze({ 
 | 
    STORE: 0, 
 | 
    TRACK: 3, 
 | 
    LIFT: 67, 
 | 
    CHARGE: 5, 
 | 
    DISABLE: 1, 
 | 
}) 
 | 
  
 | 
export const NOTIFY_TYPE = Object.freeze({ 
 | 
    OPEN: 'open', 
 | 
    SUCCESS: 'success', 
 | 
    INFO: 'info', 
 | 
    WARNING: 'warning', 
 | 
    ERROR: 'error', 
 | 
}) 
 | 
  
 | 
export const getRealPosition = (x, y, mapContainer) => { 
 | 
    const rect = app.view.getBoundingClientRect(); 
 | 
    return { 
 | 
        mapX: (x - rect.left) / mapContainer.scale.x - mapContainer.x / mapContainer.scale.x, 
 | 
        mapY: (y - rect.top) / mapContainer.scale.y - mapContainer.y / mapContainer.scale.y 
 | 
    } 
 | 
} 
 | 
  
 | 
export const generateSprite = (sensorType) => { 
 | 
    let sprite; 
 | 
    switch (sensorType) { 
 | 
        case SENSOR_TYPE.SHUTTLE: 
 | 
            sprite = new PIXI.Sprite(PIXI.Texture.from(shuttle, { resourceOptions: { scale: 5 } })); 
 | 
            sprite.width = 50; 
 | 
            sprite.height = 50; 
 | 
            sprite.zIndex = SENSOR_ZINDEX.SHUTTLE; 
 | 
            break; 
 | 
        case SENSOR_TYPE.AGV: 
 | 
            sprite = new PIXI.Sprite(PIXI.Texture.from(agv, { resourceOptions: { scale: 5 } })); 
 | 
            sprite.width = 50; 
 | 
            sprite.height = 50; 
 | 
            sprite.zIndex = SENSOR_ZINDEX.AGV; 
 | 
            break; 
 | 
        case SENSOR_TYPE.SHELF: 
 | 
            sprite = new PIXI.Sprite(PIXI.Texture.from(shelf, { resourceOptions: { scale: 1 } })); 
 | 
            sprite.width = 60; 
 | 
            sprite.height = 60; 
 | 
            sprite.zIndex = SENSOR_ZINDEX.SHELF; 
 | 
            break; 
 | 
        case SENSOR_TYPE.CONVEYOR: 
 | 
            sprite = new PIXI.Sprite(PIXI.Texture.from(conveyor, { resourceOptions: { scale: 5 } })); 
 | 
            sprite.width = 112; 
 | 
            sprite.height = 63; 
 | 
            sprite.zIndex = SENSOR_ZINDEX.CONVEYOR; 
 | 
            break; 
 | 
        case SENSOR_TYPE.POINT: 
 | 
            sprite = new PIXI.Sprite(PIXI.Texture.from(point, { resourceOptions: { scale: 5 } })); 
 | 
            sprite.width = 10; 
 | 
            sprite.height = 10; 
 | 
            sprite.zIndex = SENSOR_ZINDEX.POINT; 
 | 
            break; 
 | 
        default: 
 | 
            break; 
 | 
    } 
 | 
    return sprite; 
 | 
} 
 | 
  
 | 
export const initSprite = (sprite, type) => { 
 | 
    sprite.anchor.set(0.5); 
 | 
    sprite.cursor = 'pointer'; 
 | 
    sprite.eventMode = 'static'; 
 | 
    sprite.data = { 
 | 
        type: type, 
 | 
        uuid: generateID() 
 | 
    }; 
 | 
} 
 | 
  
 | 
export const querySprite = (type, no) => { 
 | 
    if (!mapContainer) { 
 | 
        return; 
 | 
    } 
 | 
    for (const sprite of mapContainer.children) { 
 | 
        if (sprite.data?.type === type && sprite.data?.no === no) { 
 | 
            return sprite; 
 | 
        } 
 | 
    } 
 | 
} 
 | 
  
 | 
// show sprite feature from sprite click event 
 | 
export const viewFeature = (sprite, setCurSPrite) => { 
 | 
    sprite.off('pointerup'); 
 | 
    sprite.off('pointermove'); 
 | 
    sprite.off('pointerdown'); 
 | 
    sprite.off('click'); 
 | 
  
 | 
    sprite.on("click", onClick); 
 | 
  
 | 
    function onClick(event) { 
 | 
        setCurSPrite(sprite); 
 | 
    } 
 | 
  
 | 
} 
 | 
  
 | 
// sprite be movable from sprite click event 
 | 
export const beMovable = (sprite) => { 
 | 
    sprite.off('pointerup'); 
 | 
    sprite.off('pointermove'); 
 | 
    sprite.off('pointerdown'); 
 | 
    sprite.off('click'); 
 | 
  
 | 
    sprite.on("pointerdown", onDragStart); 
 | 
  
 | 
    let dragTarget; 
 | 
    function onDragStart(event) { 
 | 
        if (event.button === 0) { 
 | 
            dragTarget = event.currentTarget; 
 | 
            mapContainer.parent.off('pointermove'); 
 | 
            mapContainer.parent.on('pointermove', onDragMove, dragTarget); 
 | 
  
 | 
            mapContainer.parent.off('pointerup'); 
 | 
            mapContainer.parent.on('pointerup', onDragEnd.bind(mapContainer)); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    function onDragMove(event) { 
 | 
        if (this) { 
 | 
            this.parent.toLocal(event.global, null, this.position); 
 | 
        } 
 | 
    } 
 | 
  
 | 
    function onDragEnd() { 
 | 
        if (dragTarget) { 
 | 
            this.parent.off('pointermove'); 
 | 
            this.parent.off('pointerup'); 
 | 
            dragTarget.alpha = 1; 
 | 
            dragTarget = null; 
 | 
        } 
 | 
    } 
 | 
  
 | 
} 
 | 
  
 | 
// sprite be beSettings from sprite click event 
 | 
export const beSettings = (sprite, setSpriteBySettings) => { 
 | 
    sprite.off('pointerup'); 
 | 
    sprite.off('pointermove'); 
 | 
    sprite.off('pointerdown'); 
 | 
    sprite.off('click'); 
 | 
  
 | 
    sprite.on("click", onClick); 
 | 
  
 | 
    function onClick(event) { 
 | 
        setSpriteBySettings(sprite); 
 | 
    } 
 | 
} 
 | 
  
 | 
// sprites be movable from select box 
 | 
// the scale was dynamic 
 | 
export const spriteListBeMovable = (selectedSprites, resetFn) => { 
 | 
    if (selectedSprites && selectedSprites.length > 0) { 
 | 
        let batchMove = false; 
 | 
        let batchMoveStartPos = null; 
 | 
  
 | 
        const batchMoving = (event) => { 
 | 
            const scale = mapContainer.scale.x; 
 | 
            if (batchMove && batchMoveStartPos) { 
 | 
                // offset move val 
 | 
                var mouseMovement = { 
 | 
                    x: (event.global.x - batchMoveStartPos.x) / scale, 
 | 
                    y: (event.global.y - batchMoveStartPos.y) / scale 
 | 
                }; 
 | 
                for (let sprite of selectedSprites) { 
 | 
                    sprite.position.x = sprite.batchMoveStartPos.x + mouseMovement.x; 
 | 
                    sprite.position.y = sprite.batchMoveStartPos.y + mouseMovement.y; 
 | 
                } 
 | 
            } 
 | 
        } 
 | 
  
 | 
        const batchMoveEnd = (event) => { 
 | 
            batchMove = false; 
 | 
            batchMoveStartPos = null; 
 | 
            selectedSprites.forEach(child => { 
 | 
                unMarkSprite(child); 
 | 
            }) 
 | 
            selectedSprites = []; 
 | 
            mapContainer.parent.off('mousedown'); 
 | 
            mapContainer.parent.off('mousemove'); 
 | 
            mapContainer.parent.off('mouseup'); 
 | 
  
 | 
            if (resetFn) { 
 | 
                resetFn(); 
 | 
            } 
 | 
        } 
 | 
  
 | 
        const batchMoveStart = (event) => { 
 | 
            batchMoveStartPos = { x: event.data.global.clone().x, y: event.data.global.clone().y }; 
 | 
            selectedSprites.forEach(child => { 
 | 
                child.batchMoveStartPos = { x: child.position.x, y: child.position.y }; 
 | 
            }) 
 | 
  
 | 
            batchMove = true; 
 | 
            mapContainer.parent.off('mousemove'); 
 | 
            mapContainer.parent.on('mousemove', batchMoving); 
 | 
  
 | 
            mapContainer.parent.off('mouseup'); 
 | 
            mapContainer.parent.on('mouseup', batchMoveEnd); 
 | 
        } 
 | 
  
 | 
        mapContainer.parent.off('mousedown') 
 | 
        mapContainer.parent.on('mousedown', batchMoveStart); 
 | 
    } 
 | 
} 
 | 
  
 | 
export const isSpriteInSelectionBox = (sprite, selectionBox) => { 
 | 
    const spriteBounds = sprite.getBounds(); 
 | 
    const boxBounds = selectionBox.getBounds(); 
 | 
  
 | 
    return spriteBounds.x + spriteBounds.width > boxBounds.x 
 | 
        && spriteBounds.x < boxBounds.x + boxBounds.width 
 | 
        && spriteBounds.y + spriteBounds.height > boxBounds.y 
 | 
        && spriteBounds.y < boxBounds.y + boxBounds.height; 
 | 
} 
 | 
  
 | 
export const showSelectedEffect = (sprite) => { 
 | 
    const { width, height } = sprite; 
 | 
    const scale = sprite.scale.x; 
 | 
    const sideLen = (Math.max(width, height) + 10) * scale; 
 | 
    const color = app.renderer.backgroundColor === '#f1f2f6' ? 0x273c75 : 0xffffff; 
 | 
  
 | 
    effectHalfCircle = new PIXI.Graphics(); 
 | 
    effectHalfCircle.beginFill(color); 
 | 
    effectHalfCircle.lineStyle(2 * scale, color); 
 | 
    effectHalfCircle.arc(0, 0, sideLen, 0, Math.PI); 
 | 
    effectHalfCircle.endFill(); 
 | 
    effectHalfCircle.position.set(sprite.x, sprite.y); 
 | 
    effectHalfCircle.scale.set(1 / scale); 
 | 
    effectHalfCircle.zIndex = 9999; 
 | 
  
 | 
    effectRectangle = new PIXI.Graphics(); 
 | 
    effectRectangle.lineStyle(5 * scale, color, 1); 
 | 
    effectRectangle.drawRoundedRect(0, 0, sideLen, sideLen, 16 * scale); 
 | 
    effectRectangle.endFill(); 
 | 
    effectRectangle.mask = effectHalfCircle; 
 | 
    effectRectangle.zIndex = 9999; 
 | 
  
 | 
    const scaledWidth = sideLen * (1 / scale); 
 | 
    const scaledHeight = sideLen * (1 / scale); 
 | 
  
 | 
    effectRectangle.scale.set(1 / scale); 
 | 
    effectRectangle.position.set(sprite.x - scaledWidth / 2, sprite.y - scaledHeight / 2); 
 | 
  
 | 
    mapContainer.addChild(effectRectangle); 
 | 
    mapContainer.addChild(effectHalfCircle); 
 | 
  
 | 
    selectedSprite = sprite; 
 | 
  
 | 
    let phase = 0; 
 | 
    effectTick = (delta) => { 
 | 
        phase += delta / 10; 
 | 
        phase %= (Math.PI * 2); 
 | 
        if (effectHalfCircle) { 
 | 
            effectHalfCircle.rotation = phase; 
 | 
        } 
 | 
    }; 
 | 
  
 | 
    app.ticker.add(effectTick); 
 | 
} 
 | 
  
 | 
export const updateEffect = (sprite) => { 
 | 
    if (!sprite || sprite !== selectedSprite || !effectRectangle || !effectHalfCircle) { 
 | 
        return 
 | 
    } 
 | 
    const { width, height } = sprite; 
 | 
    const scale = sprite.scale.x; 
 | 
    const sideLen = (Math.max(width, height) + 10) * scale; 
 | 
    const scaledWidth = sideLen * (1 / scale); 
 | 
    const scaledHeight = sideLen * (1 / scale); 
 | 
  
 | 
    effectRectangle.position.set(sprite.x - scaledWidth / 2, sprite.y - scaledHeight / 2); 
 | 
  
 | 
    effectHalfCircle.position.set(sprite.x, sprite.y); 
 | 
} 
 | 
  
 | 
export const removeSelectedEffect = () => { 
 | 
    if (effectTick) { 
 | 
        app.ticker.remove(effectTick); 
 | 
    } 
 | 
    if (effectHalfCircle) { 
 | 
        mapContainer.removeChild(effectHalfCircle); 
 | 
        effectHalfCircle = null; 
 | 
    } 
 | 
    if (effectRectangle) { 
 | 
        mapContainer.removeChild(effectRectangle); 
 | 
        effectRectangle = null; 
 | 
    } 
 | 
    selectedSprite = null; 
 | 
} 
 | 
  
 | 
export const copySprite = (sprite) => { 
 | 
    const copiedSprite = generateSprite(sprite.data.type) 
 | 
    initSprite(copiedSprite); 
 | 
    copiedSprite.position.set(sprite.position.x, sprite.position.y); 
 | 
    copiedSprite.scale.set(sprite.scale.x, sprite.scale.y); 
 | 
    copiedSprite.rotation = sprite.rotation; 
 | 
    copiedSprite.data = deepCopy(sprite.data); 
 | 
    copiedSprite.data.uuid = generateID(); 
 | 
    if (copiedSprite.data.type === SENSOR_TYPE.SHELF) { 
 | 
        showSheflType(copiedSprite); 
 | 
    } 
 | 
    return copiedSprite; 
 | 
} 
 | 
  
 | 
export const markSprite = (sprite) => { 
 | 
    sprite.alpha = 0.5; 
 | 
} 
 | 
  
 | 
export const unMarkSprite = (sprite) => { 
 | 
    sprite.alpha = 1; 
 | 
} 
 | 
  
 | 
export const generateID = () => { 
 | 
    return Date.now().toString(36) + Math.random().toString(36).substring(2); 
 | 
} 
 | 
  
 | 
export const deepCopy = (data) => { 
 | 
    return JSON.parse(JSON.stringify(data)); 
 | 
} 
 | 
  
 | 
export const pureNumStr = (param) => { 
 | 
    if (param) { 
 | 
        return Number(param); 
 | 
    } else { 
 | 
        return ''; 
 | 
    } 
 | 
} 
 | 
  
 | 
export const rotationToNum = (rotation) => { 
 | 
    let res = rotation * 180 / Math.PI; 
 | 
    if (res < 0) { 
 | 
        res += 360; 
 | 
    } else if (res > 360) { 
 | 
        res -= 360; 
 | 
    } 
 | 
    return res; 
 | 
} 
 | 
  
 | 
export const rotationParseNum = (num) => { 
 | 
    return num * Math.PI / 180; 
 | 
} 
 | 
  
 | 
export const findSpriteByUuid = (uuid) => { 
 | 
    return mapContainer?.children?.find(child => child?.data?.uuid === uuid); 
 | 
} 
 | 
  
 | 
export const fetchMapFloor = async () => { 
 | 
    const res = await Http.doPost('api/map/floor/list'); 
 | 
    if (res.code === 200) { 
 | 
        return eval(res.data); 
 | 
    } else { 
 | 
        mapNotify(res.msg, NOTIFY_TYPE.ERROR); 
 | 
    } 
 | 
} 
 | 
  
 | 
export const fetchMapData = async (curFloor) => { 
 | 
    clearMapData(); 
 | 
    await Http.doPostPromise('api/map/list', { floor: curFloor }, (res) => { 
 | 
        const mapItemList = eval(res.data); 
 | 
        mapItemList.forEach(item => { 
 | 
            if (!( 
 | 
                item.type === SENSOR_TYPE.SHUTTLE 
 | 
                || item.type === SENSOR_TYPE.AGV 
 | 
            )) { 
 | 
                const sprite = generateSprite(item.type); 
 | 
                if (sprite) { 
 | 
                    initSprite(sprite, item.type); 
 | 
                    // data 
 | 
                    sprite.data.uuid = item.uuid; 
 | 
                    sprite.data.no = item.no; 
 | 
  
 | 
                    // dynamical data 
 | 
                    Object.assign(sprite.data, item.property); 
 | 
  
 | 
                    showSheflType(sprite); 
 | 
                    // graph 
 | 
                    setTimeout(() => { 
 | 
                        sprite.position.set(item.positionX, item.positionY); 
 | 
                        sprite.scale.set(item.scaleX, item.scaleY); 
 | 
                        sprite.rotation = rotationParseNum(item.rotation); 
 | 
                    }, 50); 
 | 
  
 | 
                    mapContainer.addChild(sprite); 
 | 
                } 
 | 
            } 
 | 
        }) 
 | 
  
 | 
    }).catch((error) => { 
 | 
        console.error(error); 
 | 
    }) 
 | 
} 
 | 
  
 | 
export const saveMapData = async (intl, floor) => { 
 | 
    if (!mapContainer) { 
 | 
        return; 
 | 
    } 
 | 
  
 | 
    let mapItemList = []; 
 | 
    mapContainer?.children.forEach(child => { 
 | 
        if (child.data?.uuid) { 
 | 
            const { type, uuid, no, ...property } = child.data; 
 | 
            if (!( 
 | 
                type === SENSOR_TYPE.SHUTTLE 
 | 
                || type === SENSOR_TYPE.AGV 
 | 
            )) { 
 | 
                mapItemList.push({ 
 | 
                    // data 
 | 
                    type: type, 
 | 
                    uuid: uuid, 
 | 
                    no: no, 
 | 
                    property: property, 
 | 
  
 | 
                    // graph 
 | 
                    positionX: child.position.x, 
 | 
                    positionY: child.position.y, 
 | 
                    scaleX: child.scale.x, 
 | 
                    scaleY: child.scale.y, 
 | 
                    rotation: rotationToNum(child.rotation) 
 | 
                }) 
 | 
            } 
 | 
        } 
 | 
    }) 
 | 
  
 | 
    const closeLoading = message.loading({ content: intl.formatMessage({ id: 'common.loading.api.message', defaultMessage: '等待服务器......' }), duration: API_TIMEOUT }); 
 | 
    await Http.doPostPromise('api/map/save', { 
 | 
        itemList: mapItemList, 
 | 
        floor: floor 
 | 
    }, (res) => { 
 | 
        closeLoading(); 
 | 
    }).catch((error) => { 
 | 
        closeLoading(); 
 | 
        console.error(error); 
 | 
    }) 
 | 
} 
 | 
  
 | 
export const clearMapData = (intl) => { 
 | 
    if (!mapContainer) { 
 | 
        return; 
 | 
    } 
 | 
    let childList = []; 
 | 
    mapContainer.children.forEach(child => { 
 | 
        if (child.data?.uuid) { 
 | 
            childList.push(child); 
 | 
        } 
 | 
    }) 
 | 
    if (childList.length > 0) { 
 | 
        childList.forEach(child => { 
 | 
            mapContainer.removeChild(child); 
 | 
            child.destroy({ children: true, texture: false, baseTexture: false }); 
 | 
        }) 
 | 
        childList.forEach((child, index) => { 
 | 
            childList[index] = null; 
 | 
        }); 
 | 
        childList = []; 
 | 
    } 
 | 
} 
 | 
  
 | 
export const beCenter = (sprite) => { 
 | 
    if (!sprite || !app || !mapContainer) { 
 | 
        return; 
 | 
    } 
 | 
  
 | 
    mapContainer.scale.set(1); 
 | 
    mapContainer.position.set(0, 0); 
 | 
  
 | 
    let bounds = sprite.getBounds(); 
 | 
    let centerPoint = { 
 | 
        x: bounds.x + bounds.width / 2, 
 | 
        y: bounds.y + bounds.height / 2 
 | 
    }; 
 | 
  
 | 
    let targetPos = { 
 | 
        x: app.renderer.width / 3 - centerPoint.x * mapContainer.scale.x, 
 | 
        y: app.renderer.height / 3 - centerPoint.y * mapContainer.scale.y 
 | 
    }; 
 | 
  
 | 
    new TWEEDLE.Tween(mapContainer.position).easing(TWEEDLE.Easing.Quadratic.Out) 
 | 
        .to(targetPos, 500).start(); 
 | 
} 
 | 
  
 | 
export const mapNotify = (msg, type = NOTIFY_TYPE.OPEN) => { 
 | 
    notify[type]({ 
 | 
        description: msg, 
 | 
        duration: 1.5, 
 | 
        style: { width: 300 }, 
 | 
        placement: 'bottom', 
 | 
        closeIcon: false, 
 | 
        onClick: () => { } 
 | 
    }); 
 | 
} 
 | 
  
 | 
export const showSheflType = (sprite) => { 
 | 
    let showColor; 
 | 
    switch (sprite.data.shelfType) { 
 | 
        case SHELF_TYPE.STORE: 
 | 
            break; 
 | 
        case SHELF_TYPE.TRACK: 
 | 
            showColor = '#faf6e9'; 
 | 
            break; 
 | 
        case SHELF_TYPE.LIFT: 
 | 
            showColor = '#EBDEF0'; 
 | 
            break; 
 | 
        case SHELF_TYPE.CHARGE: 
 | 
            showColor = '#D4EFDF'; 
 | 
            break; 
 | 
        case SHELF_TYPE.DISABLE: 
 | 
            showColor = '#ffc8c8'; 
 | 
            break; 
 | 
        default: 
 | 
            break; 
 | 
    } 
 | 
    if (showColor) { 
 | 
        sprite.tint = showColor; 
 | 
    } else { 
 | 
        sprite.tint = 0xFFFFFF;  // recovery 
 | 
    } 
 | 
    return showColor; 
 | 
} 
 | 
  
 | 
export const waitTime = (time = 1000) => { 
 | 
    return new Promise((resolve) => { 
 | 
        setTimeout(() => { 
 | 
            resolve(true); 
 | 
        }, time); 
 | 
    }); 
 | 
}; 
 | 
  
 | 
export const isNullOfUndefined = (param) => { 
 | 
    if (null === param || undefined === param) { 
 | 
        return true; 
 | 
    } else { 
 | 
        return false; 
 | 
    } 
 | 
} 
 | 
  
 | 
export const parseLocNo = (locNo) => { 
 | 
    if (!locNo || typeof locNo !== 'string') { 
 | 
        return null; 
 | 
    } 
 | 
    const locParseArr = locNo.split('-'); 
 | 
    return { 
 | 
        row: locParseArr?.[0], 
 | 
        bay: locParseArr?.[1], 
 | 
        lev: locParseArr?.[2], 
 | 
    } 
 | 
} 
 | 
  
 | 
export const generateLocNo = (row, bay, lev) => { 
 | 
    return row + '-' + bay + '-' + lev; 
 | 
} 
 | 
  
 | 
export const updateMapStatusInRealTime = (data, curFloorGetter, setCurSPrite) => { 
 | 
    const curFloor = curFloorGetter(); 
 | 
    if (isNullOfUndefined(curFloor)) { return; } 
 | 
    const mapVo = JSON.parse(data); 
 | 
    // shuttleVo 
 | 
    for (const shuttleVo of mapVo.shuttleVos) { 
 | 
        // path 
 | 
        drawTravelPath(shuttleVo, curFloor); 
 | 
        // shuttle 
 | 
        showShuttle(shuttleVo, curFloor, setCurSPrite); 
 | 
    } 
 | 
} 
 | 
  
 | 
export const drawTravelPath = (shuttleVo, curFloor) => { 
 | 
    const { shuttleNo, curLocNo, travelPath: path } = shuttleVo; 
 | 
    if (!mapContainer) { 
 | 
        return; 
 | 
    } 
 | 
    const pathLineName = 'preTravelPath-' + shuttleNo; 
 | 
    let pathLine = mapContainer.getChildByName(pathLineName); 
 | 
    if (pathLine) { 
 | 
        mapContainer.removeChild(pathLine); 
 | 
    } 
 | 
  
 | 
    pathLine = new PIXI.Graphics(); 
 | 
    pathLine.name = pathLineName; 
 | 
    pathLine.lineStyle(2 * (1 / mapContainer.scale.x), 0x3498db, 0.8); 
 | 
    pathLine.zIndex = SENSOR_ZINDEX.TRAVEL_PATH; 
 | 
    let firstNode = true; 
 | 
    for (let i = Math.max(0, path.indexOf(curLocNo) - 1); i < path.length; i++) { 
 | 
        const { row, bay, lev } = parseLocNo(path[i]); 
 | 
        if (Number(lev) !== curFloor) { continue } 
 | 
        const shelf = querySprite(SENSOR_TYPE.SHELF, row + '-' + bay); 
 | 
        if (!shelf) { continue }; 
 | 
        let position = shelf.position; 
 | 
        let x = position.x; 
 | 
        let y = position.y; 
 | 
        if (firstNode) { 
 | 
            pathLine.moveTo(x, y); 
 | 
            firstNode = false; 
 | 
        } else { 
 | 
            pathLine.lineTo(x, y); 
 | 
        } 
 | 
    } 
 | 
    mapContainer.addChild(pathLine); 
 | 
} 
 | 
  
 | 
export const showShuttle = (shuttleVo, curFloor, setCurSPrite) => { 
 | 
    const { shuttleNo, curLocNo } = shuttleVo; 
 | 
    if (!curLocNo) { return } 
 | 
    const { row, bay, lev } = parseLocNo(curLocNo); 
 | 
    if (Number(lev) !== curFloor) { return } 
 | 
  
 | 
    const shelf = querySprite(SENSOR_TYPE.SHELF, row + '-' + bay); 
 | 
    if (!shelf) { return } 
 | 
  
 | 
    let shuttle = querySprite(SENSOR_TYPE.SHUTTLE, shuttleNo); 
 | 
    if (!shuttle) { 
 | 
        shuttle = generateSprite(SENSOR_TYPE.SHUTTLE); 
 | 
        initSprite(shuttle, SENSOR_TYPE.SHUTTLE); 
 | 
        shuttle.data.no = shuttleNo; 
 | 
        shuttle.position.set(shelf.position.x, shelf.position.y); 
 | 
        mapContainer.addChild(shuttle); 
 | 
        viewFeature(shuttle, setCurSPrite); 
 | 
    } 
 | 
  
 | 
    new TWEEDLE.Tween(shuttle?.position).easing(TWEEDLE.Easing.Linear.None).to({ 
 | 
        x: shelf.position.x, 
 | 
        y: shelf.position.y 
 | 
    }, 1000).onUpdate(() => { 
 | 
        updateEffect(shuttle); 
 | 
    }).start(); 
 | 
} 
 |