Restructuring controller to broaden usability; changed events logic to support that

This commit is contained in:
2026-01-18 00:52:54 -06:00
parent f7d944f7a9
commit 99f1bffefb
46 changed files with 169 additions and 221 deletions

View File

@@ -3,7 +3,7 @@
# Lib imports # Lib imports
# Application 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 from ..source_view import SourceView
@@ -38,17 +38,18 @@ class CommandSystem:
return method.execute(*args) 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... """ """ 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... """ """ Monky patch 'emit' from command controller... """
... ...
def get_file(self, view: SourceView): def get_file(self, view: SourceView):
event = Event_Factory.create_get_file( event = Event_Factory.create_event(
"get_file",
view = view, view = view,
buffer = view.get_buffer() buffer = view.get_buffer()
) )
@@ -58,7 +59,8 @@ class CommandSystem:
return event.response return event.response
def get_swap_file(self, view: SourceView): def get_swap_file(self, view: SourceView):
event = Event_Factory.create_get_swap_file( event = Event_Factory.create_event(
"get_swap_file",
view = view, view = view,
buffer = view.get_buffer() buffer = view.get_buffer()
) )
@@ -75,7 +77,8 @@ class CommandSystem:
return event.response return event.response
def remove_file(self, view: SourceView): def remove_file(self, view: SourceView):
event = Event_Factory.create_remove_file( event = Event_Factory.create_event(
"removed_file",
view = view, view = view,
buffer = view.get_buffer() buffer = view.get_buffer()
) )

View File

@@ -3,22 +3,21 @@
# Lib imports # Lib imports
# Application 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 from ..command_system import CommandSystem
class CommandsController(ControllerBase, list): class CommandsController(ControllerBase, list):
def __init__(self): def __init__(self):
super(CommandsController, self).__init__() super(CommandsController, self).__init__()
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: Code_Event_Types.CodeEvent):
if isinstance(event, Event_Factory_Types.GetCommandSystemEvent): if isinstance(event, Code_Event_Types.GetCommandSystemEvent):
event.response = self.get_command_system() event.response = self.get_command_system()
def get_command_system(self): def get_command_system(self):

View File

@@ -8,8 +8,8 @@ from gi.repository import GLib
from gi.repository import GtkSource from gi.repository import GtkSource
# Application imports # Application imports
from libs.code.event_factory import Event_Factory, Event_Factory_Types from libs.controllers.controller_base import ControllerBase
from libs.code.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.example_completion_provider import ExampleCompletionProvider
from ..completion_providers.lsp_completion_provider import LSPCompletionProvider from ..completion_providers.lsp_completion_provider import LSPCompletionProvider
@@ -25,17 +25,17 @@ class CompletionController(ControllerBase):
self._lsp_provider: LSPCompletionProvider = LSPCompletionProvider() self._lsp_provider: LSPCompletionProvider = LSPCompletionProvider()
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: Code_Event_Types.CodeEvent):
if isinstance(event, Event_Factory_Types.FocusedViewEvent): if isinstance(event, Code_Event_Types.FocusedViewEvent):
self._completor = event.view.get_completion() self._completor = event.view.get_completion()
if not self._timeout_id: return if not self._timeout_id: return
GLib.source_remove(self._timeout_id) GLib.source_remove(self._timeout_id)
self._timeout_id = None self._timeout_id = None
elif isinstance(event, Event_Factory_Types.RequestCompletionEvent): elif isinstance(event, Code_Event_Types.RequestCompletionEvent):
self.request_completion() self.request_completion()
# elif isinstance(event, Event_Factory_Types.TextInsertedEvent): # elif isinstance(event, Code_Event_Types.TextInsertedEvent):
# self.request_completion() # self.request_completion()
def _process_request_completion(self): def _process_request_completion(self):

View File

@@ -5,10 +5,10 @@
# Application imports # Application imports
from libs.singleton import Singleton 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.event_factory import Code_Event_Types
from libs.code.controllers.controller_context import ControllerContext
@@ -43,9 +43,9 @@ class ControllerManager(Singleton, dict):
def get_controllers_key_list(self) -> list[str]: def get_controllers_key_list(self) -> list[str]:
return self.keys() 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) 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(): for key in self.keys():
self[key]._controller_message(event) self[key]._controller_message(event)

View File

@@ -3,8 +3,8 @@
# Lib imports # Lib imports
# Application imports # Application imports
from libs.code.event_factory import Event_Factory, Event_Factory_Types from libs.controllers.controller_base import ControllerBase
from libs.code.controllers.controller_base import ControllerBase from libs.event_factory import Event_Factory, Code_Event_Types
from ..source_file import SourceFile from ..source_file import SourceFile
from ..source_buffer import SourceBuffer from ..source_buffer import SourceBuffer
@@ -17,21 +17,21 @@ class FilesController(ControllerBase, list):
super(FilesController, self).__init__() super(FilesController, self).__init__()
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: Code_Event_Types.CodeEvent):
if isinstance(event, Event_Factory_Types.AddNewFileEvent): if isinstance(event, Code_Event_Types.AddNewFileEvent):
self.new_file(event) self.new_file(event)
elif isinstance(event, Event_Factory_Types.SwapFileEvent): elif isinstance(event, Code_Event_Types.SwapFileEvent):
self.swap_file(event) self.swap_file(event)
elif isinstance(event, Event_Factory_Types.PopFileEvent): elif isinstance(event, Code_Event_Types.PopFileEvent):
self.pop_file(event) self.pop_file(event)
elif isinstance(event, Event_Factory_Types.RemoveFileEvent): elif isinstance(event, Code_Event_Types.RemoveFileEvent):
self.remove_file(event) self.remove_file(event)
elif isinstance(event, Event_Factory_Types.GetFileEvent): elif isinstance(event, Code_Event_Types.GetFileEvent):
self.get_file(event) self.get_file(event)
elif isinstance(event, Event_Factory_Types.GetSwapFileEvent): elif isinstance(event, Code_Event_Types.GetSwapFileEvent):
self.get_swap_file(event) 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 if not event.buffer: return
for file in self: for file in self:
@@ -41,7 +41,7 @@ class FilesController(ControllerBase, list):
return file 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 if not event.buffer: return
for i, file in enumerate(self): for i, file in enumerate(self):
@@ -55,7 +55,7 @@ class FilesController(ControllerBase, list):
return swapped_file, next_file 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 = SourceFile()
file.emit = self.emit file.emit = self.emit
file.emit_to = self.emit_to file.emit_to = self.emit_to
@@ -73,7 +73,7 @@ class FilesController(ControllerBase, list):
return file 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 if not event.buffer: return
for i, file in enumerate(self): for i, file in enumerate(self):
@@ -87,7 +87,7 @@ class FilesController(ControllerBase, list):
return swapped_file, next_file 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 if not event.buffer: return
for i, file in enumerate(self): for i, file in enumerate(self):
@@ -109,7 +109,7 @@ class FilesController(ControllerBase, list):
return popped_file, next_file 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 if not event.buffer: return
for i, file in enumerate(self): for i, file in enumerate(self):

View File

@@ -3,8 +3,8 @@
# Lib imports # Lib imports
# Application imports # Application imports
from libs.code.event_factory import Event_Factory, Event_Factory_Types from libs.controllers.controller_base import ControllerBase
from libs.code.controllers.controller_base import ControllerBase from libs.event_factory import Event_Factory, Code_Event_Types
from ..command_system import CommandSystem from ..command_system import CommandSystem
from ..key_mapper import KeyMapper from ..key_mapper import KeyMapper
@@ -39,10 +39,10 @@ class SourceViewsController(ControllerBase, list):
self.append(source_view) self.append(source_view)
return source_view return source_view
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: Code_Event_Types.CodeEvent):
if isinstance(event, Event_Factory_Types.RemovedFileEvent): if isinstance(event, Code_Event_Types.RemovedFileEvent):
self._remove_file(event) 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") self.active_view.command.exec("update_info_bar")
def _map_signals(self, source_view: SourceView): def _map_signals(self, source_view: SourceView):
@@ -60,7 +60,7 @@ class SourceViewsController(ControllerBase, list):
view.command.exec("set_focus_border") view.command.exec("set_focus_border")
view.command.exec("update_info_bar") 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) self.emit(event)
def _move_cursor(self, view, step, count, extend_selection): def _move_cursor(self, view, step, count, extend_selection):
@@ -69,7 +69,8 @@ class SourceViewsController(ControllerBase, list):
line = iter.get_line() line = iter.get_line()
char = iter.get_line_offset() char = iter.get_line_offset()
event = Event_Factory.create_cursor_moved( event = Event_Factory.create_event(
"cursor_moved",
view = view, view = view,
buffer = buffer, buffer = buffer,
line = line, line = line,
@@ -108,7 +109,7 @@ class SourceViewsController(ControllerBase, list):
return True return True
def _remove_file(self, event: Event_Factory_Types.RemovedFileEvent): def _remove_file(self, event: Code_Event_Types.RemovedFileEvent):
for view in self: for view in self:
if not event.file.buffer == view.get_buffer(): continue if not event.file.buffer == view.get_buffer(): continue
if not event.next_file: if not event.next_file:

View File

@@ -3,8 +3,8 @@
# Lib imports # Lib imports
# Application imports # Application imports
from libs.code.event_factory import Event_Factory, Event_Factory_Types from libs.controllers.controller_base import ControllerBase
from libs.code.controllers.controller_base import ControllerBase from libs.event_factory import Event_Factory, Code_Event_Types
from ..tabs_widget import TabsWidget from ..tabs_widget import TabsWidget
from ..tab_widget import TabWidget from ..tab_widget import TabWidget
@@ -21,28 +21,28 @@ class TabsController(ControllerBase):
self.tabs_widget: TabsWidget = TabsWidget() self.tabs_widget: TabsWidget = TabsWidget()
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: Code_Event_Types.CodeEvent):
if isinstance(event, Event_Factory_Types.FocusedViewEvent): if isinstance(event, Code_Event_Types.FocusedViewEvent):
self.active_view = event.view self.active_view = event.view
elif isinstance(event, Event_Factory_Types.FilePathSetEvent): elif isinstance(event, Code_Event_Types.FilePathSetEvent):
self.update_tab_label(event) self.update_tab_label(event)
elif isinstance(event, Event_Factory_Types.AddedNewFileEvent): elif isinstance(event, Code_Event_Types.AddedNewFileEvent):
self.add_tab(event) 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) self.remove_tab(event)
def get_tabs_widget(self): def get_tabs_widget(self):
return self.tabs_widget 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(): for tab in self.tabs_widget.get_children():
if not event.file == tab.file: continue if not event.file == tab.file: continue
tab.label.set_label(event.file.fname) tab.label.set_label(event.file.fname)
break 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): def set_active_tab(tab, eve, file):
event = Event_Factory.create_event( event = Event_Factory.create_event(
"set_active_file", "set_active_file",
@@ -72,7 +72,7 @@ class TabsController(ControllerBase):
self.tabs_widget.add(tab) self.tabs_widget.add(tab)
tab.show() 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(): for tab in self.tabs_widget.get_children():
if not event.file == tab.file: continue if not event.file == tab.file: continue

View File

@@ -12,7 +12,7 @@ from gi.repository import GtkSource
from gi.repository import Gio from gi.repository import Gio
# Application 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_buffer import SourceBuffer from .source_buffer import SourceBuffer
@@ -41,7 +41,7 @@ class SourceFile(GtkSource.File):
) )
def _changed(self, buffer: SourceBuffer): 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 event.file = self
self.emit(event) self.emit(event)
@@ -58,16 +58,17 @@ class SourceFile(GtkSource.File):
def _mark_set(self, buffer: SourceBuffer, location: Gtk.TextIter, def _mark_set(self, buffer: SourceBuffer, location: Gtk.TextIter,
mark: Gtk.TextMark mark: Gtk.TextMark
): ):
# event = CodeEvent() # event = Event_Factory.create_event(
# event.etype = "mark_set" # "mark_set",
# event.file = self # file = self, buffer = buffer
# event.buffer = buffer # )
# self.emit(event) # self.emit(event)
... ...
def _modified_changed(self, buffer: SourceBuffer): def _modified_changed(self, buffer: SourceBuffer):
event = Event_Factory.create_modified_changed( event = Event_Factory.create_event(
"modified_changed",
file = self, buffer = buffer file = self, buffer = buffer
) )
@@ -121,8 +122,8 @@ class SourceFile(GtkSource.File):
def close(self): def close(self):
del self.buffer 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):
... ...

View File

@@ -6,7 +6,7 @@ gi.require_version('Gtk', '3.0')
from gi.repository import Gtk from gi.repository import Gtk
# Application imports # 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_view import SourceView
from .source_file import SourceFile from .source_file import SourceFile
@@ -37,7 +37,7 @@ class TabsWidget(Gtk.ButtonBox):
def _load_widgets(self): 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.""" """Add a tab widget for the given file event."""
if not hasattr(self, 'tabs'): if not hasattr(self, 'tabs'):
return return
@@ -61,7 +61,7 @@ class TabsWidget(Gtk.ButtonBox):
self.tabs.add(tab) 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.""" """Remove a tab widget for the given file event."""
if not hasattr(self, 'tabs'): if not hasattr(self, 'tabs'):
return return
@@ -75,7 +75,7 @@ class TabsWidget(Gtk.ButtonBox):
return 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.""" """Update tab label for the given file event."""
if not hasattr(self, 'tabs'): if not hasattr(self, 'tabs'):
return return

