From 99f1bffefb07f0f90ac1c6af48ca1686ec36b124 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Sun, 18 Jan 2026 00:52:54 -0600 Subject: [PATCH] Restructuring controller to broaden usability; changed events logic to support that --- .../code/command_system/command_system.py | 15 ++- .../code/controllers/commands_controller.py | 9 +- .../code/controllers/completion_controller.py | 12 +- .../code/controllers/controller_manager.py | 10 +- .../code/controllers/files_controller.py | 30 ++--- .../controllers/source_views_controller.py | 17 +-- .../code/controllers/tabs_controller.py | 22 ++-- src/core/widgets/code/source_file.py | 19 ++-- src/core/widgets/code/tabs_widget.py | 8 +- src/core/widgets/vte_widget.py | 1 - src/core/widgets/webkit/webkit_ui.py | 4 +- src/libs/code/__init__.py | 3 - src/libs/code/controllers/__init__.py | 3 - src/libs/code/dto/__init__.py | 3 - src/libs/code/event_factory.py | 103 ------------------ src/libs/controllers/__init__.py | 3 + .../{code => }/controllers/controller_base.py | 8 +- .../controllers/controller_context.py | 6 +- .../{code => }/controllers/emit_dispatcher.py | 6 +- src/libs/dto/__init__.py | 2 +- src/libs/dto/base_event.py | 14 +++ src/libs/{code => }/dto/code/__init__.py | 0 .../{code => }/dto/code/add_new_file_event.py | 0 .../dto/code/added_new_file_event.py | 0 src/libs/{code => }/dto/code/code_event.py | 3 +- .../{code => }/dto/code/cursor_moved_event.py | 0 .../dto/code/file_path_set_event.py | 0 .../{code => }/dto/code/focused_view_event.py | 0 .../dto/code/get_command_system_event.py | 0 .../{code => }/dto/code/get_file_event.py | 0 .../dto/code/get_swap_file_event.py | 0 .../dto/code/modified_changed_event.py | 0 .../{code => }/dto/code/pop_file_event.py | 0 .../{code => }/dto/code/popped_file_event.py | 0 .../{code => }/dto/code/remove_file_event.py | 0 .../{code => }/dto/code/removed_file_event.py | 0 .../dto/code/request_completion_event.py | 0 .../dto/code/set_active_file_event.py | 0 .../{code => }/dto/code/swap_file_event.py | 0 .../{code => }/dto/code/swapped_file_event.py | 0 .../{code => }/dto/code/text_changed_event.py | 0 .../dto/code/text_inserted_event.py | 0 src/libs/dto/event.py | 14 --- src/libs/dto/observable_event.py | 10 -- src/libs/event_factory.py | 63 +++++++++++ src/libs/settings/options/config.py | 2 +- 46 files changed, 169 insertions(+), 221 deletions(-) delete mode 100644 src/libs/code/__init__.py delete mode 100644 src/libs/code/controllers/__init__.py delete mode 100644 src/libs/code/dto/__init__.py delete mode 100644 src/libs/code/event_factory.py create mode 100644 src/libs/controllers/__init__.py rename src/libs/{code => }/controllers/controller_base.py (74%) rename src/libs/{code => }/controllers/controller_context.py (70%) rename src/libs/{code => }/controllers/emit_dispatcher.py (55%) create mode 100644 src/libs/dto/base_event.py rename src/libs/{code => }/dto/code/__init__.py (100%) rename src/libs/{code => }/dto/code/add_new_file_event.py (100%) rename src/libs/{code => }/dto/code/added_new_file_event.py (100%) rename src/libs/{code => }/dto/code/code_event.py (82%) rename src/libs/{code => }/dto/code/cursor_moved_event.py (100%) rename src/libs/{code => }/dto/code/file_path_set_event.py (100%) rename src/libs/{code => }/dto/code/focused_view_event.py (100%) rename src/libs/{code => }/dto/code/get_command_system_event.py (100%) rename src/libs/{code => }/dto/code/get_file_event.py (100%) rename src/libs/{code => }/dto/code/get_swap_file_event.py (100%) rename src/libs/{code => }/dto/code/modified_changed_event.py (100%) rename src/libs/{code => }/dto/code/pop_file_event.py (100%) rename src/libs/{code => }/dto/code/popped_file_event.py (100%) rename src/libs/{code => }/dto/code/remove_file_event.py (100%) rename src/libs/{code => }/dto/code/removed_file_event.py (100%) rename src/libs/{code => }/dto/code/request_completion_event.py (100%) rename src/libs/{code => }/dto/code/set_active_file_event.py (100%) rename src/libs/{code => }/dto/code/swap_file_event.py (100%) rename src/libs/{code => }/dto/code/swapped_file_event.py (100%) rename src/libs/{code => }/dto/code/text_changed_event.py (100%) rename src/libs/{code => }/dto/code/text_inserted_event.py (100%) delete mode 100644 src/libs/dto/event.py delete mode 100644 src/libs/dto/observable_event.py create mode 100644 src/libs/event_factory.py diff --git a/src/core/widgets/code/command_system/command_system.py b/src/core/widgets/code/command_system/command_system.py index 50d0b72..63986f2 100644 --- a/src/core/widgets/code/command_system/command_system.py +++ b/src/core/widgets/code/command_system/command_system.py @@ -3,7 +3,7 @@ # Lib imports # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types +from libs.event_factory import Event_Factory, Code_Event_Types from ..source_view import SourceView @@ -38,17 +38,18 @@ class CommandSystem: return method.execute(*args) - def emit(self, event: Event_Factory_Types.CodeEvent): + def emit(self, event: Code_Event_Types.CodeEvent): """ Monky patch 'emit' from command controller... """ ... - def emit_to(self, controller: str, event: Event_Factory_Types.CodeEvent): + def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent): """ Monky patch 'emit' from command controller... """ ... def get_file(self, view: SourceView): - event = Event_Factory.create_get_file( + event = Event_Factory.create_event( + "get_file", view = view, buffer = view.get_buffer() ) @@ -58,7 +59,8 @@ class CommandSystem: return event.response def get_swap_file(self, view: SourceView): - event = Event_Factory.create_get_swap_file( + event = Event_Factory.create_event( + "get_swap_file", view = view, buffer = view.get_buffer() ) @@ -75,7 +77,8 @@ class CommandSystem: return event.response def remove_file(self, view: SourceView): - event = Event_Factory.create_remove_file( + event = Event_Factory.create_event( + "removed_file", view = view, buffer = view.get_buffer() ) diff --git a/src/core/widgets/code/controllers/commands_controller.py b/src/core/widgets/code/controllers/commands_controller.py index 2e564a5..e1aec04 100644 --- a/src/core/widgets/code/controllers/commands_controller.py +++ b/src/core/widgets/code/controllers/commands_controller.py @@ -3,22 +3,21 @@ # Lib imports # Application imports -from libs.code.event_factory import Event_Factory_Types +from libs.controllers.controller_base import ControllerBase -from libs.code.controllers.controller_base import ControllerBase +from libs.event_factory import Code_Event_Types from ..command_system import CommandSystem - class CommandsController(ControllerBase, list): def __init__(self): super(CommandsController, self).__init__() - def _controller_message(self, event: Event_Factory_Types.CodeEvent): - if isinstance(event, Event_Factory_Types.GetCommandSystemEvent): + def _controller_message(self, event: Code_Event_Types.CodeEvent): + if isinstance(event, Code_Event_Types.GetCommandSystemEvent): event.response = self.get_command_system() def get_command_system(self): diff --git a/src/core/widgets/code/controllers/completion_controller.py b/src/core/widgets/code/controllers/completion_controller.py index fc69484..6330841 100644 --- a/src/core/widgets/code/controllers/completion_controller.py +++ b/src/core/widgets/code/controllers/completion_controller.py @@ -8,8 +8,8 @@ from gi.repository import GLib from gi.repository import GtkSource # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types -from libs.code.controllers.controller_base import ControllerBase +from libs.controllers.controller_base import ControllerBase +from libs.event_factory import Event_Factory, Code_Event_Types from ..completion_providers.example_completion_provider import ExampleCompletionProvider from ..completion_providers.lsp_completion_provider import LSPCompletionProvider @@ -25,17 +25,17 @@ class CompletionController(ControllerBase): self._lsp_provider: LSPCompletionProvider = LSPCompletionProvider() - def _controller_message(self, event: Event_Factory_Types.CodeEvent): - if isinstance(event, Event_Factory_Types.FocusedViewEvent): + def _controller_message(self, event: Code_Event_Types.CodeEvent): + if isinstance(event, Code_Event_Types.FocusedViewEvent): self._completor = event.view.get_completion() if not self._timeout_id: return GLib.source_remove(self._timeout_id) self._timeout_id = None - elif isinstance(event, Event_Factory_Types.RequestCompletionEvent): + elif isinstance(event, Code_Event_Types.RequestCompletionEvent): self.request_completion() - # elif isinstance(event, Event_Factory_Types.TextInsertedEvent): + # elif isinstance(event, Code_Event_Types.TextInsertedEvent): # self.request_completion() def _process_request_completion(self): diff --git a/src/core/widgets/code/controllers/controller_manager.py b/src/core/widgets/code/controllers/controller_manager.py index 76aa3af..3d446c7 100644 --- a/src/core/widgets/code/controllers/controller_manager.py +++ b/src/core/widgets/code/controllers/controller_manager.py @@ -5,10 +5,10 @@ # Application imports from libs.singleton import Singleton -from libs.code.event_factory import Event_Factory_Types +from libs.controllers.controller_base import ControllerBase +from libs.controllers.controller_context import ControllerContext -from libs.code.controllers.controller_base import ControllerBase -from libs.code.controllers.controller_context import ControllerContext +from libs.event_factory import Code_Event_Types @@ -43,9 +43,9 @@ class ControllerManager(Singleton, dict): def get_controllers_key_list(self) -> list[str]: return self.keys() - def message_to(self, name: str, event: Event_Factory_Types.CodeEvent): + def message_to(self, name: str, event: Code_Event_Types.CodeEvent): self[name]._controller_message(event) - def message_all(self, event: Event_Factory_Types.CodeEvent): + def message_all(self, event: Code_Event_Types.CodeEvent): for key in self.keys(): self[key]._controller_message(event) diff --git a/src/core/widgets/code/controllers/files_controller.py b/src/core/widgets/code/controllers/files_controller.py index 3d30747..c8daa6b 100644 --- a/src/core/widgets/code/controllers/files_controller.py +++ b/src/core/widgets/code/controllers/files_controller.py @@ -3,8 +3,8 @@ # Lib imports # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types -from libs.code.controllers.controller_base import ControllerBase +from libs.controllers.controller_base import ControllerBase +from libs.event_factory import Event_Factory, Code_Event_Types from ..source_file import SourceFile from ..source_buffer import SourceBuffer @@ -17,21 +17,21 @@ class FilesController(ControllerBase, list): super(FilesController, self).__init__() - def _controller_message(self, event: Event_Factory_Types.CodeEvent): - if isinstance(event, Event_Factory_Types.AddNewFileEvent): + def _controller_message(self, event: Code_Event_Types.CodeEvent): + if isinstance(event, Code_Event_Types.AddNewFileEvent): self.new_file(event) - elif isinstance(event, Event_Factory_Types.SwapFileEvent): + elif isinstance(event, Code_Event_Types.SwapFileEvent): self.swap_file(event) - elif isinstance(event, Event_Factory_Types.PopFileEvent): + elif isinstance(event, Code_Event_Types.PopFileEvent): self.pop_file(event) - elif isinstance(event, Event_Factory_Types.RemoveFileEvent): + elif isinstance(event, Code_Event_Types.RemoveFileEvent): self.remove_file(event) - elif isinstance(event, Event_Factory_Types.GetFileEvent): + elif isinstance(event, Code_Event_Types.GetFileEvent): self.get_file(event) - elif isinstance(event, Event_Factory_Types.GetSwapFileEvent): + elif isinstance(event, Code_Event_Types.GetSwapFileEvent): self.get_swap_file(event) - def get_file(self, event: Event_Factory_Types.GetFileEvent): + def get_file(self, event: Code_Event_Types.GetFileEvent): if not event.buffer: return for file in self: @@ -41,7 +41,7 @@ class FilesController(ControllerBase, list): return file - def get_swap_file(self, event: Event_Factory_Types.GetSwapFileEvent): + def get_swap_file(self, event: Code_Event_Types.GetSwapFileEvent): if not event.buffer: return for i, file in enumerate(self): @@ -55,7 +55,7 @@ class FilesController(ControllerBase, list): return swapped_file, next_file - def new_file(self, event: Event_Factory_Types.AddNewFileEvent): + def new_file(self, event: Code_Event_Types.AddNewFileEvent): file = SourceFile() file.emit = self.emit file.emit_to = self.emit_to @@ -73,7 +73,7 @@ class FilesController(ControllerBase, list): return file - def swap_file(self, event: Event_Factory_Types.GetSwapFileEvent): + def swap_file(self, event: Code_Event_Types.GetSwapFileEvent): if not event.buffer: return for i, file in enumerate(self): @@ -87,7 +87,7 @@ class FilesController(ControllerBase, list): return swapped_file, next_file - def pop_file(self, event: Event_Factory_Types.PopFileEvent): + def pop_file(self, event: Code_Event_Types.PopFileEvent): if not event.buffer: return for i, file in enumerate(self): @@ -109,7 +109,7 @@ class FilesController(ControllerBase, list): return popped_file, next_file - def remove_file(self, event: Event_Factory_Types.RemoveFileEvent): + def remove_file(self, event: Code_Event_Types.RemoveFileEvent): if not event.buffer: return for i, file in enumerate(self): diff --git a/src/core/widgets/code/controllers/source_views_controller.py b/src/core/widgets/code/controllers/source_views_controller.py index c129546..c2ff44d 100644 --- a/src/core/widgets/code/controllers/source_views_controller.py +++ b/src/core/widgets/code/controllers/source_views_controller.py @@ -3,8 +3,8 @@ # Lib imports # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types -from libs.code.controllers.controller_base import ControllerBase +from libs.controllers.controller_base import ControllerBase +from libs.event_factory import Event_Factory, Code_Event_Types from ..command_system import CommandSystem from ..key_mapper import KeyMapper @@ -39,10 +39,10 @@ class SourceViewsController(ControllerBase, list): self.append(source_view) return source_view - def _controller_message(self, event: Event_Factory_Types.CodeEvent): - if isinstance(event, Event_Factory_Types.RemovedFileEvent): + def _controller_message(self, event: Code_Event_Types.CodeEvent): + if isinstance(event, Code_Event_Types.RemovedFileEvent): self._remove_file(event) - elif isinstance(event, Event_Factory_Types.TextChangedEvent): + elif isinstance(event, Code_Event_Types.TextChangedEvent): self.active_view.command.exec("update_info_bar") def _map_signals(self, source_view: SourceView): @@ -60,7 +60,7 @@ class SourceViewsController(ControllerBase, list): view.command.exec("set_focus_border") view.command.exec("update_info_bar") - event = Event_Factory.create_focused_view(view = view) + event = Event_Factory.create_event("focused_view", view = view) self.emit(event) def _move_cursor(self, view, step, count, extend_selection): @@ -69,7 +69,8 @@ class SourceViewsController(ControllerBase, list): line = iter.get_line() char = iter.get_line_offset() - event = Event_Factory.create_cursor_moved( + event = Event_Factory.create_event( + "cursor_moved", view = view, buffer = buffer, line = line, @@ -108,7 +109,7 @@ class SourceViewsController(ControllerBase, list): return True - def _remove_file(self, event: Event_Factory_Types.RemovedFileEvent): + def _remove_file(self, event: Code_Event_Types.RemovedFileEvent): for view in self: if not event.file.buffer == view.get_buffer(): continue if not event.next_file: diff --git a/src/core/widgets/code/controllers/tabs_controller.py b/src/core/widgets/code/controllers/tabs_controller.py index 4d8f90f..5a789c7 100644 --- a/src/core/widgets/code/controllers/tabs_controller.py +++ b/src/core/widgets/code/controllers/tabs_controller.py @@ -3,8 +3,8 @@ # Lib imports # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types -from libs.code.controllers.controller_base import ControllerBase +from libs.controllers.controller_base import ControllerBase +from libs.event_factory import Event_Factory, Code_Event_Types from ..tabs_widget import TabsWidget from ..tab_widget import TabWidget @@ -21,28 +21,28 @@ class TabsController(ControllerBase): self.tabs_widget: TabsWidget = TabsWidget() - def _controller_message(self, event: Event_Factory_Types.CodeEvent): - if isinstance(event, Event_Factory_Types.FocusedViewEvent): + def _controller_message(self, event: Code_Event_Types.CodeEvent): + if isinstance(event, Code_Event_Types.FocusedViewEvent): self.active_view = event.view - elif isinstance(event, Event_Factory_Types.FilePathSetEvent): + elif isinstance(event, Code_Event_Types.FilePathSetEvent): self.update_tab_label(event) - elif isinstance(event, Event_Factory_Types.AddedNewFileEvent): + elif isinstance(event, Code_Event_Types.AddedNewFileEvent): self.add_tab(event) - elif isinstance(event, Event_Factory_Types.PoppedFileEvent): + elif isinstance(event, Code_Event_Types.PoppedFileEvent): ... - elif isinstance(event, Event_Factory_Types.RemovedFileEvent): + elif isinstance(event, Code_Event_Types.RemovedFileEvent): self.remove_tab(event) def get_tabs_widget(self): return self.tabs_widget - def update_tab_label(self, event: Event_Factory_Types.FilePathSetEvent): + def update_tab_label(self, event: Code_Event_Types.FilePathSetEvent): for tab in self.tabs_widget.get_children(): if not event.file == tab.file: continue tab.label.set_label(event.file.fname) break - def add_tab(self, event: Event_Factory_Types.AddedNewFileEvent): + def add_tab(self, event: Code_Event_Types.AddedNewFileEvent): def set_active_tab(tab, eve, file): event = Event_Factory.create_event( "set_active_file", @@ -72,7 +72,7 @@ class TabsController(ControllerBase): self.tabs_widget.add(tab) tab.show() - def remove_tab(self, event: Event_Factory_Types.RemovedFileEvent): + def remove_tab(self, event: Code_Event_Types.RemovedFileEvent): for tab in self.tabs_widget.get_children(): if not event.file == tab.file: continue diff --git a/src/core/widgets/code/source_file.py b/src/core/widgets/code/source_file.py index 26bcaa4..02817c1 100644 --- a/src/core/widgets/code/source_file.py +++ b/src/core/widgets/code/source_file.py @@ -12,7 +12,7 @@ from gi.repository import GtkSource from gi.repository import Gio # Application imports -from libs.code.event_factory import Event_Factory, Event_Factory_Types +from libs.event_factory import Event_Factory, Code_Event_Types from .source_buffer import SourceBuffer @@ -41,7 +41,7 @@ class SourceFile(GtkSource.File): ) def _changed(self, buffer: SourceBuffer): - event = Event_Factory.create_text_changed(buffer = buffer) + event = Event_Factory.create_event("text_changed", buffer = buffer) event.file = self self.emit(event) @@ -58,16 +58,17 @@ class SourceFile(GtkSource.File): def _mark_set(self, buffer: SourceBuffer, location: Gtk.TextIter, mark: Gtk.TextMark ): - # event = CodeEvent() - # event.etype = "mark_set" - # event.file = self - # event.buffer = buffer + # event = Event_Factory.create_event( + # "mark_set", + # file = self, buffer = buffer + # ) # self.emit(event) ... def _modified_changed(self, buffer: SourceBuffer): - event = Event_Factory.create_modified_changed( + event = Event_Factory.create_event( + "modified_changed", file = self, buffer = buffer ) @@ -121,8 +122,8 @@ class SourceFile(GtkSource.File): def close(self): del self.buffer - def emit(self, event: Event_Factory_Types.CodeEvent): + def emit(self, event: Code_Event_Types.CodeEvent): ... - def emit_to(self, controller: str, event: Event_Factory_Types.CodeEvent): + def emit_to(self, controller: str, event: Code_Event_Types.CodeEvent): ... diff --git a/src/core/widgets/code/tabs_widget.py b/src/core/widgets/code/tabs_widget.py index 6b0a016..88840ca 100644 --- a/src/core/widgets/code/tabs_widget.py +++ b/src/core/widgets/code/tabs_widget.py @@ -6,7 +6,7 @@ gi.require_version('Gtk', '3.0') from gi.repository import Gtk # Application imports -from libs.code.event_factory import Event_Factory_Types +from libs.event_factory import Code_Event_Types from .source_view import SourceView from .source_file import SourceFile @@ -37,7 +37,7 @@ class TabsWidget(Gtk.ButtonBox): def _load_widgets(self): ... - def add_tab(self, event: Event_Factory_Types.CodeEvent): + def add_tab(self, event: Code_Event_Types.CodeEvent): """Add a tab widget for the given file event.""" if not hasattr(self, 'tabs'): return @@ -61,7 +61,7 @@ class TabsWidget(Gtk.ButtonBox): self.tabs.add(tab) - def remove_tab(self, event: Event_Factory_Types.CodeEvent): + def remove_tab(self, event: Code_Event_Types.CodeEvent): """Remove a tab widget for the given file event.""" if not hasattr(self, 'tabs'): return @@ -75,7 +75,7 @@ class TabsWidget(Gtk.ButtonBox): return - def update_tab_label(self, event: Event_Factory_Types.CodeEvent): + def update_tab_label(self, event: Code_Event_Types.CodeEvent): """Update tab label for the given file event.""" if not hasattr(self, 'tabs'): return diff --git a/src/core/widgets/vte_widget.py b/src/core/widgets/vte_widget.py index 421962c..0e742ae 100644 --- a/src/core/widgets/vte_widget.py +++ b/src/core/widgets/vte_widget.py @@ -12,7 +12,6 @@ from gi.repository import GLib from gi.repository import Vte # Application imports -from libs.dto.event import Event diff --git a/src/core/widgets/webkit/webkit_ui.py b/src/core/widgets/webkit/webkit_ui.py index d92b65d..d6476c2 100644 --- a/src/core/widgets/webkit/webkit_ui.py +++ b/src/core/widgets/webkit/webkit_ui.py @@ -10,7 +10,7 @@ from gi.repository import WebKit2 # Application imports from libs.settings.other.webkit_ui_settings import WebkitUISettings -from libs.dto.event import Event +from libs.dto.base_event import BaseEvent class WebkitUI(WebKit2.WebView): @@ -55,7 +55,7 @@ class WebkitUI(WebKit2.WebView): message = js_value.to_string() try: - event = Event( **json.loads(message) ) + event = BaseEvent( **json.loads(message) ) event_system.emit("handle-bridge-event", (event,)) except Exception as e: logger.info(e) diff --git a/src/libs/code/__init__.py b/src/libs/code/__init__.py deleted file mode 100644 index f320a83..0000000 --- a/src/libs/code/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" - Libs Code Package -""" \ No newline at end of file diff --git a/src/libs/code/controllers/__init__.py b/src/libs/code/controllers/__init__.py deleted file mode 100644 index 1b2fbeb..0000000 --- a/src/libs/code/controllers/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" - Libs Code Controllers Package -""" \ No newline at end of file diff --git a/src/libs/code/dto/__init__.py b/src/libs/code/dto/__init__.py deleted file mode 100644 index 212583b..0000000 --- a/src/libs/code/dto/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" - Libs Code DTO(s) Package -""" diff --git a/src/libs/code/event_factory.py b/src/libs/code/event_factory.py deleted file mode 100644 index f023a39..0000000 --- a/src/libs/code/event_factory.py +++ /dev/null @@ -1,103 +0,0 @@ -# Python imports -import inspect -from typing import Dict, Type -import re - -# Lib imports - -# Application imports -from ..singleton import Singleton -from .dto.code import CodeEvent -from .dto import code - - - -class EventFactory(Singleton): - def __init__(self): - self._event_classes: Dict[str, Type[CodeEvent]] = {} - - self._auto_register_events() - - def register_event(self, event_type: str, event_class: Type[CodeEvent]): - self._event_classes[event_type] = event_class - - def create_event(self, event_type: str, **kwargs) -> CodeEvent: - if event_type not in self._event_classes: - raise ValueError(f"Unknown event type: {event_type}") - - event_class = self._event_classes[event_type] - event = event_class() - - for key, value in kwargs.items(): - if not hasattr(event, key): - raise ValueError(f"Event class {event_class.__name__} has no attribute '{key}'") - - setattr(event, key, value) - - return event - - def _auto_register_events(self): - for name, obj in code.__dict__.items(): - if not self._is_valid_event_class(obj): continue - - event_type = self._class_name_to_event_type(name) - self.register_event(event_type, obj) - - logger.debug(f"Auto-registered {len(self._event_classes)} event types") - - def _is_valid_event_class(self, obj) -> bool: - return ( - inspect.isclass(obj) and - issubclass(obj, CodeEvent) and - obj != CodeEvent - ) - - def _class_name_to_event_type(self, class_name: str) -> str: - base_name = class_name[:-5] if class_name.endswith('Event') else class_name - return re.sub(r'(? BaseEvent: + if event_type not in self._event_classes: + raise ValueError(f"Unknown event type: {event_type}") + + event_class = self._event_classes[event_type] + event = event_class() + + for key, value in kwargs.items(): + if not hasattr(event, key): + raise ValueError(f"Event class {event_class.__name__} has no attribute '{key}'") + + setattr(event, key, value) + + return event + + def _auto_register_events(self, events: dict): + for name, obj in events: + if not self._is_valid_event_class(obj): continue + + event_type = self._class_name_to_event_type(name) + self.register_event(event_type, obj) + + logger.debug(f"Auto-registered {len(self._event_classes)} event types") + + def _is_valid_event_class(self, obj) -> bool: + return ( + inspect.isclass(obj) and + issubclass(obj, BaseEvent) and + obj != BaseEvent + ) + + def _class_name_to_event_type(self, class_name: str) -> str: + base_name = class_name[:-5] if class_name.endswith('Event') else class_name + return re.sub(r'(?