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