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

@@ -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
from libs.singleton import Singleton
from ..event_factory import Event_Factory_Types
from ..dto.base_event import BaseEvent
from .emit_dispatcher import EmitDispatcher
from .controller_context import ControllerContext
@@ -24,15 +24,15 @@ class ControllerBase(Singleton, EmitDispatcher):
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'...")
def set_controller_context(self, controller_context: ControllerContext):
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)
def message_all(self, event: Event_Factory_Types.CodeEvent):
def message_all(self, event: BaseEvent):
return self.controller_context.message_all(event)

View File

@@ -3,7 +3,7 @@
# Lib 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__()
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...")
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...")

View File

@@ -3,7 +3,7 @@
# Lib 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__()
def emit(self, event: Event_Factory_Types.CodeEvent):
def emit(self, event: BaseEvent):
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)

View File

@@ -2,4 +2,4 @@
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
# Application imports
from ..base_event import BaseEvent
@dataclass
class CodeEvent:
class CodeEvent(BaseEvent):
ignore_focus: bool = False
view: 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
@dataclass
@dataclass(slots = True)
class Config:
base_of_home: str = ""
hide_hidden_files: str = "true"