Skip to content

Commit 01ef1d1

Browse files
committed
Refactor EventHandler import: move from model_system_event_listener to event_handler
1 parent 9d597af commit 01ef1d1

File tree

11 files changed

+77
-70
lines changed

11 files changed

+77
-70
lines changed

Scripts/assignment/assignment_period.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import pandas
44

55
from typing import TYPE_CHECKING, Any, Dict, Optional, Union
6-
from events.model_system_event_listener import EventHandler
6+
from events.event_handler import EventHandler
77
import utils.log as log
88
import parameters.assignment as param
99
import parameters.zone as zone_param

Scripts/assignment/emme_assignment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import parameters.zone as zone_param
1111
from assignment.abstract_assignment import AssignmentModel
1212
from assignment.assignment_period import AssignmentPeriod
13-
from events.model_system_event_listener import EventHandler
13+
from events.event_handler import EventHandler
1414
if TYPE_CHECKING:
1515
from assignment.emme_bindings.emme_project import EmmeProject
1616
from assignment.datatypes.transit_fare import TransitFareZoneSpecification

Scripts/events/event_handler.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from sys import gettrace
2+
import importlib.util
3+
from utils import log
4+
from pathlib import Path
5+
from events.model_system_event_listener import ModelSystemEventListener
6+
7+
8+
class EventHandler(ModelSystemEventListener):
9+
"""Event handler that calls all equivalent methods in all other ModelSystemEventListener classes."""
10+
def __init__(self):
11+
"""Initialize the EventHandler.
12+
13+
Args:
14+
model_system (ModelSystem): ModelSystem instance.
15+
"""
16+
super().__init__()
17+
self.listeners = []
18+
self._create_methods()
19+
20+
def register_listener(self, listener: ModelSystemEventListener):
21+
self.listeners.append(listener)
22+
23+
def load_listeners(self, listener_path: Path):
24+
"""Load all listeners from a given path.
25+
26+
Args:
27+
listener_path (str): The path to the listeners.
28+
"""
29+
for file_path in listener_path.glob("*.py"):
30+
if file_path.name != "__init__.py":
31+
try:
32+
module_name = file_path.stem
33+
spec = importlib.util.spec_from_file_location(module_name, file_path)
34+
module = importlib.util.module_from_spec(spec)
35+
spec.loader.exec_module(module)
36+
for attr_name in dir(module):
37+
attr = getattr(module, attr_name)
38+
if isinstance(attr, type) and issubclass(attr, ModelSystemEventListener) and attr is not ModelSystemEventListener:
39+
self.register_listener(attr())
40+
log.info(f"Loaded listener {attr.__name__} from {file_path}")
41+
except Exception as e:
42+
log.error(f"Error loading listener from {file_path}: {e}")
43+
44+
45+
def _create_methods(self):
46+
"""Create methods that call all equivalent methods in all other ModelSystemEventListener classes.
47+
Methods area automatically created for all methods that start with "on_" in all ModelSystemEventListener classes.
48+
"""
49+
for method_name in dir(ModelSystemEventListener):
50+
if method_name.startswith("on_") and callable(getattr(ModelSystemEventListener, method_name)):
51+
setattr(self, method_name, self._create_method(method_name))
52+
53+
def _create_method(self, method_name):
54+
"""Create a method that calls all equivalent methods in all other ModelSystemEventListener classes.
55+
56+
Args:
57+
method_name (str): name of the method to create.
58+
"""
59+
def method(*args, **kwargs):
60+
for listener in self.listeners:
61+
try:
62+
getattr(listener, method_name)(*args, **kwargs)
63+
except Exception as e:
64+
if gettrace() is not None:
65+
# Re-raise exception if debugger is attached
66+
raise e
67+
log.error(f"Error in {listener.__class__.__name__}.{method_name}: {e}")
68+
return method

Scripts/events/model_system_event_listener.py

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
from abc import ABC
22
from typing import TYPE_CHECKING, Dict, Union
3-
from sys import gettrace
4-
from utils import log
53
from pathlib import Path
6-
import importlib.util
74

