warchron_app/src/warchron/model/war_event.py

154 lines
4.2 KiB
Python
Raw Normal View History

from __future__ import annotations
from typing import Dict, Any, TypeVar, Type, cast
from datetime import datetime
from uuid import uuid4
T = TypeVar("T", bound="WarEvent")
EVENT_REGISTRY: Dict[str, Type["WarEvent"]] = {}
def register_event(cls: Type[T]) -> Type[T]:
EVENT_REGISTRY[cls.TYPE] = cls
return cls
class WarEvent:
TYPE = "WarEvent"
def __init__(self, participant_id: str | None, context_type: str, context_id: str):
self.id: str = str(uuid4())
self.participant_id: str | None = participant_id
self.context_type = context_type # battle, round, campaign, war
self.context_id = context_id
self.timestamp: datetime = datetime.now()
def set_id(self, new_id: str) -> None:
self.id = new_id
def set_participant(self, new_war_part_id: str | None) -> None:
self.participant_id = new_war_part_id
def set_timestamp(self, new_timestamp: datetime) -> None:
self.timestamp = new_timestamp
def toDict(self) -> Dict[str, Any]:
return {
"type": self.TYPE,
"id": self.id,
"participant_id": self.participant_id,
"context_type": self.context_type,
"context_id": self.context_id,
"timestamp": self.timestamp.isoformat(),
}
@classmethod
def _base_fromDict(cls: Type[T], ev: T, data: Dict[str, Any]) -> T:
ev.id = data["id"]
ev.participant_id = data["participant_id"]
ev.context_type = data["context_type"]
ev.context_id = data["context_id"]
ev.timestamp = datetime.fromisoformat(data["timestamp"])
return ev
@staticmethod
def fromDict(data: Dict[str, Any]) -> "WarEvent":
ev_type = data["type"]
cls = cast(Type[WarEvent], EVENT_REGISTRY.get(ev_type))
if cls is None:
raise ValueError(f"Unknown event type: {ev_type}")
return cls.fromDict(data)
@register_event
class TieResolved(WarEvent):
TYPE = "TieResolved"
def __init__(
self,
participant_id: str | None,
context_type: str,
context_id: str,
score_value: int | None = None,
):
super().__init__(participant_id, context_type, context_id)
self.score_value = score_value
def toDict(self) -> Dict[str, Any]:
d = super().toDict()
d.update(
{
"score_value": self.score_value or None,
}
)
return d
@classmethod
def fromDict(cls, data: Dict[str, Any]) -> TieResolved:
ev = cls(
data["participant_id"] or None,
data["context_type"],
data["context_id"],
data["score_value"] or None,
)
return cls._base_fromDict(ev, data)
@register_event
class InfluenceGained(WarEvent):
TYPE = "InfluenceGained"
def __init__(
self, participant_id: str, amount: int, context_type: str, context_id: str
):
super().__init__(participant_id, context_type, context_id)
self.amount = amount
def toDict(self) -> Dict[str, Any]:
d = super().toDict()
d.update(
{
"amount": self.amount,
}
)
return d
@classmethod
def fromDict(cls, data: Dict[str, Any]) -> InfluenceGained:
ev = cls(
data["participant_id"],
int(data["amount"]),
data["context_type"],
data["context_id"],
)
return cls._base_fromDict(ev, data)
@register_event
class InfluenceSpent(WarEvent):
TYPE = "InfluenceSpent"
def __init__(
self, participant_id: str, amount: int, context_type: str, context_id: str
):
super().__init__(participant_id, context_type, context_id)
self.amount = amount
def toDict(self) -> Dict[str, Any]:
d = super().toDict()
d.update(
{
"amount": self.amount,
}
)
return d
@classmethod
def fromDict(cls, data: Dict[str, Any]) -> InfluenceSpent:
ev = cls(
data["participant_id"],
int(data["amount"]),
data["context_type"],
data["context_id"],
)
return cls._base_fromDict(ev, data)