event#
- bamengine.core.decorators.event(cls=None, *, name=None, after=None, before=None, replace=None, **dataclass_kwargs)[source]#
Decorator to define an Event with automatic inheritance and dataclass.
This decorator dramatically simplifies Event definition by: 1. Making the class inherit from Event (if not already) 2. Applying @dataclass(slots=True) 3. Handling registration automatically 4. Optionally storing pipeline hook metadata for explicit positioning
- Parameters:
cls (
type | None) – The class to decorate (provided automatically when used without parens)name (
str | None) – Optional custom name for the event. If None, uses class name (snake_case).after (
str | None) – Insert this event immediately after the target event in the pipeline. Hooks are applied explicitly viasim.use_events()orpipeline.apply_hooks().before (
str | None) – Insert this event immediately before the target event in the pipeline.replace (
str | None) – Replace the target event with this event in the pipeline.**dataclass_kwargs (
Any) – Additional keyword arguments to pass to @dataclass. By default, slots=True is set.
- Returns:
The decorated class or a decorator function
- Return type:
type | Callable- Raises:
ValueError – If more than one of
after,before, orreplaceis specified.
Examples
Simplest usage (no inheritance needed):
>>> from bamengine import Simulation >>> @event ... class Planning: ... def execute(self, sim: Simulation) -> None: ... pass # implementation
With custom name:
>>> @event(name="my_planning") ... class Planning: ... def execute(self, sim: Simulation) -> None: ... pass # implementation
With pipeline hook (inserted after another event):
>>> @event(after="firms_pay_dividends") ... class MyCustomEvent: ... def execute(self, sim: Simulation) -> None: ... pass # Applied via sim.use_events(MyCustomEvent)
With pipeline hook (inserted before another event):
>>> @event(before="firms_adjust_price") ... class PrePricingCheck: ... def execute(self, sim: Simulation) -> None: ... pass # Applied via sim.use_events(PrePricingCheck)
With pipeline hook (replaces another event):
>>> @event(replace="firms_decide_desired_production") ... class CustomProductionRule: ... def execute(self, sim: Simulation) -> None: ... pass # This event replaces the original
Notes
Pipeline hooks are stored as class attributes (
_hook_after,_hook_before,_hook_replace) and applied explicitly viasim.use_events()orpipeline.apply_hooks().Multiple events can target the same hook point. They are inserted in the order passed to
apply_hooks()(first = closest to target event).See also
PipelinePipeline that applies hooks
use_events()Apply hooks to simulation