Skip to content

Commit

Permalink
feat: 個別のGameObjectに関する細分化された更新イベント
Browse files Browse the repository at this point in the history
`UPDATE_GAME_OBJECT`イベントについて、`aliasName`または`identifier`で対象を絞り込んだイベントを発火させる.
新規の`UPDATE_OBJECT_CHILDREN`イベントは、`ObjectNode`の`children`の変化を`parent`で検知するために使用できる.
  • Loading branch information
TK11235 committed Mar 19, 2023
1 parent ba4c936 commit 8ce5208
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 2 deletions.
54 changes: 54 additions & 0 deletions src/app/class/core/synchronize-object/object-event-extension.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import { Event, EventSystem, Network } from '../system';
import { GameObject } from './game-object';
import { ObjectNode } from './object-node';

const objectBatches = new Map<string, { object: GameObject, originFrom: string }>();
const nodeBatches = new Set<string>();

let isBatching = false;

export function markForChanged(object: GameObject, sendFrom: string = Network.peerId) {
objectBatches.set(object.identifier, { object: object, originFrom: sendFrom });
if (object instanceof ObjectNode) markForChildrenChanged(object.parent);

startBatching();
}

export function markForChildrenChanged(node: ObjectNode) {
let current = node;
while (current) {
nodeBatches.add(current.identifier);
current = current.parent;
if (current === node) break;
}

startBatching();
}

function startBatching() {
if (!isBatching) {
queueMicrotask(triggerEvent);
isBatching = true;
}
}

const triggerEvent = () => {
isBatching = false;
let objects = Array.from(objectBatches.values());
let nodes = Array.from(nodeBatches.values());
objectBatches.clear();
nodeBatches.clear();

for (let data of objects) {
let context = {
aliasName: data.object.aliasName,
identifier: data.object.identifier,
}
EventSystem.trigger(new Event(`UPDATE_GAME_OBJECT/aliasName/${context.aliasName}`, context, data.originFrom));
EventSystem.trigger(new Event(`UPDATE_GAME_OBJECT/identifier/${context.identifier}`, context, data.originFrom));
}

for (let identifier of nodes) {
EventSystem.trigger(`UPDATE_OBJECT_CHILDREN/identifier/${identifier}`, { identifier: identifier });
}
}
3 changes: 3 additions & 0 deletions src/app/class/core/synchronize-object/object-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { XmlUtil } from '../system/util/xml-util';
import { Attributes } from './attributes';
import { defineSyncObject as SyncObject, defineSyncVariable as SyncVar } from './decorator-core';
import { GameObject, ObjectContext } from './game-object';
import { markForChildrenChanged } from './object-event-extension';
import { InnerXml, ObjectSerializer, XmlAttributes } from './object-serializer';
import { ObjectStore } from './object-store';

Expand Down Expand Up @@ -68,6 +69,7 @@ export class ObjectNode extends GameObject implements XmlAttributes, InnerXml {
onChildRemoved(child: ObjectNode) { }

private _onChildAdded(child: ObjectNode) {
markForChildrenChanged(this);
let node: ObjectNode = this;
while (node) {
node.onChildAdded(child);
Expand All @@ -77,6 +79,7 @@ export class ObjectNode extends GameObject implements XmlAttributes, InnerXml {
}

private _onChildRemoved(child: ObjectNode) {
markForChildrenChanged(this);
let node: ObjectNode = this;
while (node) {
node.onChildRemoved(child);
Expand Down
7 changes: 5 additions & 2 deletions src/app/class/core/synchronize-object/object-synchronizer.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { EventSystem, Network } from '../system';
import { GameObject, ObjectContext } from './game-object';
import { markForChanged } from './object-event-extension';
import { ObjectFactory } from './object-factory';
import { CatalogItem, ObjectStore } from './object-store';
import { SynchronizeRequest, SynchronizeTask } from './synchronize-task';
Expand Down Expand Up @@ -58,11 +59,13 @@ export class ObjectSynchronizer {
let context: ObjectContext = event.data;
let object: GameObject = ObjectStore.instance.get(context.identifier);
if (object) {
if (!event.isSendFromSelf) this.updateObject(object, context);
if (!event.isSendFromSelf) object = this.updateObject(object, context);
markForChanged(object, event.sendFrom);
} else if (ObjectStore.instance.isDeleted(context.identifier)) {
EventSystem.call('DELETE_GAME_OBJECT', { aliasName: context.aliasName, identifier: context.identifier }, event.sendFrom);
} else {
this.createObject(context);
object = this.createObject(context);
markForChanged(object, event.sendFrom);
}
})
.on('DELETE_GAME_OBJECT', 1000, event => {
Expand Down

0 comments on commit 8ce5208

Please sign in to comment.