@colyseus/schema 3.0.43 → 3.0.44

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -43,13 +43,14 @@ export class StateView {
43
43
  // TODO: allow to set multiple tags at once
44
44
  add(obj: Ref, tag: number = DEFAULT_VIEW_TAG, checkIncludeParent: boolean = true) {
45
45
  const changeTree: ChangeTree = obj?.[$changes];
46
+ const parentChangeTree = changeTree.parent;
46
47
 
47
48
  if (!changeTree) {
48
49
  console.warn("StateView#add(), invalid object:", obj);
49
- return this;
50
+ return false;
50
51
 
51
52
  } else if (
52
- !changeTree.parent &&
53
+ !parentChangeTree &&
53
54
  changeTree.refId !== 0 // allow root object
54
55
  ) {
55
56
  /**
@@ -76,20 +77,38 @@ export class StateView {
76
77
  // add parent ChangeTree's
77
78
  // - if it was invisible to this view
78
79
  // - if it were previously filtered out
79
- if (checkIncludeParent && changeTree.parent) {
80
+ if (checkIncludeParent && parentChangeTree) {
80
81
  this.addParentOf(changeTree, tag);
81
82
  }
82
83
 
83
- //
84
- // TODO: when adding an item of a MapSchema, the changes may not
85
- // be set (only the parent's changes are set)
86
- //
87
84
  let changes = this.changes.get(changeTree.refId);
88
85
  if (changes === undefined) {
89
86
  changes = {};
87
+ // FIXME / OPTIMIZE: do not add if no changes are needed
90
88
  this.changes.set(changeTree.refId, changes);
91
89
  }
92
90
 
91
+ let isChildAdded = false;
92
+
93
+ //
94
+ // Add children of this ChangeTree first.
95
+ // If successful, we must link the current ChangeTree to the child.
96
+ //
97
+ changeTree.forEachChild((change, index) => {
98
+ // Do not ADD children that don't have the same tag
99
+ if (
100
+ metadata &&
101
+ metadata[index].tag !== undefined &&
102
+ metadata[index].tag !== tag
103
+ ) {
104
+ return;
105
+ }
106
+
107
+ if (this.add(change.ref, tag, false)) {
108
+ isChildAdded = true;
109
+ }
110
+ });
111
+
93
112
  // set tag
94
113
  if (tag !== DEFAULT_VIEW_TAG) {
95
114
  if (!this.tags) {
@@ -111,12 +130,14 @@ export class StateView {
111
130
  }
112
131
  });
113
132
 
114
- } else {
115
- const isInvisible = this.invisible.has(changeTree);
133
+ } else if (!changeTree.isNew || isChildAdded) {
134
+ // new structures will be added as part of .encode() call, no need to force it to .encodeView()
116
135
  const changeSet = (changeTree.filteredChanges !== undefined)
117
136
  ? changeTree.allFilteredChanges
118
137
  : changeTree.allChanges;
119
138
 
139
+ const isInvisible = this.invisible.has(changeTree);
140
+
120
141
  for (let i = 0, len = changeSet.operations.length; i < len; i++) {
121
142
  const index = changeSet.operations[i];
122
143
  if (index === undefined) { continue; } // skip "undefined" indexes
@@ -124,33 +145,20 @@ export class StateView {
124
145
  const op = changeTree.indexedOperations[index] ?? OPERATION.ADD;
125
146
  const tagAtIndex = metadata?.[index].tag;
126
147
  if (
127
- !changeTree.isNew && // new structures will be added as part of .encode() call, no need to force it to .encodeView()
148
+ op !== OPERATION.DELETE &&
128
149
  (
129
150
  isInvisible || // if "invisible", include all
130
151
  tagAtIndex === undefined || // "all change" with no tag
131
152
  tagAtIndex === tag // tagged property
132
- ) &&
133
- op !== OPERATION.DELETE
153
+ )
134
154
  ) {
135
155
  changes[index] = op;
156
+ isChildAdded = true; // FIXME: assign only once
136
157
  }
137
158
  }
138
159
  }
139
160
 
140
- // Add children of this ChangeTree to this view
141
- changeTree.forEachChild((change, index) => {
142
- // Do not ADD children that don't have the same tag
143
- if (
144
- metadata &&
145
- metadata[index].tag !== undefined &&
146
- metadata[index].tag !== tag
147
- ) {
148
- return;
149
- }
150
- this.add(change.ref, tag, false);
151
- });
152
-
153
- return this;
161
+ return isChildAdded;
154
162
  }
155
163
 
156
164
  protected addParentOf(childChangeTree: ChangeTree, tag: number) {
@@ -120,7 +120,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
120
120
 
121
121
  if (previousValue !== undefined) {
122
122
  // remove root reference from previous value
123
- previousValue[$changes].root?.remove(previousValue[$changes]);
123
+ previousValue[$changes].root?.remove(previousValue[$changes], obj);
124
124
  }
125
125
 
126
126
  } else {
@@ -310,7 +310,7 @@ export class ArraySchema<V = any> implements Array<V>, Collection<number, V> {
310
310
 
311
311
  // remove children references
312
312
  changeTree.forEachChild((childChangeTree, _) => {
313
- changeTree.root?.remove(childChangeTree);
313
+ changeTree.root?.remove(childChangeTree, this);
314
314
  });
315
315
 
316
316
  changeTree.discard(true);
@@ -118,7 +118,7 @@ export class CollectionSchema<V=any> implements Collection<K, V>{
118
118
 
119
119
  // remove children references
120
120
  changeTree.forEachChild((childChangeTree, _) => {
121
- changeTree.root?.remove(childChangeTree);
121
+ changeTree.root?.remove(childChangeTree, this);
122
122
  });
123
123
 
124
124
  // clear previous indexes
@@ -114,7 +114,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
114
114
 
115
115
  // remove reference from previous value
116
116
  if (previousValue !== undefined) {
117
- previousValue[$changes].root?.remove(previousValue[$changes]);
117
+ previousValue[$changes].root?.remove(previousValue[$changes], this);
118
118
  }
119
119
  }
120
120
 
@@ -163,7 +163,7 @@ export class MapSchema<V=any, K extends string = string> implements Map<K, V>, C
163
163
 
164
164
  // remove children references
165
165
  changeTree.forEachChild((childChangeTree, _) => {
166
- changeTree.root?.remove(childChangeTree);
166
+ changeTree.root?.remove(childChangeTree, this);
167
167
  });
168
168
 
169
169
  // clear previous indexes
@@ -36,4 +36,4 @@ export const $descriptors = "~descriptors";
36
36
  export const $numFields = "~__numFields";
37
37
  export const $refTypeFieldIndexes = "~__refTypeFieldIndexes";
38
38
  export const $viewFieldIndexes = "~__viewFieldIndexes";
39
- export const $fieldIndexesByViewTag = "$__fieldIndexesByViewTag";
39
+ export const $fieldIndexesByViewTag = "$__fieldIndexesByViewTag";