85
if TYPE_CHECKING:
96
import pandas as pd
@@ -308,61 +305,3 @@ def on_daily_results_aggregated(self, assignment_model: 'EmmeAssignmentModel', d
308305
pass
309306

310307

311-
class EventHandler(ModelSystemEventListener):
312-
"""Event handler that calls all equivalent methods in all other ModelSystemEventListener classes."""
313-
def __init__(self):
314-
"""Initialize the EventHandler.
315-
316-
Args:
317-
model_system (ModelSystem): ModelSystem instance.
318-
"""
319-
super().__init__()
320-
self.listeners = []
321-
self._create_methods()
322-
323-
def register_listener(self, listener: ModelSystemEventListener):
324-
self.listeners.append(listener)
325-
326-
def load_listeners(self, listener_path: Path):
327-
"""Load all listeners from a given path.
328-
329-
Args:
330-
listener_path (str): The path to the listeners.
331-
"""
332-
for file_path in listener_path.glob("*.py"):
333-
if file_path.name != "__init__.py":
334-
module_name = file_path.stem
335-
spec = importlib.util.spec_from_file_location(module_name, file_path)
336-
module = importlib.util.module_from_spec(spec)
337-
spec.loader.exec_module(module)
338-
for attr_name in dir(module):
339-
attr = getattr(module, attr_name)
340-
if isinstance(attr, type) and issubclass(attr, ModelSystemEventListener) and attr is not ModelSystemEventListener:
341-
self.register_listener(attr())
342-
log.info(f"Loaded listener {attr.__name__} from {file_path}")
343-
344-
345-
def _create_methods(self):
346-
"""Create methods that call all equivalent methods in all other ModelSystemEventListener classes.
347-
Methods area automatically created for all methods that start with "on_" in all ModelSystemEventListener classes.
348-
"""
349-
for method_name in dir(ModelSystemEventListener):
350-
if method_name.startswith("on_") and callable(getattr(ModelSystemEventListener, method_name)):
351-
setattr(self, method_name, self._create_method(method_name))
352-
353-
def _create_method(self, method_name):
354-
"""Create a method that calls all equivalent methods in all other ModelSystemEventListener classes.
355-
356-
Args:
357-
method_name (str): name of the method to create.
358-
"""
359-
def method(*args, **kwargs):
360-
for listener in self.listeners:
361-
try:
362-
getattr(listener, method_name)(*args, **kwargs)
363-
except Exception as e:
364-
if gettrace() is not None:
365-
# Re-raise exception if debugger is attached
366-
raise e
367-
log.error(f"Error in {listener.__class__.__name__}.{method_name}: {e}")
368-
return method

Scripts/helmet.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
import utils.log as log
99
from assignment.emme_assignment import EmmeAssignmentModel
1010
from assignment.mock_assignment import MockAssignmentModel
11-
from events.model_system_event_listener import EventHandler
11+
from events.event_handler import EventHandler
1212
from modelsystem import ModelSystem, AgentModelSystem
1313
from datahandling.matrixdata import MatrixData
1414
from utils.validation import Validation

Scripts/modelsystem.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from datatypes.tour import Tour
2727
from transform.impedance_transformer import ImpedanceTransformer
2828
from models.linear import CarDensityModel
29-
from events.model_system_event_listener import EventHandler
29+
from events.event_handler import EventHandler
3030
import parameters.assignment as param
3131
import parameters.zone as zone_param
3232
import parameters.tour_generation as gen_param

Scripts/tests/emme_only/test_assignment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
import os
55
import logging
6-
from events.model_system_event_listener import EventHandler
6+
from events.event_handler import EventHandler
77
import utils.log as log
88
import numpy
99

Scripts/tests/integration/test_models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import numpy
44

55
from datahandling.zonedata import ZoneData
6-
from events.model_system_event_listener import EventHandler
6+
from events.event_handler import EventHandler
77
import utils.log as log
88
from modelsystem import ModelSystem, AgentModelSystem
99
from assignment.mock_assignment import MockAssignmentModel

Scripts/tests/unit/test_assignment.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import pandas
66
import os
77

8-
from events.model_system_event_listener import EventHandler
8+
from events.event_handler import EventHandler
99
from utils.validate_network import validate
1010
from assignment.emme_bindings.mock_project import MockProject
1111
from assignment.emme_assignment import EmmeAssignmentModel

Scripts/transform/impedance_transformer.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
if TYPE_CHECKING:
1010
from datatypes.purpose import Purpose
11-
from events.model_system_event_listener import EventHandler
11+
from events.event_handler import EventHandler
1212
import parameters.impedance_transformation as param
1313
from parameters.assignment import assignment_classes
1414
try:

0 commit comments

Comments
 (0)