Skip to content

Commit 8be33e2

Browse files
committed
ArraySchema: fix .clear() operation usage with StateView.
1 parent c7a21f2 commit 8be33e2

File tree

4 files changed

+129
-3
lines changed

4 files changed

+129
-3
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.32",
3+
"version": "3.0.33",
44
"description": "Binary state serializer with delta encoding for games",
55
"bin": {
66
"schema-codegen": "./bin/schema-codegen",

src/encoder/ChangeTree.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,9 +241,14 @@ export class ChangeTree<T extends Ref=any> {
241241
operation(op: OPERATION) {
242242
// operations without index use negative values to represent them
243243
// this is checked during .encode() time.
244-
this.changes.operations.push(-op);
244+
if (this.filteredChanges !== undefined) {
245+
this.filteredChanges.operations.push(-op);
246+
enqueueChangeTree(this.root, this, 'filteredChanges');
245247

246-
enqueueChangeTree(this.root, this, 'changes');
248+
} else {
249+
this.changes.operations.push(-op);
250+
enqueueChangeTree(this.root, this, 'changes');
251+
}
247252
}
248253

249254
change(index: number, operation: OPERATION = OPERATION.ADD) {

test/ArraySchema.test.ts

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2383,6 +2383,60 @@ describe("ArraySchema Tests", () => {
23832383

23842384
assertDeepStrictEqualEncodeAll(state);
23852385
});
2386+
2387+
it("should allow clear + push", () => {
2388+
class Player extends Schema {
2389+
@type(["string"]) public hand = new ArraySchema<string>();
2390+
@type(["string"]) public deck = new ArraySchema<string>();
2391+
}
2392+
class State extends Schema {
2393+
@type({ map: Player }) players = new MapSchema<Player>();
2394+
}
2395+
const state = new State();
2396+
const decodedState = createInstanceFromReflection(state);
2397+
2398+
function createPlayer() {
2399+
const player = new Player();
2400+
for (let i = 0; i < 10; i++) {
2401+
player.deck.push(`card${i}`);
2402+
}
2403+
player.hand.push(player.deck.pop());
2404+
player.hand.push(player.deck.pop());
2405+
player.hand.push(player.deck.pop());
2406+
return player;
2407+
}
2408+
2409+
const player1 = createPlayer();
2410+
const player2 = createPlayer();
2411+
2412+
state.players.set("one", player1);
2413+
state.players.set("two", player2);
2414+
2415+
decodedState.decode(state.encode());
2416+
assert.strictEqual(decodedState.players.size, 2);
2417+
assert.strictEqual(decodedState.players.get("one").hand.length, 3);
2418+
assert.strictEqual(decodedState.players.get("one").deck.length, 7);
2419+
assert.strictEqual(decodedState.players.get("two").hand.length, 3);
2420+
assert.strictEqual(decodedState.players.get("two").deck.length, 7);
2421+
2422+
player1.hand.clear();
2423+
player1.hand.push("card1");
2424+
player1.hand.push("card2");
2425+
2426+
player2.hand.clear();
2427+
player2.hand.push("card1");
2428+
player2.hand.push("card2");
2429+
2430+
decodedState.decode(state.encode());
2431+
assert.strictEqual(decodedState.players.size, 2);
2432+
assert.strictEqual(decodedState.players.get("one").hand.length, 2);
2433+
assert.strictEqual(decodedState.players.get("one").deck.length, 7);
2434+
assert.strictEqual(decodedState.players.get("two").hand.length, 2);
2435+
assert.strictEqual(decodedState.players.get("two").deck.length, 7);
2436+
assert.deepStrictEqual(state.toJSON(), decodedState.toJSON());
2437+
2438+
assertDeepStrictEqualEncodeAll(state);
2439+
});
23862440
})
23872441

23882442
describe("array methods", () => {

test/StateView.test.ts

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1585,6 +1585,73 @@ describe("StateView", () => {
15851585

15861586
assertEncodeAllMultiple(encoder, state, [client]);
15871587
});
1588+
1589+
it("should allow clear and push on filtered array", () => {
1590+
class Player extends Schema {
1591+
@view() @type(["string"]) public hand = new ArraySchema<string>();
1592+
@view() @type(["string"]) public deck = new ArraySchema<string>();
1593+
}
1594+
class State extends Schema {
1595+
@type({ map: Player }) players = new MapSchema<Player>();
1596+
}
1597+
const state = new State();
1598+
const encoder = getEncoder(state);
1599+
1600+
const client1 = createClientWithView(state);
1601+
const client2 = createClientWithView(state);
1602+
1603+
function createPlayer() {
1604+
const player = new Player();
1605+
for (let i = 0; i < 10; i++) {
1606+
player.deck.push(`card${i}`);
1607+
}
1608+
player.hand.push(player.deck.pop());
1609+
player.hand.push(player.deck.pop());
1610+
player.hand.push(player.deck.pop());
1611+
return player;
1612+
}
1613+
1614+
const player1 = createPlayer();
1615+
const player2 = createPlayer();
1616+
1617+
state.players.set("one", player1);
1618+
state.players.set("two", player2);
1619+
1620+
encodeMultiple(encoder, state, [client1, client2]);
1621+
assert.strictEqual(client1.state.players.size, 2);
1622+
assert.strictEqual(client1.state.players.get("one").hand, undefined);
1623+
assert.strictEqual(client2.state.players.size, 2);
1624+
assert.strictEqual(client2.state.players.get("two").hand, undefined);
1625+
1626+
client1.view.add(player1);
1627+
client2.view.add(player2);
1628+
1629+
encodeMultiple(encoder, state, [client1, client2]);
1630+
assert.strictEqual(client1.state.players.size, 2);
1631+
assert.strictEqual(client1.state.players.get("one").hand.length, 3);
1632+
assert.strictEqual(client1.state.players.get("one").deck.length, 7);
1633+
assert.strictEqual(client2.state.players.size, 2);
1634+
assert.strictEqual(client2.state.players.get("two").hand.length, 3);
1635+
assert.strictEqual(client2.state.players.get("two").deck.length, 7);
1636+
1637+
player1.hand.clear();
1638+
player1.hand.push("card1");
1639+
player1.hand.push("card2");
1640+
1641+
player2.hand.clear();
1642+
player2.hand.push("card1");
1643+
player2.hand.push("card2");
1644+
1645+
console.log(Schema.debugRefIds(state));
1646+
1647+
encodeMultiple(encoder, state, [client1, client2]);
1648+
assert.strictEqual(client1.state.players.get("one").hand.length, 2);
1649+
assert.strictEqual(client1.state.players.get("one").deck.length, 7);
1650+
assert.strictEqual(client2.state.players.get("two").hand.length, 2);
1651+
assert.strictEqual(client2.state.players.get("two").deck.length, 7);
1652+
1653+
assertEncodeAllMultiple(encoder, state, [client1, client2]);
1654+
});
15881655
});
15891656

15901657
describe("Deep and nested structures", () => {

0 commit comments

Comments
 (0)