summaryrefslogtreecommitdiff
path: root/wrappers/python/eduvpn_common/event.py
diff options
context:
space:
mode:
Diffstat (limited to 'wrappers/python/eduvpn_common/event.py')
-rw-r--r--wrappers/python/eduvpn_common/event.py76
1 files changed, 75 insertions, 1 deletions
diff --git a/wrappers/python/eduvpn_common/event.py b/wrappers/python/eduvpn_common/event.py
index e2bfabb..193e659 100644
--- a/wrappers/python/eduvpn_common/event.py
+++ b/wrappers/python/eduvpn_common/event.py
@@ -10,12 +10,25 @@ from eduvpn_common.server import (
from eduvpn_common.state import State, StateType
from eduvpn_common.types import get_ptr_string
+# The attribute that callback functions get
EDUVPN_CALLBACK_PROPERTY = "_eduvpn_property_callback"
# A state transition decorator for classes
# To use this, make sure to register the class with `register_class_callbacks`
def class_state_transition(state: int, state_type: StateType) -> Callable:
+ """A decorator to be internally by classes to register the event
+
+ :param state: int: The state of the transition
+ :param state_type: StateType: The type of transition
+
+ :meta: private:
+ """
def wrapper(func):
+ """
+
+ :param func: The function to set the internal attribute for
+
+ """
setattr(func, EDUVPN_CALLBACK_PROPERTY, (state, state_type))
return func
@@ -23,6 +36,14 @@ def class_state_transition(state: int, state_type: StateType) -> Callable:
def convert_data(lib: CDLL, state: int, data: Any) -> None:
+ """The function that converts the C structure from the Go library to a Python structure
+
+ :param lib: CDLL: The Go shared library
+ :param state: int: The state to convert the data for
+ :param data: Any: The data itself that has to be converted
+
+ :meta: private:
+ """
if not data:
return None
if state is State.NO_SERVER:
@@ -43,11 +64,19 @@ def convert_data(lib: CDLL, state: int, data: Any) -> None:
class EventHandler(object):
+ """The class that neatly handles event callbacks from the internal Go FSM"""
def __init__(self, lib: CDLL):
self.handlers: Dict[Tuple[int, StateType], List[Callable]] = {}
self.lib = lib
def change_class_callbacks(self, cls: Any, add: bool = True) -> None:
+ """The function that is used to change class callbacks
+
+ :param cls: Any: The class to change the callbacks for
+ :param add: bool: (Default value = True): Whether or not to add or remove the event. If true the event gets added
+
+ :meta: private:
+ """
# Loop over method names
for method_name in dir(cls):
try:
@@ -68,6 +97,14 @@ class EventHandler(object):
self.remove_event(state, state_type, method)
def remove_event(self, state: int, state_type: StateType, func: Callable) -> None:
+ """Removes an event
+
+ :param state: int: The state to remove the event for
+ :param state_type: StateType: The state type to remove the event for
+ :param func: Callable: The function that needs to be removed from the event
+
+ :meta: private:
+ """
for key, values in self.handlers.copy().items():
if key == (state, state_type):
values.remove(func)
@@ -77,13 +114,32 @@ class EventHandler(object):
self.handlers[key] = values
def add_event(self, state: int, state_type: StateType, func: Callable) -> None:
+ """Adds an event
+
+ :param state: int: The state to add the event for
+ :param state_type: StateType: The state type to add the event for
+ :param func: Callable: The function that needs to be added to the event
+
+ :meta: private:
+ """
if (state, state_type) not in self.handlers:
self.handlers[(state, state_type)] = []
self.handlers[(state, state_type)].append(func)
- # A decorator for standalone functions
def on(self, state: int, state_type: StateType) -> Callable:
+ """The decorator for standalone functions
+
+ :param state: int: The state of the event
+ :param state_type: StateType: The state type of the event
+
+ :meta: private:
+ """
def wrapped_f(func):
+ """
+
+ :param func: The function to add the event for
+
+ """
self.add_event(state, state_type, func)
return func
@@ -92,6 +148,15 @@ class EventHandler(object):
def run_state(
self, state: int, other_state: int, state_type: StateType, data: str
) -> None:
+ """The function that runs the callback for a specific event
+
+ :param state: int: The state of the event
+ :param other_state: int: The other state of the event
+ :param state_type: StateType: The state type of the event
+ :param data: str: The data that gets passed to the function callback when the event is ran
+
+ :meta: private:
+ """
if (state, state_type) not in self.handlers:
return
for func in self.handlers[(state, state_type)]:
@@ -100,6 +165,15 @@ class EventHandler(object):
def run(
self, old_state: int, new_state: int, data: Any, convert: bool = True
) -> None:
+ """Run a specific event.
+ It converts the data and then runs the event for all state types
+
+ :param old_state: int: The previous state for running the event
+ :param new_state: int: The new state for running the event
+ :param data: Any: The data that gets passed to the event
+ :param convert: bool: (Default value = True): Whether or not to convert the data further
+
+ """
# First run leave transitions, then enter
# The state is done when the wait event finishes
converted = data