Protocols¶
Protocol definitions for duck-typing compatibility across the simulation framework.
Protocol definitions for duck-typed simulation components.
This module defines structural types (Protocols) that allow any class with the right methods to participate in a simulation, without requiring inheritance from Entity.
Two approaches are supported: 1. Inherit from Entity (traditional, explicit contract) 2. Implement the Simulatable protocol (duck typing, no inheritance required)
Example using duck typing
class MyClient: def init(self, name: str): self.name = name self._clock: Clock | None = None
def set_clock(self, clock: Clock) -> None:
self._clock = clock
@property
def now(self) -> Instant:
return self._clock.now
def handle_event(self, event: Event) -> list[Event] | None:
# process event
return []
Or use the @simulatable decorator for automatic clock injection: from happysimulator.core.decorators import simulatable
@simulatable
class MyClient:
def __init__(self, name: str):
self.name = name
def handle_event(self, event: Event) -> list[Event] | None:
print(f"Processing at {self.now}") # self.now is injected
return []
Simulatable ¶
Bases: Protocol
Protocol for objects that can participate in a simulation.
Any class that implements these methods can be used as an entity in the simulation, without inheriting from Entity. The @runtime_checkable decorator allows isinstance() checks at runtime.
Required attributes
name: Identifier for logging and debugging.
Required methods
set_clock: Called by Simulation to inject the shared clock. handle_event: Process incoming events and return reactions.
Optional methods
has_capacity: Override to model resource constraints (defaults to True).
set_clock ¶
Receive the simulation clock for time-aware operations.
Called automatically by Simulation during initialization. Store the clock to access simulation time via clock.now.
handle_event ¶
Process an incoming event and return any resulting events.
Returns:
| Name | Type | Description |
|---|---|---|
Generator |
HandleEventReturn
|
For multi-step processes. Yield delays; optionally return events on completion. |
HandleEventReturn
|
list[Event] | Event | None: For immediate, single-step responses. |
HasCapacity ¶
Bases: Protocol
Optional protocol for entities with resource constraints.
Entities that implement has_capacity() can signal when they're unable to accept additional work (e.g., server at max connections).