import { displayNumber } from '../../util.js'; export class Actor { constructor(name, scene) { if (!scene) throw new Error('An actor without a scene!'); this.name = name; this.scene = scene; this.callbacks = new Map(); this.status = scene.addDisplayValue(`${this.name} status`); this.status.set('Created'); this.values = new Map(); this.valueFunctions = new Map(); this.active = 0; scene?.registerActor(this); } activate() { this.active += 1; this.scene?.sequence?.activate(this.name); } async deactivate() { if (!this.active) { throw new Error(`${this.name} is not active, can not deactivate`); } this.active -= 1; await this.scene?.sequence?.deactivate(this.name); } async send(dest, action, detail) { await action.log(this, dest, detail ? JSON.stringify(detail) : ''); await dest.recv(this, action, detail); return this; } async recv(src, action, detail) { const cb = this.callbacks.get(action.name); if (!cb) { throw new Error( `[${this.scene?.name} actor ${this.name} does not have a callback registered for ${action.name}`, ); } await cb(src, detail); return this; } on(action, cb) { this.callbacks.set(action.name, cb); return this; } setStatus(status) { this.status.set(status); return this; } async addComputedValue(label, fn) { this.values.set(label, this.scene?.addDisplayValue(`${this.name} ${label}`)); if (fn) { this.valueFunctions.set(label, fn); await this.computeValues(); } return this; } async setValue(label, value) { if (typeof value === 'function') { return this.addComputedValue(label, value); } const displayValue = this.values.get(label) ?? this.scene?.addDisplayValue(`${this.name} ${label}`); if (value !== displayValue.get()) { await this.scene?.sequence?.log(`note over ${this.name} : ${label} = ${displayNumber(value)}`); } displayValue.set(value); this.values.set(label, displayValue); return this; } async computeValues() { for (const [label, fn] of this.valueFunctions.entries()) { const value = fn(); await this.setValue(label, value); } } getValuesMap() { return new Map(Array.from(this.values.entries()) .map(([key, displayValue]) => [key, { name: displayValue.getName(), value: displayValue.get(), }])); } }