View File

@@ -12,7 +12,6 @@ from gi.repository import GLib
from gi.repository import Vte from gi.repository import Vte
# Application imports # Application imports
from libs.dto.event import Event

View File

@@ -10,7 +10,7 @@ from gi.repository import WebKit2
# Application imports # Application imports
from libs.settings.other.webkit_ui_settings import WebkitUISettings 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): class WebkitUI(WebKit2.WebView):
@@ -55,7 +55,7 @@ class WebkitUI(WebKit2.WebView):
message = js_value.to_string() message = js_value.to_string()
try: try:
event = Event( **json.loads(message) ) event = BaseEvent( **json.loads(message) )
event_system.emit("handle-bridge-event", (event,)) event_system.emit("handle-bridge-event", (event,))
except Exception as e: except Exception as e:
logger.info(e) logger.info(e)

View File

@@ -1,3 +0,0 @@
"""
Libs Code Package
"""

View File

@@ -1,3 +0,0 @@
"""
Libs Code Controllers Package
"""

View File

@@ -1,3 +0,0 @@
"""
Libs Code DTO(s) Package
"""

View File

@@ -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'(?<!^)(?=[A-Z])', '_', base_name).lower()
def create_cursor_moved(self, **kwargs):
return self.create_event("cursor_moved", **kwargs)
def create_text_changed(self, **kwargs):
return self.create_event("text_changed", **kwargs)
def create_focused_view(self, **kwargs):
return self.create_event("focused_view", **kwargs)
def create_modified_changed(self, **kwargs):
return self.create_event("modified_changed", **kwargs)
def create_get_command_system(self, **kwargs):
return self.create_event("get_command_system", **kwargs)
def create_file_path_set(self, **kwargs):
return self.create_event("file_path_set", **kwargs)
def create_text_inserted(self, **kwargs):
return self.create_event("text_inserted", **kwargs)
def create_set_active_file(self, **kwargs):
return self.create_event("set_active_file", **kwargs)
def create_added_new_file(self, **kwargs):
return self.create_event("added_new_file", **kwargs)
def create_popped_file(self, **kwargs):
return self.create_event("popped_file", **kwargs)
def create_get_file(self, **kwargs):
return self.create_event("get_file", **kwargs)
def create_get_swap_file(self, **kwargs):
return self.create_event("get_swap_file", **kwargs)
def create_remove_file(self, **kwargs):
return self.create_event("remove_file", **kwargs)
def create_removed_file(self, **kwargs):
return self.create_event("removed_file", **kwargs)
Event_Factory = EventFactory()
Event_Factory_Types = code

