import type { RPGActions, RPGVariables } from "../types"; import { ACTION_KEYS, VARIABLE_KEYS } from "../decorators"; export interface RPGComponent { getVariables: () => RPGVariables; getActions: () => RPGActions; } export abstract class RPGComponentBase implements RPGComponent { getVariables(): RPGVariables { const meta = (this.constructor as Function)[Symbol.metadata]; const keys = meta?.[VARIABLE_KEYS] as Map | undefined; if (!keys) return {}; const vars: RPGVariables = {}; for (const [methodKey, exportName] of keys) { const k = String(methodKey); const v = (this as unknown as Record)[k]; if (v != null) { vars[exportName] = v; } } return vars; } getActions(): RPGActions { const meta = (this.constructor as Function)[Symbol.metadata]; const keys = meta?.[ACTION_KEYS] as Set | undefined; if (!keys) return {}; const actions: RPGActions = {}; for (const key of keys) { const k = String(key); actions[k] = (arg?: unknown) => (this as unknown as Record unknown>)[k](arg); } return actions; } } export class RPGEntity implements RPGComponent { private components = new Map(); addComponent(id: string, component: RPGComponent): void { this.components.set(id, component); } removeComponent(id: string): void { this.components.delete(id); } getComponent(id: string): T | undefined { return this.components.get(id) as T | undefined; } getVariables(): RPGVariables { const variables: RPGVariables = {}; for (const [componentKey, component] of this.components) { for (const [key, value] of Object.entries(component.getVariables())) { if (value != null) { variables[`${componentKey}.${key}`] = value; } } } return variables; } getActions() { const actions: RPGActions = {}; for (const [componentKey, component] of this.components) { for (const [key, action] of Object.entries(component.getActions())) { actions[`${componentKey}.${key}`] = action; } } return actions; } }