Skip to content

Commit

Permalink
refactor hasFilter(). add context.useFilters property. #75
Browse files Browse the repository at this point in the history
  • Loading branch information
endel committed Jul 14, 2020
1 parent 6cd1693 commit d8e6cc2
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 56 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": "1.0.0-alpha.8",
"version": "1.0.0-alpha.9",
"description": "Schema-based binary serializer / de-serializer.",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand Down
2 changes: 0 additions & 2 deletions src/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,8 +392,6 @@ export abstract class Schema {
// });
// }

// value.$changes.refId = refId;

$root.addRef(refId, value);
// $root.refs.set(refId, value);

Expand Down
65 changes: 18 additions & 47 deletions src/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class SchemaDefinition {
}

this.filters[this.indexes[field]] = cb;
return true;
}

addChildrenFilter(field: string, cb: FilterChildrenCallback) {
Expand All @@ -103,6 +104,7 @@ export class SchemaDefinition {
}

this.childFilters[index] = cb;
return true;

} else {
console.warn(`@filterChildren: field '${field}' can't have children. Ignoring filter.`);
Expand All @@ -118,48 +120,8 @@ export class SchemaDefinition {
}
}

export function hasFilter(
klass: typeof Schema,
knownSchemas: Set<typeof Schema> = new Set<typeof Schema>()
// knownSchemas: WeakSet<typeof Schema> = new WeakSet<typeof Schema>()
) {
const definition = klass['_definition'];
const schema = definition.schema;

let has = false;

// set of schemas we already checked OR are still checking
knownSchemas.add(klass);

for (const fieldName of Object.keys(schema)) {
// skip if a filter has been found
if (has) { break; }

if (
definition.filters[definition.indexes[fieldName]] ||
definition.childFilters[definition.indexes[fieldName]]
) {
has = true;

} else if (typeof schema[fieldName] === 'function') {
const childSchema = schema[fieldName] as typeof Schema;

if (!knownSchemas.has(childSchema)) {
has = hasFilter(childSchema, knownSchemas);
}

} else if (typeof(Object.values(schema[fieldName])[0]) !== "string") {
// Array.isArray(schema[fieldName])
const key = Object.keys(schema[fieldName])[0];
const childSchema = schema[fieldName][key] as typeof Schema;

if (!knownSchemas.has(childSchema)) {
has = hasFilter(childSchema, knownSchemas);
}
}
}

return has;
export function hasFilter(klass: typeof Schema) {
return klass._context.useFilters;
}

// Colyseus integration
Expand All @@ -168,6 +130,7 @@ export type Client = { sessionId: string } & any;
export class Context {
types: {[id: number]: typeof Schema} = {};
schemas = new Map<typeof Schema, number>();
useFilters = false;

has(schema: typeof Schema) {
return this.schemas.has(schema);
Expand All @@ -183,8 +146,7 @@ export class Context {
this.schemas.set(schema, schema._typeid);
}

static create() {
const context = new Context();
static create(context: Context = new Context) {
return function (definition: DefinitionType) {
return type(definition, context);
}
Expand Down Expand Up @@ -308,15 +270,20 @@ export function filter<T extends Schema, V, R extends Schema>(cb: FilterCallback
return function (target: any, field: string) {
const constructor = target.constructor as typeof Schema;
const definition = constructor._definition;
definition.addFilter(field, cb);

if (definition.addFilter(field, cb)) {
constructor._context.useFilters = true;
}
}
}

export function filterChildren<T extends Schema, K, V, R extends Schema>(cb: FilterChildrenCallback<T, K, V, R>): PropertyDecorator {
return function (target: any, field: string) {
const constructor = target.constructor as typeof Schema;
const definition = constructor._definition;
definition.addChildrenFilter(field, cb);
if (definition.addChildrenFilter(field, cb)) {
constructor._context.useFilters = true;
}
}
}

Expand Down Expand Up @@ -344,7 +311,11 @@ export function deprecated(throws: boolean = true, context: Context = globalCont
}
}

export function defineTypes(target: typeof Schema, fields: {[property: string]: DefinitionType}, context: Context = globalContext) {
export function defineTypes(
target: typeof Schema,
fields: { [property: string]: DefinitionType },
context: Context = target._context || globalContext
) {
for (let field in fields) {
type(fields[field], context)(target.prototype, field);
}
Expand Down
27 changes: 21 additions & 6 deletions test/DefinitionTest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as assert from "assert";

import { Schema, type, MapSchema, filter, hasFilter, ArraySchema } from "../src";
import { defineTypes } from "../src/annotations";
import { defineTypes, Context } from "../src/annotations";

describe("Definition Tests", () => {

Expand Down Expand Up @@ -52,6 +52,8 @@ describe("Definition Tests", () => {

describe("hasFilter()", () => {
it("should return false", () => {
const type = Context.create();

class State extends Schema {
@type("string") str: string;
}
Expand All @@ -60,6 +62,8 @@ describe("Definition Tests", () => {
});

it("should return true", () => {
const type = Context.create();

class State extends Schema {
@filter(function (client, value, root) {
return true;
Expand All @@ -71,6 +75,8 @@ describe("Definition Tests", () => {
});

it("should be able to navigate on recursive structures", () => {
const type = Context.create();

class Container extends Schema {
@type("string") name: string;

Expand All @@ -87,7 +93,10 @@ describe("Definition Tests", () => {
assert.equal(false, fun());
});

it("should be able to navigate on more complex recursive structures", () => {
it("should be able to navigate on more complex recursive array structures", () => {
const context = new Context();
const type = Context.create(context);

class ContainerA extends Schema {
@type("string") contAName: string;
}
Expand All @@ -102,7 +111,7 @@ describe("Definition Tests", () => {
defineTypes(cont, {
containersA: [ContainerA],
containersB: [ContainerB],
});
}, context);
});

const fun = () => hasFilter(State);
Expand All @@ -111,7 +120,9 @@ describe("Definition Tests", () => {
assert.equal(false, fun());
});

it("should find filter on more complex recursive structures - array", () => {
it("should find filter on more complex recursive map structures", () => {
const type = Context.create();

class ContainerA extends Schema {
@type("string") contAName: string;
}
Expand All @@ -126,15 +137,17 @@ describe("Definition Tests", () => {
const allContainers = [State, ContainerA, ContainerB];
allContainers.forEach((cont) => {
defineTypes(cont, {
containersA: [ContainerA],
containersB: [ContainerB],
containersA: { map: ContainerA },
containersB: { map: ContainerB },
});
});

assert.ok(hasFilter(State));
});

it("should find filter on more complex recursive structures - map", () => {
const type = Context.create();

class ContainerA extends Schema {
@type("string") contAName: string;
}
Expand All @@ -158,6 +171,8 @@ describe("Definition Tests", () => {
});

it("should be able to navigate on maps and arrays of primitive types", () => {
const type = Context.create();

class State extends Schema {
@type(["string"]) stringArr: MapSchema<string>;
@type(["number"]) numberArr: MapSchema<number>;
Expand Down

0 comments on commit d8e6cc2

Please sign in to comment.