import { Component } from '@hatiolab/things-scene' import { themesColorMap } from '@fmsim/api' import { LEGEND_NULL } from './mcs-status-default' type Constructor = new (...args: any[]) => T interface Legend { [key: string]: string } export const MCSStatusMixinProperties = [ { type: 'select', label: 'legend-name', name: 'legendName', property: { options: themesColorMap } } ] export function MCSStatusMixin>(Base: TBase): any { return class extends Base { isLVComponent() { return true } get status(): string | undefined { return } get auxStatus(): string | undefined { return } get legend(): Legend { return LEGEND_NULL } get auxLegend(): Legend { return LEGEND_NULL } get statusColor(): string | undefined { const status = this.status const legend = this.legend return (status && legend && (legend[status] || legend[status!] || legend.default)) || legend?.default || '#F0F0F0' } get auxColor(): string | undefined { const status = this.auxStatus const legend = this.auxLegend return (status && legend && (legend[status] || legend[status!] || legend.default)) || legend?.default } /** * 데이터 변경 시 status 기반 색상을 state.fillStyle 로 반영. * things-scene 표준 경로(updateFillStyle)가 2D/3D 모두 자동 갱신하도록 유도. * * 주의: state.fillStyle 이 runtime 색상으로 덮어써짐. 모델 저장 시 status 색상이 * 남을 수 있는 트레이드오프가 있음 (data-driven 컴포넌트의 fillStyle 은 의미상 * 초기값일 뿐 항상 status 가 덮어쓰는 것이 자연스러움). */ onchangeData(after: any, before: any) { // Base (mixin 인자) 의 onchangeData 를 렉시컬하게 호출. // Object.getPrototypeOf(this) 는 leaf 를 가리켜 무한재귀되므로 Base.prototype 직접 사용. const baseOnchange = (Base.prototype as any).onchangeData if (typeof baseOnchange === 'function') { baseOnchange.call(this, after, before) } const color = this.statusColor if (color && color !== (this as any).state?.fillStyle) { ;(this as any).setState('fillStyle', color) } } } }