View File

@@ -0,0 +1,3 @@
"""
Libs Controllers Package
"""

View File

@@ -5,7 +5,7 @@
# Application imports # Application imports
from libs.singleton import Singleton from libs.singleton import Singleton
from ..event_factory import Event_Factory_Types from ..dto.base_event import BaseEvent
from .emit_dispatcher import EmitDispatcher from .emit_dispatcher import EmitDispatcher
from .controller_context import ControllerContext from .controller_context import ControllerContext
@@ -24,15 +24,15 @@ class ControllerBase(Singleton, EmitDispatcher):
self.controller_context: ControllerContext = None self.controller_context: ControllerContext = None
def _controller_message(self, event: Event_Factory_Types.CodeEvent): def _controller_message(self, event: BaseEvent):
raise ControllerBaseException("Controller Base must override '_controller_message'...") raise ControllerBaseException("Controller Base must override '_controller_message'...")
def set_controller_context(self, controller_context: ControllerContext): def set_controller_context(self, controller_context: ControllerContext):
self.controller_context = controller_context self.controller_context = controller_context
def message_to(self, name: str, event: Event_Factory_Types.CodeEvent): def message_to(self, name: str, event: BaseEvent):
return self.controller_context.message_to(name, event) return self.controller_context.message_to(name, event)
def message_all(self, event: Event_Factory_Types.CodeEvent): def message_all(self, event: BaseEvent):
return self.controller_context.message_all(event) return self.controller_context.message_all(event)

