feat(gems): add multiplayer gem game with custom content packs
treefmt / nix fmt (pull_request) Successful in 6s
test ebook search / test-ebook-search (pull_request) Successful in 39s
pytest / pytest (pull_request) Successful in 40s
build_systems / build-brain (pull_request) Successful in 1m0s
build_systems / build-bob (pull_request) Successful in 1m2s
build_systems / build-rhapsody-in-green (pull_request) Successful in 1m33s
build_systems / build-jeeves (pull_request) Successful in 2m25s
test ebook search / test-ebook-search (push) Successful in 35s
build_systems / build-brain (push) Successful in 37s
build_systems / build-bob (push) Successful in 37s
build_systems / build-jeeves (push) Successful in 2m17s
treefmt / nix fmt (push) Successful in 5s
pytest / pytest (push) Successful in 29s
build_systems / build-rhapsody-in-green (push) Successful in 49s
treefmt / nix fmt (pull_request) Successful in 6s
test ebook search / test-ebook-search (pull_request) Successful in 39s
pytest / pytest (pull_request) Successful in 40s
build_systems / build-brain (pull_request) Successful in 1m0s
build_systems / build-bob (pull_request) Successful in 1m2s
build_systems / build-rhapsody-in-green (pull_request) Successful in 1m33s
build_systems / build-jeeves (pull_request) Successful in 2m25s
test ebook search / test-ebook-search (push) Successful in 35s
build_systems / build-brain (push) Successful in 37s
build_systems / build-bob (push) Successful in 37s
build_systems / build-jeeves (push) Successful in 2m17s
treefmt / nix fmt (push) Successful in 5s
pytest / pytest (push) Successful in 29s
build_systems / build-rhapsody-in-green (push) Successful in 49s
- implement FastAPI and HTMX lobby and game interfaces - support up to four human and AI-controlled players - add configurable rules, victory conditions, and expansion modules - support validated JSON cards, patrons, objectives, and outposts
This commit was merged in pull request #43.
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
"""In-process revision notifications for SSE clients."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
from collections import defaultdict
|
||||
|
||||
|
||||
class EventBroker:
|
||||
"""Fan out room revisions; clients always reload the latest snapshot."""
|
||||
|
||||
def __init__(self) -> None:
|
||||
"""Initialize an empty subscription registry."""
|
||||
self._queues: dict[str, set[asyncio.Queue[int]]] = defaultdict(set)
|
||||
|
||||
def subscribe(self, room_code: str) -> asyncio.Queue[int]:
|
||||
"""Subscribe a bounded notification queue to a room."""
|
||||
queue: asyncio.Queue[int] = asyncio.Queue(maxsize=1)
|
||||
self._queues[room_code].add(queue)
|
||||
return queue
|
||||
|
||||
def unsubscribe(self, room_code: str, queue: asyncio.Queue[int]) -> None:
|
||||
"""Remove a room notification queue from the registry."""
|
||||
self._queues[room_code].discard(queue)
|
||||
if not self._queues[room_code]:
|
||||
self._queues.pop(room_code, None)
|
||||
|
||||
def publish(self, room_code: str, revision: int) -> None:
|
||||
"""Publish the newest room revision to every subscriber."""
|
||||
for queue in tuple(self._queues.get(room_code, ())):
|
||||
if queue.full():
|
||||
with contextlib.suppress(asyncio.QueueEmpty):
|
||||
queue.get_nowait()
|
||||
queue.put_nowait(revision)
|
||||
Reference in New Issue
Block a user