Skip to content

Commit

Permalink
Fixed chip.Alternative and bumped version to 3.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
drpepper committed Jul 11, 2023
1 parent 42500e7 commit 6cb0da8
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 19 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = {
rules: {
"no-console": "off",
"no-unused-vars": ["error", { args: "none" }],
"@typescript-eslint/no-non-null-assertion": "off",
},
ignorePatterns: [".eslintrc.js"],
};
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "booyah",
"version": "3.0.5",
"version": "3.0.6",
"description": "HTML5 game engine",
"scripts": {
"build": "tsc",
Expand Down
42 changes: 24 additions & 18 deletions src/chip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,7 @@ export abstract class ChipBase extends EventEmitter implements Chip {
if (this._state !== "active" && this._state !== "paused")
throw new Error(`terminate() called from state ${this._state}`);

this._outputSignal = outputSignal ?? makeSignal();
this._outputSignal = outputSignal;
this._onTerminate();

this._unsubscribe(); // Remove all event listeners
Expand Down Expand Up @@ -577,14 +577,26 @@ export abstract class Composite extends ChipBase {
}

public terminate(outputSignal: Signal = makeSignal()): void {
// Can't just call super.terminate() here, the order is slightly different

if (this._state !== "active" && this._state !== "paused")
throw new Error(`terminate() called from state ${this._state}`);

if (this._methodCallInProgress) {
this._deferredOutputSignal = outputSignal;
return;
}

this._state = "inactive";

this._unsubscribe(); // Remove all event listeners

this._terminateAllChildChips();

super.terminate(outputSignal);
this._outputSignal = outputSignal;
this._onTerminate();

this.emit("terminated", this._outputSignal);
}

public pause(tickInfo: TickInfo): void {
Expand Down Expand Up @@ -1500,27 +1512,21 @@ export class Alternative extends Composite {
}

_onActivate() {
for (const chipActivationInfo of this._chipActivationInfos) {
for (let i = 0; i < this._chipActivationInfos.length; i++) {
const chipActivationInfo = this._chipActivationInfos[i];

this._subscribe(chipActivationInfo.chip, "terminated", () =>
this._onChildTerminated(i)
);
this._activateChildChip(chipActivationInfo.chip, {
context: chipActivationInfo.context,
});
}

this._checkForSignal();
}

_onTick() {
this._checkForSignal();
}

private _checkForSignal(): void {
for (let i = 0; i < this._chipActivationInfos.length; i++) {
if (this._childChips[i].outputSignal) {
const terminateWith =
this._chipActivationInfos[i].signal ?? makeSignal(i.toString());
this.terminate(terminateWith);
break;
}
}
private _onChildTerminated(index: number) {
const terminateWith =
this._chipActivationInfos[index].signal ?? makeSignal(index.toString());
this.terminate(terminateWith);
}
}
40 changes: 40 additions & 0 deletions tests/chip.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -811,6 +811,46 @@ describe("StateMachine", () => {
});
});

describe("Alternative", () => {
test("picks the first chip that terminates", () => {
const children = [new MockChip(), new MockChip()];

const alternative = new chip.Alternative(children);

// Run once
alternative.activate(makeFrameInfo(), makeChipContext(), makeSignal());
alternative.tick(makeFrameInfo());

// Terminate second child
children[1].terminate();

// Alternative should terminate as well, with an output signal of the index of the child
expect(alternative.state).toBe("inactive");
expect(alternative.outputSignal.name).toBe("1");
});

test("can provide custom signal", () => {
const children = [
{ chip: new MockChip(), signal: chip.makeSignal("hello") },
new MockChip(),
];

const alternative = new chip.Alternative(children);

// Run once
alternative.activate(makeFrameInfo(), makeChipContext(), makeSignal());
alternative.tick(makeFrameInfo());

// Terminate first child
// @ts-ignore
children[0].chip.terminate();

// Alternative should terminate as well, with an output signal of the index of the child
expect(alternative.state).toBe("inactive");
expect(alternative.outputSignal.name).toBe("hello");
});
});

//// Test hot reload features

class ReloadingChip extends chip.ChipBase {
Expand Down

0 comments on commit 6cb0da8

Please sign in to comment.