View File

@@ -3,7 +3,7 @@
# Lib imports # Lib imports
# Application imports # Application imports
from ..event_factory import Event_Factory_Types from ..dto.base_event import BaseEvent
@@ -17,8 +17,8 @@ class ControllerContext:
super(ControllerContext, self).__init__() super(ControllerContext, self).__init__()
def message_to(self, name: str, event: Event_Factory_Types.CodeEvent): def message_to(self, name: str, event: BaseEvent):
raise ControllerContextException("Controller Context 'message_to' must be overriden by Controller Manager...") raise ControllerContextException("Controller Context 'message_to' must be overriden by Controller Manager...")
def message_all(self, event: Event_Factory_Types.CodeEvent): def message_all(self, event: BaseEvent):
raise ControllerContextException("Controller Context 'message_all' must be overriden by Controller Manager...") raise ControllerContextException("Controller Context 'message_all' must be overriden by Controller Manager...")

View File

@@ -3,7 +3,7 @@
# Lib imports # Lib imports
# Application imports # Application imports
from ..event_factory import Event_Factory_Types from ..dto.base_event import BaseEvent
@@ -12,8 +12,8 @@ class EmitDispatcher:
super(EmitDispatcher, self).__init__() super(EmitDispatcher, self).__init__()
def emit(self, event: Event_Factory_Types.CodeEvent): def emit(self, event: BaseEvent):
self.message_all(event) self.message_all(event)
def emit_to(self, controller: str, event: Event_Factory_Types.CodeEvent): def emit_to(self, controller: str, event: BaseEvent):
self.message_to(controller, event) self.message_to(controller, event)

