Skip to content

Commit c1498c4

Browse files
committed
StateView: fix view.remove() to recursively delete visible child schema instances
1 parent 2cbfa45 commit c1498c4

File tree

3 files changed

+45
-5
lines changed

3 files changed

+45
-5
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@colyseus/schema",
3-
"version": "3.0.38",
3+
"version": "3.0.39",
44
"description": "Binary state serializer with delta encoding for games",
55
"bin": {
66
"schema-codegen": "bin/schema-codegen",

src/encoder/StateView.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -238,9 +238,7 @@ export class StateView {
238238
changes[changeTree.parentIndex] = OPERATION.DELETE;
239239

240240
// Remove child schema from visible set
241-
changeTree.forEachChild((childChangeTree) => {
242-
this.visible.delete(childChangeTree);
243-
});
241+
this._recursiveDeleteVisibleChangeTree(changeTree);
244242

245243
} else {
246244
// delete all "tagged" properties.
@@ -319,4 +317,11 @@ export class StateView {
319317

320318
return isVisible;
321319
}
320+
321+
protected _recursiveDeleteVisibleChangeTree(changeTree: ChangeTree) {
322+
changeTree.forEachChild((childChangeTree) => {
323+
this.visible.delete(childChangeTree);
324+
this._recursiveDeleteVisibleChangeTree(childChangeTree);
325+
});
326+
}
322327
}

test/StateView.test.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1123,7 +1123,7 @@ describe("StateView", () => {
11231123
assert.deepStrictEqual(client.state.items.get("1").toJSON(), item1.toJSON());
11241124
});
11251125

1126-
it("view.remove() should remove nested items", () => {
1126+
it("view.remove() should remove nested items (1 level)", () => {
11271127
class Coordinates extends Schema {
11281128
@type("number") x: number;
11291129
@type("number") y: number;
@@ -1157,6 +1157,41 @@ describe("StateView", () => {
11571157
encodeAllMultiple(encoder, state, [client1]));
11581158
});
11591159

1160+
it("view.remove() should remove nested items (2 levels)", () => {
1161+
class Tag extends Schema {
1162+
@type("string") name: string;
1163+
}
1164+
class Coordinates extends Schema {
1165+
@type("number") x: number;
1166+
@type("number") y: number;
1167+
@type(Tag) tag: Tag;
1168+
}
1169+
class Diamond extends Schema {
1170+
@type(Coordinates) position: Coordinates;
1171+
}
1172+
class State extends Schema {
1173+
@view() @type({ map: Diamond }) diamonds = new MapSchema<Diamond>();
1174+
}
1175+
1176+
const state = new State();
1177+
const encoder = getEncoder(state);
1178+
1179+
const diamond = new Diamond().assign({
1180+
position: new Coordinates().assign({ x: 10, y: 20, tag: new Tag().assign({ name: "tag1" }) })
1181+
});
1182+
state.diamonds.set("one", diamond);
1183+
1184+
const client1 = createClientWithView(state);
1185+
client1.view.add(diamond);
1186+
encodeMultiple(encoder, state, [client1]);
1187+
1188+
client1.view.remove(diamond);
1189+
encodeMultiple(encoder, state, [client1]);
1190+
1191+
assert.doesNotThrow(() =>
1192+
encodeAllMultiple(encoder, state, [client1]));
1193+
});
1194+
11601195
});
11611196

11621197
describe("ArraySchema", () => {

0 commit comments

Comments
 (0)