11from abc import ABC
22from typing import TYPE_CHECKING , Dict , Union
3- from sys import gettrace
4- from utils import log
53from pathlib import Path
6- import importlib .util
74
85if 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
0 commit comments