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