1- from inspect import isawaitable
21from typing import TYPE_CHECKING
32from typing import List
43from uuid import uuid4
87from .exceptions import InvalidDefinition
98from .i18n import _
109from .transition_mixin import AddCallbacksMixin
11- from .utils import run_async_from_sync
1210
1311if TYPE_CHECKING :
1412 from .statemachine import StateMachine
@@ -44,6 +42,9 @@ class Event(AddCallbacksMixin, str):
4442 name : str
4543 """The event name."""
4644
45+ delay : float = 0
46+ """The delay in milliseconds before the event is triggered. Default is 0."""
47+
4748 _sm : "StateMachine | None" = None
4849 """The state machine instance."""
4950
@@ -55,6 +56,7 @@ def __new__(
5556 transitions : "str | TransitionList | None" = None ,
5657 id : "str | None" = None ,
5758 name : "str | None" = None ,
59+ delay : float = 0 ,
5860 _sm : "StateMachine | None" = None ,
5961 ):
6062 if isinstance (transitions , str ):
@@ -66,6 +68,7 @@ def __new__(
6668
6769 instance = super ().__new__ (cls , id )
6870 instance .id = id
71+ instance .delay = delay
6972 if name :
7073 instance .name = name
7174 elif _has_real_id :
@@ -106,19 +109,13 @@ def __get__(self, instance, owner):
106109 """
107110 if instance is None :
108111 return self
109- return BoundEvent (id = self .id , name = self .name , _sm = instance )
112+ return BoundEvent (id = self .id , name = self .name , delay = self . delay , _sm = instance )
110113
111- def __call__ (self , * args , ** kwargs ):
112- """Send this event to the current state machine.
113-
114- Triggering an event on a state machine means invoking or sending a signal, initiating the
115- process that may result in executing a transition.
116- """
114+ def put (self , * args , machine : "StateMachine" , ** kwargs ):
117115 # The `__call__` is declared here to help IDEs knowing that an `Event`
118116 # can be called as a method. But it is not meant to be called without
119117 # an SM instance. Such SM instance is provided by `__get__` method when
120118 # used as a property descriptor.
121- machine = self ._sm
122119 if machine is None :
123120 raise RuntimeError (_ ("Event {} cannot be called without a SM instance" ).format (self ))
124121
@@ -130,10 +127,20 @@ def __call__(self, *args, **kwargs):
130127 kwargs = kwargs ,
131128 )
132129 machine ._put_nonblocking (trigger_data )
133- result = machine ._processing_loop ()
134- if not isawaitable (result ):
135- return result
136- return run_async_from_sync (result )
130+
131+ def __call__ (self , * args , ** kwargs ):
132+ """Send this event to the current state machine.
133+
134+ Triggering an event on a state machine means invoking or sending a signal, initiating the
135+ process that may result in executing a transition.
136+ """
137+ # The `__call__` is declared here to help IDEs knowing that an `Event`
138+ # can be called as a method. But it is not meant to be called without
139+ # an SM instance. Such SM instance is provided by `__get__` method when
140+ # used as a property descriptor.
141+ machine = self ._sm
142+ self .put (* args , machine = machine , ** kwargs )
143+ return machine ._processing_loop ()
137144
138145 def split ( # type: ignore[override]
139146 self , sep : "str | None" = None , maxsplit : int = - 1
0 commit comments