94 lines
2.4 KiB
JavaScript
94 lines
2.4 KiB
JavaScript
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(),
|
|
}]));
|
|
}
|
|
}
|