event bus
event_bus
Event-bus API for Femora lifecycle coordination.
This page documents the event objects that power Femora's advanced lifecycle
hooks. A Model owns a per-model event bus exposed
as model.events. Runtime subsystems such as the assembler emit
FemoraEvent values at key
stages, and subscribed callbacks receive payload data describing what just
happened.
This mechanism is mainly useful for advanced extension work. Ordinary modeling flows usually create components directly through managers and do not need to subscribe to events.
Under the hood, the flow looks like this:
- a runtime subsystem reaches a lifecycle stage such as
POST_ASSEMBLE - it emits a
FemoraEventthrough the model-owned bus - subscribers receive keyword-argument payload data
- advanced components inspect the payload and react
Example
from femora.core.model import Model
from femora.components.event.event_bus import FemoraEvent
model = Model()
def on_post_assemble(**payload):
assembled_mesh = payload.get("assembled_mesh")
if assembled_mesh is not None:
print(f"assembled cells: {assembled_mesh.n_cells}")
model.events.subscribe(FemoraEvent.POST_ASSEMBLE, on_post_assemble)
Tip
Prefer the model-owned model.events bus for new code. The legacy
EventBus wrapper is kept
for compatibility with older code paths and tests.
Classes
FemoraEvent
Bases: Enum
Lifecycle signals emitted by Femora runtime subsystems.
These enum values describe when a callback is being invoked. They are not ordinary modeling commands. Instead, they mark important stages in the runtime lifecycle so advanced components can react at the right time.
The most important practical events are:
PRE_ASSEMBLE: emitted before the final assembled mesh is builtPOST_ASSEMBLE: emitted after the final assembled mesh existsRESOLVE_CORE_CONFLICTS: emitted after assembly when partition/core ownership updates may need follow-up workPRE_EXPORTandPOST_EXPORT: emitted around export-time workflows
More specialized events such as EMBEDDED_BEAM_SOLID_TCL are used by
advanced exporters and interface-specific integrations.
ModelEventBus
Per-model publish/subscribe bus owned by a Model.
A Model creates one ModelEventBus and
exposes it through model.events. Managers and advanced components use
that bus to coordinate lifecycle work without tightly coupling themselves
to one another.
Callbacks are registered per FemoraEvent
and are invoked with keyword-argument payload data supplied by the emitter.
Example
from femora.core.model import Model
from femora.components.event.event_bus import FemoraEvent
model = Model()
def on_post_assemble(**payload):
assembled_mesh = payload.get("assembled_mesh")
if assembled_mesh is not None:
print(assembled_mesh.n_points)
model.events.subscribe(FemoraEvent.POST_ASSEMBLE, on_post_assemble)
Initialize an empty per-model subscriber registry.
Methods:
subscribe
Register a callback for one lifecycle event.
If the callback is already subscribed to the same event, it is not added a second time.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
FemoraEvent
|
Lifecycle event to listen for. |
required |
callback
|
Callable
|
Callable invoked when |
required |
unsubscribe
Remove a previously registered callback from one event.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
FemoraEvent
|
Lifecycle event previously used during subscription. |
required |
callback
|
Callable
|
Callback to remove. |
required |
emit
Dispatch one lifecycle event to its current subscribers.
The bus iterates over a snapshot of the subscriber list so callbacks can safely unsubscribe or adjust registrations during dispatch without corrupting the iteration order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
event
|
FemoraEvent
|
Lifecycle event being emitted. |
required |
**payload
|
Keyword arguments forwarded directly to each callback.
Emitters commonly provide objects such as |
{}
|
EventBus
Legacy process-global compatibility wrapper around ModelEventBus.
This class exists mainly to preserve older code paths and tests that still
expect a process-global event bus. New code should prefer the model-owned
ModelEventBus exposed through
model.events.
Under the hood, this wrapper forwards operations to an internal
ModelEventBus instance while preserving compatibility with older code
that mutates _subscribers directly.
Methods:
subscribe
classmethod
Register a callback through the legacy compatibility wrapper.
unsubscribe
classmethod
Remove a callback through the legacy compatibility wrapper.