diff --git a/package.json b/package.json index 0aecbecb..9e2b44d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@colyseus/schema", - "version": "0.5.22", + "version": "0.5.23", "description": "Schema-based binary serializer / de-serializer.", "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/src/Schema.ts b/src/Schema.ts index 9b31c647..d4e54d6c 100644 --- a/src/Schema.ts +++ b/src/Schema.ts @@ -722,11 +722,13 @@ export abstract class Schema { discardAllChanges() { const schema = this._schema; - const changes = this.$changes.changes; + const changes = Array.from(this.$changes.changes); + const fieldsByIndex = this._fieldsByIndex; - for (const field in changes) { + for (const index in changes) { + const field = fieldsByIndex[index]; const type = schema[field]; - const value = changes[field]; + const value = this[field]; // skip unchagned fields if (value === undefined) { continue; } diff --git a/test/ChangeAPITest.ts b/test/ChangeAPITest.ts index cee232a3..b37ef368 100644 --- a/test/ChangeAPITest.ts +++ b/test/ChangeAPITest.ts @@ -2,7 +2,7 @@ import * as sinon from "sinon"; import * as util from "util"; import * as assert from "assert"; -import { type } from './../src/annotations'; +import { type, filter } from './../src/annotations'; import { State, Player } from "./Schema"; import { Schema, MapSchema, ArraySchema, DataChange } from "../src"; @@ -658,6 +658,36 @@ describe("Change API", () => { }); }); + describe("with filters", () => { + class Round extends Schema { + @type(["number"]) scores = new ArraySchema(0, 0); + } + + class State extends Schema { + @filter(() => true) + @type("number") timer: number; + @type(Round) currentRound: Round = new Round(); + } + + it("should not trigger unchanged fields", () => { + let changesTriggered: number = 0; + + const state = new State(); + state.timer = 10; + + const decodedState = new State(); + decodedState.currentRound.listen("scores", () => changesTriggered++); + + do { + state.timer--; + decodedState.decode(state.encodeFiltered({})); + state.discardAllChanges(); + } while (state.timer > 0); + + assert.equal(1, changesTriggered); + }); + }); + describe("triggerAll", () => { it("should trigger onChange on Schema instance", () => { const state = new State(); @@ -701,7 +731,6 @@ describe("Change API", () => { }); }); - describe("callback order", () => { class MyState extends Schema { @type("string") str: string;