import { Component, ContainerAbstract } from '@hatiolab/things-scene' import { getPopupData } from '@fmsim/api' import { MCSStatusMixin, MCSStatusMixinProperties } from './features/mcs-status-mixin' import { LEGEND_MACHINE, Legend } from './features/mcs-status-default' /** * MCS Machine의 공통 속성을 정의한 최상위 오브젝트 * - Container * - */ export default class MCSMachine extends MCSStatusMixin(ContainerAbstract) { static get properties(): any { return [ ...MCSStatusMixinProperties, { type: 'number', name: 'round', label: 'round' } ] } get showMoveHandle() { return false } /** * id 후보를 조회할 때 백엔드에 보낼 타입명. 값이 있으면 검색(lookup) 대상. * 기본은 자기 타입. 자기 타입과 다른 타입으로 조회해야 하는 특수 케이스는 override. */ get idLookupType(): string | undefined { return this.state.type } /** MCS 머신 — parentObject(부모 머신) 후보 수집 시 머신으로 식별. */ get isMcsMachine(): boolean { return true } containable(component: Component) { return ['rect', 'ellipse'].includes(component.state.type) } get decorators() { return ['decotag'] } getTheme() { const { legendName } = this.state if (legendName) { return (this.root as any)?.style?.[legendName] } } get hasTextProperty() { return true } get status() { return this.data?.STATUS } get auxStatus() { return this.data?.STATUS } get legend(): Legend { return this.getTheme() || this.getLegendFallback() } get auxLegend() { return LEGEND_MACHINE } get auxColor() { return this.state.strokeStyle } getLegendFallback() { return LEGEND_MACHINE } /** * 2D 에서는 `state.alpha`(3D material 전용)를 무시한다. hidden/모델링 dim 흐림은 **코어(draw)가 * 일괄 처리**하므로 여기서 손대지 않는다 (component-drawing.ts draw 가 prerender 직후 faint 적용). * fade 애니메이션은 보존. 3D 는 factory `updateAlpha()` 가 state.alpha 를 별도로 존중. */ prerender(ctx: any) { super.prerender(ctx) ctx.globalAlpha = 1 - this._delta.fade } render(ctx) { var { round = 0, lineWidth } = this.state var { left, top, width, height } = this.bounds ctx.beginPath() ctx.strokeStyle = this.auxColor ctx.fillStyle = this.statusColor! ctx.lineWidth = lineWidth || 1 ctx.lineCap = 'round' ctx.setLineDash([]) if (round > 0) { ctx.roundRect(left, top, width, height, round) } else { ctx.rect(left, top, width, height) } ctx.fill() ctx.stroke() } // get text() { // if (this.data?.LOCALENAME) { // // TODO 왜 LOCALENAME 데이타는 문자열인가 ? 오브젝트로 보내달라. // return JSON.parse(this.data.LOCALENAME)[getLocaleLanguage()] // } // return super.text // } // set text(text) { // super.text = text // } async detailInfo() { const { type, id } = this.state if (!id) { return } return await getPopupData(type, id) } }