/* * Copyright © HatioLab Inc. All rights reserved. */ import { Component, Shape, sceneComponent } from '@hatiolab/things-scene' import MCSMachine from './mcs-machine' const NATURE = { mutable: false, resizable: false, rotatable: false, properties: [ { type: 'string', name: 'NodeMachine', label: 'node-machine' }, { type: 'nodes', label: 'nodes', name: 'alias' } ] } @sceneComponent('Node') export default class Node extends Shape { static RADIUS = 8 is3dish() { return true } /** * Node 는 기본적으로 컨테이너 드롭 입양 불가 — 라인 머신(AGVLine/OHTLine/CraneRail)만 * 자기 containable 화이트리스트로 Node 를 받는다. 단 FloorPlate 에는 들어갈 수 있게 허용. * FloorPlate 는 things-scene 코어 컨테이너라 거기에 'Node' 를 명시할 수 없으므로 * Node 측에서 해결한다 (FloorPlate 의 기본 containable = component.isDescendible(this)). */ isDescendible(container?: any) { return container?.state?.type === 'floor-plate' } render(context) { const { cx, cy } = this.state context.beginPath() context.ellipse(cx, cy, Math.abs(Node.RADIUS) * 1, Math.abs(Node.RADIUS) * 1, 0, 0, 2 * Math.PI) context.closePath() } get path() { var { cx, cy } = this.state return [ { x: cx - Node.RADIUS * 1, y: cy - Node.RADIUS * 1 }, { x: cx + Node.RADIUS * 1, y: cy - Node.RADIUS * 1 }, { x: cx + Node.RADIUS * 1, y: cy + Node.RADIUS * 1 }, { x: cx - Node.RADIUS * 1, y: cy + Node.RADIUS * 1 } ] } set path(path) { var left_top = path[0] var right_bottom = path[2] this.set({ cx: left_top.x + (right_bottom.x - left_top.x) / 2, cy: left_top.y + (right_bottom.y - left_top.y) / 2 }) } get nodeMachine() { if (this.state.NodeMachine) { return this.state.NodeMachine } const parent = this.parent if (parent && parent instanceof MCSMachine) { return parent.state.id } } contains(x, y) { var { cx, cy } = this.state var normx = (x - cx) / (Node.RADIUS * 2) var normy = (y - cy) / (Node.RADIUS * 2) return normx * normx + normy * normy < 0.25 } outline(progress) { var { cx, cy } = this.state return this.transcoordS2T(cx, cy) } get nature() { return NATURE } } Component.memoize(Node.prototype, 'path', false)