66from logging import getLogger
77from typing import TYPE_CHECKING , cast
88
9+ from streamdeck .event_handlers .protocol import (
10+ EventHandlerFunc ,
11+ EventModel_contra ,
12+ InjectableParams ,
13+ SupportsEventHandlers ,
14+ )
15+
916
1017if TYPE_CHECKING :
1118 from collections .abc import Callable , Generator
12- from typing import Protocol
13-
14- from typing_extensions import ParamSpec , TypeVar
1519
16- from streamdeck .models .events import EventBase
1720 from streamdeck .types import ActionUUIDStr , EventNameStr
1821
1922
2023
21- EventModel_contra = TypeVar ("EventModel_contra" , bound = EventBase , default = EventBase , contravariant = True )
22- InjectableParams = ParamSpec ("InjectableParams" , default = ...)
23-
24- class EventHandlerFunc (Protocol [EventModel_contra , InjectableParams ]):
25- """Protocol for an event handler function that takes an event (of subtype of EventBase) and other parameters that are injectable."""
26- def __call__ (self , event_data : EventModel_contra , * args : InjectableParams .args , ** kwargs : InjectableParams .kwargs ) -> None : ...
27-
28-
29-
3024logger = getLogger ("streamdeck.actions" )
3125
3226
33- class ActionBase (ABC ):
27+ class ActionBase (ABC , SupportsEventHandlers ):
3428 """Base class for all actions."""
29+ _events : dict [EventNameStr , set [EventHandlerFunc ]]
30+ """Dictionary mapping event names to sets of event handler functions."""
3531
3632 def __init__ (self ) -> None :
3733 """Initialize an Action instance."""
38- self ._events : dict [ EventNameStr , set [ EventHandlerFunc ]] = defaultdict (set )
34+ self ._events = defaultdict (set )
3935
4036 def on (self , event_name : EventNameStr , / ) -> Callable [[EventHandlerFunc [EventModel_contra , InjectableParams ]], EventHandlerFunc [EventModel_contra , InjectableParams ]]:
4137 """Register an event handler for a specific event.
@@ -88,6 +84,8 @@ class GlobalAction(ActionBase):
8884
8985class Action (ActionBase ):
9086 """Represents an action that can be performed for a specific action, with event handlers for specific event types."""
87+ uuid : ActionUUIDStr
88+ """The unique identifier for the action."""
9189
9290 def __init__ (self , uuid : ActionUUIDStr ) -> None :
9391 """Initialize an Action instance.
@@ -104,37 +102,3 @@ def name(self) -> str:
104102 return self .uuid .split ("." )[- 1 ]
105103
106104
107- class ActionRegistry :
108- """Manages the registration and retrieval of actions and their event handlers."""
109-
110- def __init__ (self ) -> None :
111- """Initialize an ActionRegistry instance."""
112- self ._plugin_actions : list [ActionBase ] = []
113-
114- def register (self , action : ActionBase ) -> None :
115- """Register an action with the registry.
116-
117- Args:
118- action (Action): The action to register.
119- """
120- self ._plugin_actions .append (action )
121-
122- def get_action_handlers (self , event_name : EventNameStr , event_action_uuid : ActionUUIDStr | None = None ) -> Generator [EventHandlerFunc , None , None ]:
123- """Get all event handlers for a specific event from all registered actions.
124-
125- Args:
126- event_name (EventName): The name of the event to retrieve handlers for.
127- event_action_uuid (str | None): The action UUID to get handlers for.
128- If None (i.e., the event is not action-specific), get all handlers for the event.
129-
130- Yields:
131- EventHandlerFunc: The event handler functions for the specified event.
132- """
133- for action in self ._plugin_actions :
134- # If the event is action-specific (i.e is not a GlobalAction and has a UUID attribute),
135- # only get handlers for that action, as we don't want to trigger
136- # and pass this event to handlers for other actions.
137- if event_action_uuid is not None and (isinstance (action , Action ) and action .uuid != event_action_uuid ):
138- continue
139-
140- yield from action .get_event_handlers (event_name )
0 commit comments