74 lines
2.4 KiB
TypeScript
74 lines
2.4 KiB
TypeScript
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<string | symbol, string> | undefined;
|
|
if (!keys) return {};
|
|
const vars: RPGVariables = {};
|
|
for (const [methodKey, exportName] of keys) {
|
|
const k = String(methodKey);
|
|
const v = (this as unknown as Record<string, RPGVariables[string]>)[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<string | symbol> | 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<string, (a?: unknown) => unknown>)[k](arg);
|
|
}
|
|
return actions;
|
|
}
|
|
}
|
|
|
|
export class RPGEntity implements RPGComponent {
|
|
private components = new Map<string, RPGComponent>();
|
|
|
|
addComponent(id: string, component: RPGComponent): void {
|
|
this.components.set(id, component);
|
|
}
|
|
|
|
removeComponent(id: string): void {
|
|
this.components.delete(id);
|
|
}
|
|
|
|
getComponent<T extends RPGComponent>(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;
|
|
}
|
|
} |