View File

@@ -2,4 +2,4 @@
Libs DTO(s) Package Libs DTO(s) Package
""" """
from .event import Event from .base_event import BaseEvent

View File

@@ -0,0 +1,14 @@
# Python imports
from dataclasses import dataclass, field
# Lib imports
# Application imports
@dataclass(slots = True)
class BaseEvent:
topic: str = None
content: any = None
raw_content: any = None

View File

@@ -4,11 +4,12 @@ from dataclasses import dataclass, field
# Lib imports # Lib imports
# Application imports # Application imports
from ..base_event import BaseEvent
@dataclass @dataclass
class CodeEvent: class CodeEvent(BaseEvent):
ignore_focus: bool = False ignore_focus: bool = False
view: any = None view: any = None
file: any = None file: any = None

View File

@@ -1,14 +0,0 @@
# Python imports
from dataclasses import dataclass, field
# Lib imports
# Application imports
@dataclass
class Event:
topic: str
content: str
raw_content: str

View File

@@ -1,10 +0,0 @@
# Python imports
# Lib imports
# Application imports
class ObservableEvent:
...

63
src/libs/event_factory.py Normal file
View File

@@ -0,0 +1,63 @@
# Python imports
import inspect
from typing import Dict, Type
import re
# Lib imports
# Application imports
from .singleton import Singleton
from .dto.base_event import BaseEvent
from .dto import code
class EventFactory(Singleton):
def __init__(self):
self._event_classes: Dict[str, Type[BaseEvent]] = {}
self._auto_register_events( code.__dict__.items() )
def register_event(self, event_type: str, event_class: Type[BaseEvent]):
self._event_classes[event_type] = event_class
def create_event(self, event_type: str, **kwargs) -> 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'(?<!^)(?=[A-Z])', '_', base_name).lower()
Event_Factory = EventFactory()
Code_Event_Types = code

View File

@@ -6,7 +6,7 @@ from dataclasses import dataclass, field
# Application imports # Application imports
@dataclass @dataclass(slots = True)
class Config: class Config:
base_of_home: str = "" base_of_home: str = ""
hide_hidden_files: str = "true" hide_hidden_files: str = "true"