source documentation¶
event¶
-
class
simpy_events.event.
Callbacks
(event, before, callbacks, after)¶ Replace the ‘callbacks’ list in
simpy.events.Event
objects.Internally used to replace the single list of callbacks in
simpy.events.Event
objects.See also
It allows to add the
Event
’s hooks before, when and after thesimpy.events.Event
object is processed bysimpy
(that is when the items from its “callbacks” list are called).Callbacks
is intended to replace the originalcallbacks
list of thesimpy.events.Event
object When iterated, it chains the functions attached tobefore
,callbacks
andafter
.In order to behave as expected by
simpy
, adding or removing items from aCallbacks
object works as expected bysimpy
:Callbacks
is acollections.MutableSequence
and callables added or removed from it will be called bysimpy
as regular callbacks, i.e f(event) where event is asimpy.events.Event
object.When used to replace the
simpy.events.Event
’s callbacks attribute, it ensures the correct order is maintained if the originalsimpy.events.Event
’s callbacks attribute was itself aCallbacks
object, example:cross_red_light = Event(name='cross red light') get_caught = Event(name='caught on camera') evt = cross_red_light(env.timeout(1)) yield get_caught(evt)
In this example, the call order will be as follows
- cross_red_light's before - get_caught's before - cross_red_light's callbacks - get_caught's callbacks - cross_red_light's after - get_caught's after
-
__delitem__
(index)¶ del callable item from ‘callbacks’ list
-
__getitem__
(index)¶ return callable item from ‘callbacks’ list
-
__init__
(event, before, callbacks, after)¶ Attach the
Callbacks
obj to asimpy.events.Event
obj.event
is thesimpy.events.Event
object whosecallbacks
attribute is going to be replaced by thisCallbacks
object.before
,callbacks
andafter
are callables which will be called respectively before, when and after theevent
is actually processed bysimpy
.
-
__len__
()¶ return number of callable items in ‘callbacks’ list
-
__setitem__
(index, value)¶ set callable item in ‘callbacks’ list
-
insert
(index, value)¶ insert callable item in ‘callbacks’ list
-
-
class
simpy_events.event.
Context
(**attributes)¶ context object forwarded to event handlers by
EventDispatcher
contains following attributes:
event
, theEvent
instancehook
, the name of the hook
-
class
simpy_events.event.
Event
(**metadata)¶ Event
provides a node to access the event system.an
Event
is an endpoint that allows to dispatch ahook
to a set of handlers. Ahook
identifies a particular state for theEvent
, noteEvent
is intended to be used to wrappsimpy.events.Event
objects.- enable: triggered when
Event.enabled
is set toTrue
- disable: triggered when
Event.enabled
is set to toFalse
- before: just before the
simpy.events.Event
is processed bysimpy
- callbacks: when the
simpy.events.Event
is processed bysimpy
(i.e when callbacks are called) - after: just after the
simpy.events.Event
is processed bysimpy
Event
provides two options to dispatch an event through the event system:immediately dispatch a
hook
withEvent.dispatch
: although this method is used internally it may be used to dispatch any arbitraryhook
immediately.call the
Event
providing asimpy.events.Event
object, so the ‘before’, ‘callbacks’ and ‘after’ hooks will be dispatched automatically when the event is processed by thesimpy
loop.See also
Event
is initialized with optionalmetadata
attributes, provided as keyword args, which will be kept alltogather inEvent.metadata
attribute.handlers:
Handlers are attached to an
Event
using theEvent.topics
list, which is expected to contain a sequence of mappings, each mapping holding itself a sequence of callable handlers for a givenhook
, for exevt = Event() topic1 = { 'before': [h1, h2, h3], 'after': [h4, h5], } evt.topics.append(topic1)
Note
a topic is not expected to contain all the possible hook keys, it will be ignored if the hook is not found.
events dispatching:
Event.dispatcher
holds a dispatcher object (such asEventDispatcher
) that is called by theEvent
when dispatching a hook.Note setting
Event.dispatcher
toNone
will prevent anything from being dispatched for theEvent
instance.See also
Event.enabled
offers a switch to enable / disable dispatching. It also allows to notify handlers when theEvent
is enabled or disabled, for instance when adding / removing anEvent
in the simulation.-
__call__
(event)¶ Automatically trigger the
Event
whenevent
is processed.The
Event
will be attached to the providedsimpy.events.Event
object via its callbacks, and the following hooks will be dispatched whenevent
is processed bysimpy
(i.e when its callbacks are called) :- before: just before
event
is processed - callbacks: when
event
is processed - after: just after
event
is processed
Replaces the
simpy.events.Event
callbacks attribute by aCallbacks
instance so the hooks subscribed to thisEvent
will be called when thesimpy.events.Event
is processed bysimpy
.When the
simpy.events.Event
is processed, then callsEvent.dispatch
respectively for ‘before’, ‘callbacks’ and ‘after’ hooks.return the
simpy.events.Event
object.example usage in a typical
simpy
processsomething_happens = Event(name='important', context='test') def my_process(env): [...] yield something_happens(env.timeout(1))
- before: just before
-
__init__
(**metadata)¶ Initialized a new
Event
object with optionalmetadata
metadata
keyword args are kept inEvent.metadata
.
-
dispatch
(hook, data=None)¶ immediately dispatch
hook
for thisEvent
.hook
is the name of the hook to dispatch, for instance ‘before’, ‘after’…etc.data
is an optional object to forward to the handlers. It will beNone
by default.
Does nothing if
Event.enabled
isFalse
orEvent.dispatcher
isNone
.calls the
dispatcher.dispatch
method with the following arguments:event
: theEvent
instancehook
data
-
enabled
¶ enable / disable dispatching for the
Event
.when the value of
Event.enabled
is changed the following hooks are dispatched:- enable is dispatched just after the value is changed
- disable is dispatched just before the value is changed
See also
- enable: triggered when
-
class
simpy_events.event.
EventDispatcher
¶ Responsible for dispatching an event to
Event
’s handlersuses the
Event
’s sequence oftopics
to get all handlers for a givenhook
and call them sequentially.-
dispatch
(event, hook, data)¶ dispatch the event to each topic in
Event.topics
.args:
event
, theEvent
instancehook
, the name of the hook to dispatchdata
, data associated to the event
See also
Each
topic
is expected to be a mapping containing a sequence of handlers for a givenhook
. Thetopic
will be ignored if it doesn’t contain thehook
key.For each sequence of handlers found for
hook
, atuple
is created to ensure consistency while iterating (it’s likely handlers are removed / added while dispatching).Handlers are then called sequentially with the following arguments:
context
, aContext
objectdata
-
manager¶
-
class
simpy_events.manager.
EventType
(ns, name)¶ Link a set of
simpy_events.event.Event
instances to a name.EventType
allows to define an event type identified by a name in a givenNameSpace
, and createsimpy_events.event.Event
instances from it, which will allow to manage those instances as a group and share common properties:Topic
objects can be added to theEventType
and then automatically linked to thesimpy_events.event.Event
instances.- the
simpy_events.event.Event
instances are managed through theNameSpace
/EventType
hierarchy that allows to manage thesimpy_events.event.Event.dispatcher
andsimpy_events.event.Event.enabled
values either for a givenNameSpace
or a givenEventType
. - the
NameSpace
instance and the name of theEventType
will be given as metadata to the created events (seeEventType.create
).
Todo
remove event instance ?
-
__init__
(ns, name)¶ initializes an
EventType
attached tons
by namename
.See also
EventType
are expected to be initialized automatically, see alsoNameSpace.event_type
.ns
is theNameSpace
instance that created and holds theEventType
.name
is the name of theEventType
and under which it’s identified in its parentns
.
-
add_topic
(topic)¶ add a
Topic
object to thisEventType
.This will immediately link the
Topic
to the existing and future createdsimpy_events.event.Event
instances for thisEventType
,
-
create
(**metadata)¶ create a
simpy_events.event.Event
instancemetadata
are optional keyword args that will be forwarded as it is to initialize the event.by default two keyword args are given to the
simpy_events.event.Event
class:ns
: theNameSpace
instance (EventType.ns
)name
: the name of theEventType
(EventType.name
)
those values will be overriden by custom values if corresponding keyword are contained in
metadata
.Once the event has been created the
Topic
objects linked to theEventType
are linked to thesimpy_events.event.Event
instance.Then
simpy_events.event.Event.enabled
andsimpy_events.event.Event.dispatcher
values for the created event are synchronized with the hierarchy (NameSpace
/EventType
).
-
instances
¶ iter on created
simpy_events.event.Event
instances
-
class
simpy_events.manager.
EventsPropertiesMixin
(parent, **values)¶ Internally used mixin class to add
EventsProperty
instancesThis class add an
EventsProperty
instance for each attribute name inEventsPropertiesMixin._props
:- “dispatcher”
- “enabled”
This is used to ensure a hierarchically set value for the corresponding attribute of
simpy_events.event.Event
instances.For each attribute:
- a
property
is used to set / get the value - the
EventsProperty
object is stored in a private attribute using the name ‘_{attr_name}’ (ex: “_dispatcher”)
Then the
EventsPropertiesMixin._add_event_properties
andEventsPropertiesMixin.remove_event_properties
methods can be used in subclasses to add / remove an event to / from theEventsProperty
instances.-
__init__
(parent, **values)¶ parent
is eitherNone
or aEventsPropertiesMixin
.values
are optional extra keyword args to initialize the value of theEventsProperty
objects (ex: dispatcher=…).For each managed attribute, the
EventsProperty
object is stored in a private attribute using the name ‘_{attr_name}’ (ex: “_dispatcher”).
-
_add_event_properties
(event)¶ used in subclasses to add a
simpy_events.event.Event
.This add the event to each contained
EventsProperty
object, so the corresponding attribute is hierarchically set for the event.
-
_remove_event_properties
(event)¶ used in subclasses to remove a
simpy_events.event.Event
.This remove the event from each contained
EventsProperty
object.
-
class
simpy_events.manager.
EventsProperty
(name, value, parent)¶ Set an attribue value for a hierarchy of parents/children
EventsProperty
is used internally to automatically set the value of a specific attribute from a parent down to a hierarchy given the following rules:- the value of the parent is set recursively to children until
a child contains a not
None
value. - if the value of a given node is set to
None
then the first parent whose value is notNone
will be used to replace the value recursively.
In other words
EventsProperty
ensures the a hierarchically set value that can be overriden by children nodes.See also
-
__init__
(name, value, parent)¶ creates a new hierarchical attribute linked to
parent
for each event added to this node its
name
attribute will be set every time the applicable value is updated (thisEventsProperty
’s value or a parent value depending on whether the value isNone
or not).
-
add_event
(event)¶ add an event to this node
the corresponding attribute will be hierarchically set starting from this node in the hierarchy for the added event.
-
remove_event
(event)¶ remove an event from the hierarchy.
This doesn’t modify the corresponding attribute.
-
value
¶ return the current value of this node in the hierarchy
- the value of the parent is set recursively to children until
a child contains a not
-
class
simpy_events.manager.
Handlers
(lst=None)¶ Holds a sequence of handlers.
Handlers
is a sequence object which holds handlers for a specific hook in a topic.See also
Handlers
behave like alist
expect it’s also callable so it can be used as a decorator to append handlers to it.-
__call__
(fct)¶ append
fct
to the sequence.Handlers
object can be used as a decorator to append a handler to it.
-
__init__
(lst=None)¶ Initialize self. See help(type(self)) for accurate signature.
-
insert
(index, value)¶ S.insert(index, value) – insert value before index
-
-
class
simpy_events.manager.
NameSpace
(parent, name, root, **kwargs)¶ Define a hierarchical name space to link events and handlers.
NameSpace
provides a central node to automatically linksimpy_events.event.Event
objects and their handlers.NameSpace
allows to defineEventType
objects and createsimpy_events.event.Event
instances associated with those event types.It also allows to define
Topic
objects and link them to event types. Handlers can then be attached to theTopic
objects, which will automatically link them to the relatedsimpy_events.event.Event
instances.Then,
NameSpace
andEventType
also allow to set / overridesimpy_events.event.Event.enabled
andsimpy_events.event.Event.dispatcher
attributes at a given point in the hierarchy.See also
-
__init__
(parent, name, root, **kwargs)¶ NameSpace
are expected to be initialized automaticallySee also
parent
is the parentNameSpace
that created itname
is the name of theNameSpace
root
is theRootNameSpace
for the hierarchy- additional
kwargs
are forwarded toEventsPropertiesMixin
-
event
(name, *args, **kwargs)¶ create a
simpy_events.event.Event
instancename
is the name of the event type to use, it is either relative or absolute (seeNameSpace.event_type
).additional
args
andkwargs
are forwarded toEventType.create
.NameSpace.event
is a convenience method, the followingns.event('my event')
is equivalent to
ns.event_type('my event').create()
-
event_type
(name)¶ find or create an
EventType
name
is either relative or absolute (seeNameSpace.ns
for details).Note
the
EventType
objects have their own mapping within a givenNameSpace
, this means anEventType
and a childNameSpace
can have the same name, ex:ns.event_type('domain') ns.ns('domain')
will create the
EventType
instance if it doesn’t exist.
-
handlers
(name, hook)¶ return the handlers for the topic
name
and the hookhook
This is a convenience method that returns the
Handlers
sequence for a givenhook
in a givenTopic
.See also
Then the following
ns.handlers('my topic', 'before')
is equivalent to
ns.topic('my topic').handlers('before')
Note
this method can be used as a decorator to register a handler, for ex
@ns.handlers('my topic', 'before') def handler(context, data): pass
-
name
¶ (read only) the name of the
NameSpace
example:
root = RootNameSpace(dispatcher) ns = root.ns('first::second::third') assert ns.name == 'third'
-
ns
(name)¶ return or create the child
NameSpace
forname
There is a unique
name
:NameSpace
pair from a givenNameSpace
instance. It’s automatically created when accessing it if it doesn’t exist.name
is either a relative or absolute name. An absolute name begins with ‘::’.If
name
is absolute theNameSpace
is referenced from theRootNameSpace
in the hierarchy, ex:ns = root.ns('one') assert ns.ns('::one::two') is root.ns('one::two')
On the other hand a relative name references a
NameSpace
from the node on which ns is called, ex:ns = root.ns('one') assert ns.ns('one::two') is not root.ns('one::two') assert ns.ns('one::two') is ns.ns('one').ns('two') assert ns.ns('one::two') is root.ns('one::one::two')
Note
name
cannnot be empty (ValueError
), and redundant separators (‘::’), as well as trailing separators will be ignored, ex:ns1 = ns.ns('::::one::::two::::::::three::') assert ns1 is ns.ns('::one::two::three')
Note
‘:’ will be processed as a normal character, ex:
assert ns.ns(':one').name == ':one' ns1 = ns.ns(':one::two:::::three:') ns2 = ns.ns(':one').ns('two').ns(':').ns('three:') assert ns1 is ns2
See also
-
path
¶ (read only) return the absolute path of in the hierarchy
example:
root = RootNameSpace(dispatcher) ns = root.ns('first::second::third') assert ns.path == '::first::second::third'
Note
str(ns) will return ns.path
-
topic
(name)¶ find or create an
Topic
name
is either relative or absolute (seeNameSpace.ns
for details).Note
the
Topic
objects have their own mapping within a givenNameSpace
, this means anTopic
and a childNameSpace
can have the same name, ex:ns.topic('domain') ns.ns('domain')
will create the
Topic
instance if it doesn’t exist.
-
-
class
simpy_events.manager.
RootNameSpace
(dispatcher=None, enabled=False)¶ The root
NameSpace
object in the hierarchy.the
RootNameSpace
differs fromNameSpace
because it has no parent, as a consequence:RootNameSpace.path
returnsNone
RootNameSpace.name
returnsNone
RootNameSpace.dispatcher
cannot beNone
(i.e unspecified)a value can be specified when creating the instance, otherwise a
simpy_events.event.EventDispatcher
will be createdRootNameSpace.enabled
cannot beNone
(i.e unspecified)the value can be specifiied at creation (
False
by default)
-
__init__
(dispatcher=None, enabled=False)¶ init the root
NameSpace
in the hierarchydispatcher
: used (unless overriden in children) to setsimpy_events.event.Event.dispatcher
if the value is not provided then a
simpy_events.event.EventDispatcher
is createdenabled
: used (unless overriden in children) to set
Default value is
False
-
path
¶ (read only) return the absolute path of in the hierarchy
example:
root = RootNameSpace(dispatcher) ns = root.ns('first::second::third') assert ns.path == '::first::second::third'
Note
str(ns) will return ns.path
-
class
simpy_events.manager.
Topic
(ns, name)¶ Holds a mapping of handlers to link to specific events.
Topic
is a sequence that contains names of events to be linked automatically when they are created or the name of existing events is added.When events are created they’re registered by event type (
EventType
), identified by a name. If that name is contained in aTopic
then the topic will be added to thesimpy_events.event.Event
’stopcis
sequence and the handlers it contains will be called when the event is dispatched.a
Topic
carries adict
containing sequences of handlers for specific hooks (‘before’, ‘after’…), and thisdict
is added tosimpy_events.event.Event
’s topics. The topic’s dict is added to an event’s topics sequence either when thesimpy_events.event.Event
is created or when the corresponding event’s type (name) is added to theTopic
.Topic
’sdict
contains key:value pairs where keys are hook names (‘before’, ‘after’…) and values areHandlers
objects. The handler functions added to theTopic
are added to theHandlers
objects.The topic is removed automatically from an
simpy_events.event.Event
if the corresponding event type (name) is removed from theTopic
.-
__delitem__
(index)¶ remove an event name from the
Topic
this will remove the topic from the events identified by the event name at the removed
index
.Note
cannot use a
slice
asindex
, this will raise aNotImplementedError
.
-
__init__
(ns, name)¶ initializes a
Topic
attached tons
by its namename
.See also
Topic
are expected to be initialized automatically, see alsoNameSpace.topic
.ns
is theNameSpace
instance that created and holds theTopic
.name
is the name of theTopic
and under which it’s identified in its parentns
.
-
__setitem__
(index, event)¶ add an event name to the
Topic
this will take care of removing the topic from the events identified by the current event name at the specified
index
then the new event name will be added to the sequence and the corresponding events will be linked if instances exist.
Note
cannot use a
slice
asindex
, this will raise aNotImplementedError
.
-
get_handlers
(hook)¶ eq. to
Topic.handlers
but doesnt create theHandlers
-
handlers
(hook)¶ return the
Handlers
sequence for the hookhook
.the
Handlers
sequence for a given hook (i.e ‘before’, ‘after’…) is created in a lazy way by theTopic
.See also
simpy_events.event.Event
for details about hooks.Since
Handlers
can be used as a decorator itself to add a handler to it, this method can be used as a decorator to register a handler, for ex@topic.handlers('before') def handler(context, data): pass
See also
Topic.get_handlers
Topic.enable
Topic.disable
Topic.before
Topic.callbacks
Topic.after
-