Skip to content

Commit

Permalink
allow nested .onAdd() with .listen(). #147
Browse files Browse the repository at this point in the history
  • Loading branch information
endel committed Aug 16, 2024
1 parent 7bfba29 commit 8fd1ecf
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 6 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@colyseus/schema",
"version": "3.0.0-alpha.27",
"version": "3.0.0-alpha.28",
"description": "Binary state serializer with delta encoding for games",
"bin": {
"schema-codegen": "./bin/schema-codegen"
Expand Down
8 changes: 4 additions & 4 deletions src/decoder/strategy/StateCallbacks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):

if (metadata && !isCollection) {

const onAdd = function (
const onAddListen = function (
ref: Ref,
prop: string,
callback: (value: any, previousValue: any) => void, immediate: boolean
Expand All @@ -223,7 +223,7 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
if (
immediate &&
context.instance[prop] !== undefined &&
!onAddCalls.has(callback) // Workaround for https://github.com/colyseus/schema/issues/147
!onAddCalls.has(currentOnAddCallback) // Workaround for https://github.com/colyseus/schema/issues/147
) {
callback(context.instance[prop], undefined);
}
Expand All @@ -236,14 +236,14 @@ export function getDecoderStateCallbacks<T extends Schema>(decoder: Decoder<T>):
return new Proxy({
listen: function listen(prop: string, callback: (value: any, previousValue: any) => void, immediate: boolean = true) {
if (context.instance) {
return onAdd(context.instance, prop, callback, immediate);
return onAddListen(context.instance, prop, callback, immediate);

} else {
// collection instance not received yet
let detachCallback = () => {};

context.onInstanceAvailable((ref: Ref, existing: boolean) => {
detachCallback = onAdd(ref, prop, callback, immediate && existing)
detachCallback = onAddListen(ref, prop, callback, immediate && existing && !onAddCalls.has(currentOnAddCallback))
});

return () => detachCallback();
Expand Down
36 changes: 35 additions & 1 deletion test/callbacks/StateCallbacks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ describe("StateCallbacks", () => {
assert.strictEqual(30, bound.y);
});

it("should support nested onAdd, attached BEFORE data is available ", () => {
it("should support nested onAdd, attached BEFORE data is available", () => {
class Prop extends Schema {
@type("number") lvl: number;
}
Expand Down Expand Up @@ -113,25 +113,42 @@ describe("StateCallbacks", () => {
const $ = getCallbacks(decodedState);

let onPlayerAddCount = 0;
let onPlayerListen = 0;

let onItemAddCount = 0;
let onItemListen = 0

let onPropertyAddCount = 0;
let onPropertyListen = 0;

$(decodedState).players.onAdd((player, key) => {
onPlayerAddCount++;

$(player).listen("name", () => onPlayerListen++);

$(player).items.onAdd((item, key) => {
onItemAddCount++;

$(item).listen("type", () => onItemListen++);

$(item).properties.onAdd((prop, key) => {

$(prop).listen("lvl", () => onPropertyListen++);

onPropertyAddCount++;
});
});
});

decodedState.decode(state.encode());
assert.strictEqual(1, onPlayerAddCount);
assert.strictEqual(1, onPlayerListen);

assert.strictEqual(2, onItemAddCount);
assert.strictEqual(2, onItemListen);

assert.strictEqual(4, onPropertyAddCount);
assert.strictEqual(4, onPropertyListen);
});

it("should support nested onAdd, attached AFTER data is available ", () => {
Expand Down Expand Up @@ -180,26 +197,43 @@ describe("StateCallbacks", () => {
const $ = getCallbacks(decodedState);

let onPlayerAddCount = 0;
let onPlayerListen = 0;

let onItemAddCount = 0;
let onItemListen = 0

let onPropertyAddCount = 0;
let onPropertyListen = 0;

decodedState.decode(state.encode());

$(decodedState).players.onAdd((player, key) => {
onPlayerAddCount++;

$(player).listen("name", () => onPlayerListen++);

$(player).items.onAdd((item, key) => {
onItemAddCount++;

$(item).listen("type", () => onItemListen++);

$(item).properties.onAdd((prop, key) => {

$(prop).listen("lvl", () => onPropertyListen++);

onPropertyAddCount++;
});
});
});

assert.strictEqual(1, onPlayerAddCount);
assert.strictEqual(1, onPlayerListen);

assert.strictEqual(2, onItemAddCount);
assert.strictEqual(2, onItemListen);

assert.strictEqual(4, onPropertyAddCount);
assert.strictEqual(4, onPropertyListen);
});

});

0 comments on commit 8fd1ecf

Please sign in to comment.