diff --git a/learn_sql_model/api/websocket.py b/learn_sql_model/api/websocket.py index b4a5e0f..375c42c 100644 --- a/learn_sql_model/api/websocket.py +++ b/learn_sql_model/api/websocket.py @@ -1,10 +1,11 @@ from fastapi import APIRouter, Depends, WebSocket, WebSocketDisconnect from fastapi.responses import HTMLResponse from sqlmodel import Session +from websockets.exceptions import ConnectionClosed from learn_sql_model.api.websocket_connection_manager import manager from learn_sql_model.config import get_session -from learn_sql_model.models.hero import Heros +from learn_sql_model.models.hero import HeroUpdate, Heros web_socket_router = APIRouter() @@ -81,6 +82,31 @@ async def websocket_endpoint( session: Session = Depends(get_session), ): await websocket.accept() - while True: - heros = Heros.list(session=session) - await websocket.send_text(heros.json()) + try: + while True: + heros = Heros.list(session=session) + await websocket.send_text(heros.json()) + except WebSocketDisconnect: + print("disconnected") + except ConnectionClosed: + print("connection closed") + + +@web_socket_router.websocket("/ws-hero-update") +async def websocket_endpoint( + websocket: WebSocket, + session: Session = Depends(get_session), +): + await websocket.accept() + try: + while True: + data = await websocket.receive_text() + hero = HeroUpdate.parse_raw(data) + print(hero) + hero.update(session=session) + print("hero is updated") + + except WebSocketDisconnect: + print("disconnected") + except ConnectionClosed: + print("connection closed") diff --git a/learn_sql_model/game/game.py b/learn_sql_model/game/game.py index ed04928..394b1b9 100644 --- a/learn_sql_model/game/game.py +++ b/learn_sql_model/game/game.py @@ -9,6 +9,7 @@ import atexit import pygame +from rich.console import Console import typer from typer import Typer from websocket import create_connection @@ -29,7 +30,6 @@ class Client: def __init__(self, name, secret_name): self.hero = Hero(name=name, secret_name=secret_name, x=400, y=300, size=50) self.hero = HeroCreate(**self.hero.dict()).post() - pygame.init() self.screen = pygame.display.set_mode((800, 600)) pygame.display.set_caption("Learn SQL Model") @@ -41,14 +41,36 @@ class Client: self.moving_down = False self.moving_left = False self.moving_right = False - self.ws = create_connection( - f"ws://{config.api_client.host}:{config.api_client.port}/wsecho" - ) - self.ticks = 0 atexit.register(self.quit) + @property + def ws(self): + def connect(): + self._ws = create_connection( + f"ws://{config.api_client.host}:{config.api_client.port}/wsecho" + ) + + if not hasattr(self, "_ws"): + connect() + if not self._ws.connected: + connect() + return self._ws + + @property + def ws_update(self): + def connect(): + self._ws_update = create_connection( + f"ws://{config.api_client.host}:{config.api_client.port}/ws-hero-update" + ) + + if not hasattr(self, "_ws_update"): + connect() + if not self._ws_update.connected: + connect() + return self._ws_update + @property def others(self): raw_heros = self.ws.recv() @@ -61,6 +83,7 @@ class Client: self.render() self.clock.tick(60) self.ticks += 1 + Console().print("not running, quitting") self.quit() def quit(self): @@ -76,10 +99,9 @@ class Client: if self.moving_right: self.hero.x += speed - if self.ticks % 60 == 0: - HeroUpdate( - **{k: v for k, v in self.hero.dict().items() if v is not None} - ).update() + # if self.ticks % 1 == 0: + update = HeroUpdate(**self.hero.dict(exclude_unset=True)) + self.ws_update.send(update.json()) def render(self): # Console().print(self.hero) diff --git a/learn_sql_model/models/hero.py b/learn_sql_model/models/hero.py index 8c2455b..dac0f78 100644 --- a/learn_sql_model/models/hero.py +++ b/learn_sql_model/models/hero.py @@ -102,7 +102,18 @@ class HeroUpdate(SQLModel): pet_id: Optional[int] = Field(default=None, foreign_key="pet.id") pet: Optional[Pet] = Relationship(back_populates="hero") - def update(self) -> Hero: + def update(self, session: Session = None) -> Hero: + if session is not None: + db_hero = session.get(Hero, self.id) + if not db_hero: + raise HTTPException(status_code=404, detail="Hero not found") + for key, value in self.dict(exclude_unset=True).items(): + setattr(db_hero, key, value) + session.add(db_hero) + session.commit() + session.refresh(db_hero) + return db_hero + r = httpx.patch( f"{config.api_client.url}/hero/", json=self.dict(),