WIP: ECS / Network System #1
|
@ -101,7 +101,7 @@ class Publishable:
|
|||
|
||||
class EventProcessor:
|
||||
@abstractmethod
|
||||
def accept(self, entity_manager: EntityManager, event: Event) -> None:
|
||||
def accept(self, entity_manager: EntityManager, event: Event | tuple[Event, str]) -> None:
|
||||
pass
|
||||
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ system_manager = SystemManager()
|
|||
|
||||
class KennelEventProcessor(EventProcessor):
|
||||
def accept(
|
||||
self, entity_manager: EntityManager, event: type[Event | tuple[Event, str]]
|
||||
self, entity_manager: EntityManager, event: Event | tuple[Event, str]
|
||||
) -> None:
|
||||
if isinstance(event, tuple):
|
||||
client_event, client_id = event
|
||||
|
|
|
@ -1,16 +1,13 @@
|
|||
import $ from "jquery";
|
||||
import { Vec2 } from "./vector";
|
||||
import {
|
||||
EventType,
|
||||
type SetControllableEvent,
|
||||
type Event,
|
||||
type EventPublisher,
|
||||
} from "./event";
|
||||
import { MouseController } from "./mouse_controller";
|
||||
import {
|
||||
EntityPositionUpdateEvent,
|
||||
EventProcessor,
|
||||
EventPublisher,
|
||||
EventQueue,
|
||||
EventType,
|
||||
SetControllableEvent,
|
||||
WebsocketEventPublisher,
|
||||
WebSocketEventQueue,
|
||||
} from "./network";
|
||||
|
||||
|
@ -18,10 +15,11 @@ class KennelClient {
|
|||
private running: boolean;
|
||||
private last_update: number;
|
||||
|
||||
private controllable_entities: Set<string>;
|
||||
private controllable_entities: Set<string> = new Set();
|
||||
private mouse_controller: MouseController;
|
||||
|
||||
constructor(
|
||||
private readonly client_id: string,
|
||||
private readonly event_queue: EventQueue,
|
||||
private readonly event_publisher: EventPublisher,
|
||||
) {
|
||||
|
@ -39,21 +37,45 @@ class KennelClient {
|
|||
this.mouse_controller.start();
|
||||
|
||||
const loop = (timestamp: number) => {
|
||||
if (!this.running) return;
|
||||
const dt = timestamp - this.last_update;
|
||||
this.propogate_state_after(dt);
|
||||
requestAnimationFrame(loop); // tail call recursion! /s
|
||||
};
|
||||
requestAnimationFrame(loop);
|
||||
|
||||
$(document).on("mousemove", (event) => {
|
||||
this.mouse_controller.move(event.clientX, event.clientY);
|
||||
});
|
||||
}
|
||||
|
||||
public close() {
|
||||
this.running = false;
|
||||
this.mouse_controller.stop();
|
||||
this.controllable_entities.clear();
|
||||
$(document).off("mousemove");
|
||||
}
|
||||
|
||||
private propogate_state_after(dt: number) {
|
||||
// TODO: interpolate cats and lasers and stuff
|
||||
const events = this.event_queue.peek();
|
||||
for (const event of events) {
|
||||
switch (event.event_type) {
|
||||
case EventType.SET_CONTROLLABLE:
|
||||
this.process_set_controllable_event(event as SetControllableEvent);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(events, dt);
|
||||
this.event_queue.clear();
|
||||
}
|
||||
|
||||
private process_set_controllable_event(event: SetControllableEvent) {
|
||||
if (event.data.client_id !== this.client_id) {
|
||||
console.warn("got controllable event for client that is not us");
|
||||
return;
|
||||
}
|
||||
this.controllable_entities.add(event.data.id);
|
||||
}
|
||||
|
||||
private on_mouse_move(position: Vec2) {
|
||||
|
@ -62,13 +84,13 @@ class KennelClient {
|
|||
event_type: EventType.ENTITY_POSITION_UPDATE,
|
||||
data: { id, position: { x: position.x, y: position.y } },
|
||||
};
|
||||
this.event_publisher.send(event);
|
||||
this.event_publisher.add(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$(async () => {
|
||||
const session_id = await fetch("/assign", {
|
||||
const client_id = await fetch("/assign", {
|
||||
credentials: "include",
|
||||
})
|
||||
.then((res) => res.json())
|
||||
|
@ -80,14 +102,9 @@ $(async () => {
|
|||
});
|
||||
|
||||
const queue: EventQueue = new WebSocketEventQueue(ws);
|
||||
|
||||
const kennel_client = new KennelClient(session_id, null);
|
||||
|
||||
const publisher: EventPublisher = new WebsocketEventPublisher(ws);
|
||||
const kennel_client = new KennelClient(client_id, queue, publisher);
|
||||
ws.onclose = () => kennel_client.close();
|
||||
|
||||
const mouse_controller = new MouseController(on_mouse_move);
|
||||
$(document).on("mousemove", (event) => {
|
||||
mouse_controller.move(event.clientX, event.clientY);
|
||||
});
|
||||
mouse_controller.start();
|
||||
kennel_client.start();
|
||||
});
|
||||
|
|
|
@ -71,3 +71,20 @@ export class WebSocketEventQueue implements EventQueue {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class WebsocketEventPublisher implements EventPublisher {
|
||||
private queue: Event[];
|
||||
|
||||
constructor(private readonly websocket: WebSocket) {
|
||||
this.queue = [];
|
||||
}
|
||||
|
||||
public add(event: Event) {
|
||||
this.queue.push(event);
|
||||
}
|
||||
|
||||
public publish() {
|
||||
this.websocket.send(JSON.stringify(this.queue));
|
||||
this.queue = [];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
export class Vec2 {
|
||||
constructor(
|
||||
private readonly x: number,
|
||||
private readonly y: number,
|
||||
public readonly x: number,
|
||||
public readonly y: number,
|
||||
) {}
|
||||
|
||||
public distance_to(that: Vec2): number {
|
||||
|
|
Loading…
Reference in New Issue