source documentation¶
event¶
-
class
simpy_events.event.Callbacks(event, before, callbacks, after)¶ Replace the ‘callbacks’ list in
simpy.events.Eventobjects.Internally used to replace the single list of callbacks in
simpy.events.Eventobjects.See also
It allows to add the
Event’s hooks before, when and after thesimpy.events.Eventobject is processed bysimpy(that is when the items from its “callbacks” list are called).Callbacksis intended to replace the originalcallbackslist of thesimpy.events.Eventobject When iterated, it chains the functions attached tobefore,callbacksandafter.In order to behave as expected by
simpy, adding or removing items from aCallbacksobject works as expected bysimpy:Callbacksis acollections.MutableSequenceand callables added or removed from it will be called bysimpyas regular callbacks, i.e f(event) where event is asimpy.events.Eventobject.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 aCallbacksobject, 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
Callbacksobj to asimpy.events.Eventobj.eventis thesimpy.events.Eventobject whosecallbacksattribute is going to be replaced by thisCallbacksobject.before,callbacksandafterare callables which will be called respectively before, when and after theeventis 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
EventDispatchercontains following attributes:
event, theEventinstancehook, the name of the hook
-
class
simpy_events.event.Event(**metadata)¶ Eventprovides a node to access the event system.an
Eventis an endpoint that allows to dispatch ahookto a set of handlers. Ahookidentifies a particular state for theEvent, noteEventis intended to be used to wrappsimpy.events.Eventobjects.- enable: triggered when
Event.enabledis set toTrue - disable: triggered when
Event.enabledis set to toFalse - before: just before the
simpy.events.Eventis processed bysimpy - callbacks: when the
simpy.events.Eventis processed bysimpy(i.e when callbacks are called) - after: just after the
simpy.events.Eventis processed bysimpy
Eventprovides two options to dispatch an event through the event system:immediately dispatch a
hookwithEvent.dispatch: although this method is used internally it may be used to dispatch any arbitraryhookimmediately.call the
Eventproviding asimpy.events.Eventobject, so the ‘before’, ‘callbacks’ and ‘after’ hooks will be dispatched automatically when the event is processed by thesimpyloop.See also
Eventis initialized with optionalmetadataattributes, provided as keyword args, which will be kept alltogather inEvent.metadataattribute.handlers:
Handlers are attached to an
Eventusing theEvent.topicslist, 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.dispatcherholds a dispatcher object (such asEventDispatcher) that is called by theEventwhen dispatching a hook.Note setting
Event.dispatchertoNonewill prevent anything from being dispatched for theEventinstance.See also
Event.enabledoffers a switch to enable / disable dispatching. It also allows to notify handlers when theEventis enabled or disabled, for instance when adding / removing anEventin the simulation.-
__call__(event)¶ Automatically trigger the
Eventwheneventis processed.The
Eventwill be attached to the providedsimpy.events.Eventobject via its callbacks, and the following hooks will be dispatched wheneventis processed bysimpy(i.e when its callbacks are called) :- before: just before
eventis processed - callbacks: when
eventis processed - after: just after
eventis processed
Replaces the
simpy.events.Eventcallbacks attribute by aCallbacksinstance so the hooks subscribed to thisEventwill be called when thesimpy.events.Eventis processed bysimpy.When the
simpy.events.Eventis processed, then callsEvent.dispatchrespectively for ‘before’, ‘callbacks’ and ‘after’ hooks.return the
simpy.events.Eventobject.example usage in a typical
simpyprocesssomething_happens = Event(name='important', context='test') def my_process(env): [...] yield something_happens(env.timeout(1))
- before: just before
-
__init__(**metadata)¶ Initialized a new
Eventobject with optionalmetadatametadatakeyword args are kept inEvent.metadata.
-
dispatch(hook, data=None)¶ immediately dispatch
hookfor thisEvent.hookis the name of the hook to dispatch, for instance ‘before’, ‘after’…etc.datais an optional object to forward to the handlers. It will beNoneby default.
Does nothing if
Event.enabledisFalseorEvent.dispatcherisNone.calls the
dispatcher.dispatchmethod with the following arguments:event: theEventinstancehookdata
-
enabled¶ enable / disable dispatching for the
Event.when the value of
Event.enabledis 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 oftopicsto get all handlers for a givenhookand call them sequentially.-
dispatch(event, hook, data)¶ dispatch the event to each topic in
Event.topics.args:
event, theEventinstancehook, the name of the hook to dispatchdata, data associated to the event
See also
Each
topicis expected to be a mapping containing a sequence of handlers for a givenhook. Thetopicwill be ignored if it doesn’t contain thehookkey.For each sequence of handlers found for
hook, atupleis 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, aContextobjectdata
-
manager¶
-
class
simpy_events.manager.EventType(ns, name)¶ Link a set of
simpy_events.event.Eventinstances to a name.EventTypeallows to define an event type identified by a name in a givenNameSpace, and createsimpy_events.event.Eventinstances from it, which will allow to manage those instances as a group and share common properties:Topicobjects can be added to theEventTypeand then automatically linked to thesimpy_events.event.Eventinstances.- the
simpy_events.event.Eventinstances are managed through theNameSpace/EventTypehierarchy that allows to manage thesimpy_events.event.Event.dispatcherandsimpy_events.event.Event.enabledvalues either for a givenNameSpaceor a givenEventType. - the
NameSpaceinstance and the name of theEventTypewill be given as metadata to the created events (seeEventType.create).
Todo
remove event instance ?
-
__init__(ns, name)¶ initializes an
EventTypeattached tonsby namename.See also
EventTypeare expected to be initialized automatically, see alsoNameSpace.event_type.nsis theNameSpaceinstance that created and holds theEventType.nameis the name of theEventTypeand under which it’s identified in its parentns.
-
add_topic(topic)¶ add a
Topicobject to thisEventType.This will immediately link the
Topicto the existing and future createdsimpy_events.event.Eventinstances for thisEventType,
-
create(**metadata)¶ create a
simpy_events.event.Eventinstancemetadataare 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.Eventclass:ns: theNameSpaceinstance (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
Topicobjects linked to theEventTypeare linked to thesimpy_events.event.Eventinstance.Then
simpy_events.event.Event.enabledandsimpy_events.event.Event.dispatchervalues for the created event are synchronized with the hierarchy (NameSpace/EventType).
-
instances¶ iter on created
simpy_events.event.Eventinstances
-
class
simpy_events.manager.EventsPropertiesMixin(parent, **values)¶ Internally used mixin class to add
EventsPropertyinstancesThis class add an
EventsPropertyinstance 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.Eventinstances.For each attribute:
- a
propertyis used to set / get the value - the
EventsPropertyobject is stored in a private attribute using the name ‘_{attr_name}’ (ex: “_dispatcher”)
Then the
EventsPropertiesMixin._add_event_propertiesandEventsPropertiesMixin.remove_event_propertiesmethods can be used in subclasses to add / remove an event to / from theEventsPropertyinstances.-
__init__(parent, **values)¶ parentis eitherNoneor aEventsPropertiesMixin.valuesare optional extra keyword args to initialize the value of theEventsPropertyobjects (ex: dispatcher=…).For each managed attribute, the
EventsPropertyobject 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
EventsPropertyobject, 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
EventsPropertyobject.
-
class
simpy_events.manager.EventsProperty(name, value, parent)¶ Set an attribue value for a hierarchy of parents/children
EventsPropertyis 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
Nonevalue. - if the value of a given node is set to
Nonethen the first parent whose value is notNonewill be used to replace the value recursively.
In other words
EventsPropertyensures 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
parentfor each event added to this node its
nameattribute will be set every time the applicable value is updated (thisEventsProperty’s value or a parent value depending on whether the value isNoneor 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.
Handlersis a sequence object which holds handlers for a specific hook in a topic.See also
Handlersbehave like alistexpect it’s also callable so it can be used as a decorator to append handlers to it.-
__call__(fct)¶ append
fctto the sequence.Handlersobject 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.
NameSpaceprovides a central node to automatically linksimpy_events.event.Eventobjects and their handlers.NameSpaceallows to defineEventTypeobjects and createsimpy_events.event.Eventinstances associated with those event types.It also allows to define
Topicobjects and link them to event types. Handlers can then be attached to theTopicobjects, which will automatically link them to the relatedsimpy_events.event.Eventinstances.Then,
NameSpaceandEventTypealso allow to set / overridesimpy_events.event.Event.enabledandsimpy_events.event.Event.dispatcherattributes at a given point in the hierarchy.See also
-
__init__(parent, name, root, **kwargs)¶ NameSpaceare expected to be initialized automaticallySee also
parentis the parentNameSpacethat created itnameis the name of theNameSpacerootis theRootNameSpacefor the hierarchy- additional
kwargsare forwarded toEventsPropertiesMixin
-
event(name, *args, **kwargs)¶ create a
simpy_events.event.Eventinstancenameis the name of the event type to use, it is either relative or absolute (seeNameSpace.event_type).additional
argsandkwargsare forwarded toEventType.create.NameSpace.eventis a convenience method, the followingns.event('my event')
is equivalent to
ns.event_type('my event').create()
-
event_type(name)¶ find or create an
EventTypenameis either relative or absolute (seeNameSpace.nsfor details).Note
the
EventTypeobjects have their own mapping within a givenNameSpace, this means anEventTypeand a childNameSpacecan have the same name, ex:ns.event_type('domain') ns.ns('domain')
will create the
EventTypeinstance if it doesn’t exist.
-
handlers(name, hook)¶ return the handlers for the topic
nameand the hookhookThis is a convenience method that returns the
Handlerssequence for a givenhookin 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
NameSpaceexample:
root = RootNameSpace(dispatcher) ns = root.ns('first::second::third') assert ns.name == 'third'
-
ns(name)¶ return or create the child
NameSpacefornameThere is a unique
name:NameSpacepair from a givenNameSpaceinstance. It’s automatically created when accessing it if it doesn’t exist.nameis either a relative or absolute name. An absolute name begins with ‘::’.If
nameis absolute theNameSpaceis referenced from theRootNameSpacein 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
NameSpacefrom 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
namecannnot 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
Topicnameis either relative or absolute (seeNameSpace.nsfor details).Note
the
Topicobjects have their own mapping within a givenNameSpace, this means anTopicand a childNameSpacecan have the same name, ex:ns.topic('domain') ns.ns('domain')
will create the
Topicinstance if it doesn’t exist.
-
-
class
simpy_events.manager.RootNameSpace(dispatcher=None, enabled=False)¶ The root
NameSpaceobject in the hierarchy.the
RootNameSpacediffers fromNameSpacebecause it has no parent, as a consequence:RootNameSpace.pathreturnsNoneRootNameSpace.namereturnsNoneRootNameSpace.dispatchercannot beNone(i.e unspecified)a value can be specified when creating the instance, otherwise a
simpy_events.event.EventDispatcherwill be createdRootNameSpace.enabledcannot beNone(i.e unspecified)the value can be specifiied at creation (
Falseby default)
-
__init__(dispatcher=None, enabled=False)¶ init the root
NameSpacein the hierarchydispatcher: used (unless overriden in children) to setsimpy_events.event.Event.dispatcher
if the value is not provided then a
simpy_events.event.EventDispatcheris 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.
Topicis 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 aTopicthen the topic will be added to thesimpy_events.event.Event’stopcissequence and the handlers it contains will be called when the event is dispatched.a
Topiccarries adictcontaining sequences of handlers for specific hooks (‘before’, ‘after’…), and thisdictis added tosimpy_events.event.Event’s topics. The topic’s dict is added to an event’s topics sequence either when thesimpy_events.event.Eventis created or when the corresponding event’s type (name) is added to theTopic.Topic’sdictcontains key:value pairs where keys are hook names (‘before’, ‘after’…) and values areHandlersobjects. The handler functions added to theTopicare added to theHandlersobjects.The topic is removed automatically from an
simpy_events.event.Eventif the corresponding event type (name) is removed from theTopic.-
__delitem__(index)¶ remove an event name from the
Topicthis will remove the topic from the events identified by the event name at the removed
index.Note
cannot use a
sliceasindex, this will raise aNotImplementedError.
-
__init__(ns, name)¶ initializes a
Topicattached tonsby its namename.See also
Topicare expected to be initialized automatically, see alsoNameSpace.topic.nsis theNameSpaceinstance that created and holds theTopic.nameis the name of theTopicand under which it’s identified in its parentns.
-
__setitem__(index, event)¶ add an event name to the
Topicthis will take care of removing the topic from the events identified by the current event name at the specified
indexthen the new event name will be added to the sequence and the corresponding events will be linked if instances exist.
Note
cannot use a
sliceasindex, this will raise aNotImplementedError.
-
get_handlers(hook)¶ eq. to
Topic.handlersbut doesnt create theHandlers
-
handlers(hook)¶ return the
Handlerssequence for the hookhook.the
Handlerssequence for a given hook (i.e ‘before’, ‘after’…) is created in a lazy way by theTopic.See also
simpy_events.event.Eventfor details about hooks.Since
Handlerscan 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_handlersTopic.enableTopic.disableTopic.beforeTopic.callbacksTopic.after
-