summaryrefslogtreecommitdiff
path: root/engine/systems/NetworkUpdate.ts
diff options
context:
space:
mode:
Diffstat (limited to 'engine/systems/NetworkUpdate.ts')
-rw-r--r--engine/systems/NetworkUpdate.ts72
1 files changed, 72 insertions, 0 deletions
diff --git a/engine/systems/NetworkUpdate.ts b/engine/systems/NetworkUpdate.ts
new file mode 100644
index 0000000..6d13574
--- /dev/null
+++ b/engine/systems/NetworkUpdate.ts
@@ -0,0 +1,72 @@
+import { System, SystemNames } from '.';
+import { Game } from '../Game';
+import { ComponentNames } from '../components';
+import {
+ type MessageQueueProvider,
+ type MessagePublisher,
+ type MessageProcessor,
+ MessageType,
+ EntityUpdateBody
+} from '../network';
+
+export class NetworkUpdate extends System {
+ private queueProvider: MessageQueueProvider;
+ private publisher: MessagePublisher;
+ private messageProcessor: MessageProcessor;
+
+ private entityUpdateTimers: Map<string, number>;
+
+ constructor(
+ queueProvider: MessageQueueProvider,
+ publisher: MessagePublisher,
+ messageProcessor: MessageProcessor
+ ) {
+ super(SystemNames.NetworkUpdate);
+
+ this.queueProvider = queueProvider;
+ this.publisher = publisher;
+ this.messageProcessor = messageProcessor;
+
+ this.entityUpdateTimers = new Map();
+ }
+
+ public update(dt: number, game: Game) {
+ // 1. process new messages
+ this.queueProvider
+ .getNewMessages()
+ .forEach((message) => this.messageProcessor.process(message));
+ this.queueProvider.clearMessages();
+
+ // 2. send entity updates
+ const updateMessages: EntityUpdateBody[] = [];
+ game.forEachEntityWithComponent(
+ ComponentNames.NetworkUpdateable,
+ (entity) => {
+ let timer = this.entityUpdateTimers.get(entity.id) ?? dt;
+ timer -= dt;
+ this.entityUpdateTimers.set(entity.id, timer);
+
+ if (timer > 0) return;
+ this.entityUpdateTimers.set(entity.id, this.getNextUpdateTimeMs());
+
+ if (entity.hasComponent(ComponentNames.NetworkUpdateable)) {
+ updateMessages.push({
+ id: entity.id,
+ args: entity.serialize()
+ });
+ }
+ }
+ );
+ this.publisher.addMessage({
+ type: MessageType.UPDATE_ENTITIES,
+ body: updateMessages
+ });
+
+ // 3. publish changes
+ this.publisher.publish();
+ }
+
+ private getNextUpdateTimeMs() {
+ return Math.random() * 70 + 50;
+ }
+}