Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"generate-test-10": "bin/schema-codegen test-external/Callbacks.ts --namespace SchemaTest.Callbacks --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/Callbacks",
"generate-test-11": "bin/schema-codegen test-external/MapSchemaMoveNullifyType.ts --namespace SchemaTest.MapSchemaMoveNullifyType --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/MapSchemaMoveNullifyType",
"generate-test-12": "bin/schema-codegen test-external/ArraySchemaClear --namespace SchemaTest.ArraySchemaClear --output ../colyseus-unity-sdk/Assets/Colyseus/Tests/Editor/ColyseusTests/Schema/ArraySchemaClear",
"prepublishOnly": "npm run build"
"prepare": "npm run build"
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Happy to undo this if this PR is going to be merged. I needed my fork to build on install so I can use it directly from github.

},
"files": [
"src",
Expand Down
5 changes: 2 additions & 3 deletions src/encoder/ChangeTree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -568,16 +568,15 @@ export class ChangeTree<T extends Ref = any> {
|| fieldHasViewTag;

//
// "isFiltered" may not be imedialely available during `change()` due to the instance not being attached to the root yet.
// "isFiltered" may not be immediately available during `change()` due to the instance not being attached to the root yet.
// when it's available, we need to enqueue the "changes" changeset into the "filteredChanges" changeset.
//
if (this.isFiltered) {

this.isVisibilitySharedWithParent = (
parentChangeTree.isFiltered &&
typeof (refType) !== "string" &&
!fieldHasViewTag &&
parentIsCollection
!fieldHasViewTag
);

if (!this.filteredChanges) {
Expand Down
12 changes: 11 additions & 1 deletion test/Schema.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as assert from "assert";

import { Schema, type, ArraySchema, MapSchema, Reflection, Iterator, StateView } from "../src";
import { Schema, type, ArraySchema, MapSchema, Reflection, Iterator, StateView, view } from "../src";
import { Decoder } from "../src/decoder/Decoder";
import { Encoder } from "../src/encoder/Encoder";
import { CallbackProxy, getDecoderStateCallbacks, SchemaCallbackProxy } from "../src/decoder/strategy/getDecoderStateCallbacks";
Expand Down Expand Up @@ -249,6 +249,16 @@ export class Position extends Schema {
}
}

export class InheritanceParent extends Schema {
@type(Position) standardChild: Position | undefined = undefined;
@view() @type(Position) viewChild: Position | undefined = undefined;
@type([Position]) arrayChild: ArraySchema<Position> = new ArraySchema<Position>();
}

export class InheritanceRoot extends Schema {
@view() @type(InheritanceParent) parent = new InheritanceParent();
}

export class Another extends Schema {
@type(Position) position: Position = new Position(0, 0, 0);
}
Expand Down
83 changes: 82 additions & 1 deletion test/StateView.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as assert from "assert";
import * as util from "util";
import { Schema, type, view, ArraySchema, MapSchema, StateView, Encoder, ChangeTree, $changes, OPERATION, SetSchema, CollectionSchema } from "../src";
import { createClientWithView, encodeMultiple, assertEncodeAllMultiple, getDecoder, getEncoder, createInstanceFromReflection, encodeAllForView, encodeAllMultiple, assertRefIdCounts } from "./Schema";
import { createClientWithView, encodeMultiple, assertEncodeAllMultiple, getDecoder, getEncoder, createInstanceFromReflection, encodeAllForView, encodeAllMultiple, assertRefIdCounts, InheritanceRoot, Position } from "./Schema";
import { nanoid } from "nanoid";

describe("StateView", () => {
Expand Down Expand Up @@ -2595,4 +2595,85 @@ describe("StateView", () => {
});
});

it("should encode nested Schema", () => {
const state = new InheritanceRoot();
const encoder = getEncoder(state);

const client = createClientWithView(state);
client.view.add(state.parent);

// Initial encode: child property is undefined
encodeMultiple(encoder, state, [client]);

// Assign a child Schema instance.
state.parent.standardChild = new Position(1, 2, 3);

/**
* Encode an assignment of a child field:
* Its fields should be visible to the client, because it inherits visibility from its parent.
*/
encodeMultiple(encoder, state, [client]);

assert.notStrictEqual(client.state.parent, undefined);
assert.notStrictEqual(client.state.parent.standardChild, undefined);
assert.strictEqual(client.state.parent.standardChild.x, 1);
assert.strictEqual(client.state.parent.standardChild.y, 2);
assert.strictEqual(client.state.parent.standardChild.z, 3);
});

it("should not encode nested Schema with @view", () => {
const state = new InheritanceRoot();
const encoder = getEncoder(state);

const client = createClientWithView(state);
client.view.add(state.parent);

// Initial encode: child property is undefined
encodeMultiple(encoder, state, [client]);

// Assign a child Schema that uses @view
state.parent.viewChild = new Position(1, 2, 3);

/**
* Encode an assignment of a child field:
* the child "viewChild" field (Position) is marked with @view,
* so it does not share visibility with its parent, and
* its fields are not encoded for the client.
*/
encodeMultiple(encoder, state, [client]);

assert.notStrictEqual(client.state.parent, undefined);
assert.notStrictEqual(client.state.parent.viewChild, undefined);
assert.strictEqual(client.state.parent.viewChild.x, undefined);
assert.strictEqual(client.state.parent.viewChild.y, undefined);
assert.strictEqual(client.state.parent.viewChild.z, undefined);
});

it("should encode nested Schema wrapped in ArraySchema", () => {
const state = new InheritanceRoot();
const encoder = getEncoder(state);

const client = createClientWithView(state);
client.view.add(state.parent);

// Initial encode: child property is undefined
encodeMultiple(encoder, state, [client]);

// Assign a child Schema wrapped in an ArraySchema, to demonstrate this workaround.
state.parent.arrayChild.push(new Position(1, 2, 3));

/**
* Encode an assignment of a child field wrapped in an ArraySchema
* the child "arrayChild" field (Position) shares visibility with its parent,
* and its fields are encoded for the client.
*/
encodeMultiple(encoder, state, [client]);

assert.notStrictEqual(client.state.parent, undefined);
assert.strictEqual(client.state.parent.arrayChild.length, 1);
assert.strictEqual(client.state.parent.arrayChild[0].x, 1);
assert.strictEqual(client.state.parent.arrayChild[0].y, 2);
assert.strictEqual(client.state.parent.arrayChild[0].z, 3);
});

});