Update Architecture.py
This commit is contained in:
@@ -5,28 +5,38 @@ from abc import ABC, abstractmethod
|
|||||||
class ISignal(ABC):
|
class ISignal(ABC):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IModel(ABC):
|
class IModel(ABC):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class IDataModel(ABC, IModel):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def Save(self) -> str:
|
def Save(self) -> str:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def Load(self, data:str) -> None:
|
def Load(self, data:str) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IConvertable[T](ABC):
|
class IConvertable[T](ABC):
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def ConvertTo(self) -> T:
|
def ConvertTo(self) -> T:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class IConvertModel[T](IConvertable[T], IModel):
|
class IConvertModel[T](IConvertable[T], IModel):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SingletonModel[T](IModel):
|
class SingletonModel[T](IModel):
|
||||||
_InjectInstances:Dict[type,Any] = {}
|
_InjectInstances:Dict[type,Any] = {}
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def GetInstance(t:Typen[T]) -> T:
|
def GetInstance(t:Typen[T]) -> T:
|
||||||
return SingletonModel._InjectInstances[t]
|
return SingletonModel._InjectInstances[t]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def SetInstance(t:Typen[T], obj:T) -> None:
|
def SetInstance(t:Typen[T], obj:T) -> None:
|
||||||
SingletonModel._InjectInstances[t] = obj
|
SingletonModel._InjectInstances[t] = obj
|
||||||
@@ -34,9 +44,6 @@ class SingletonModel[T](IModel):
|
|||||||
def __init__(self, t:Typen[T]) -> None:
|
def __init__(self, t:Typen[T]) -> None:
|
||||||
self.typen: type = t
|
self.typen: type = t
|
||||||
|
|
||||||
@override
|
|
||||||
def Save(self) -> str:
|
|
||||||
return SingletonModel.GetInstance(self.typen).Save()
|
|
||||||
|
|
||||||
class DependenceModel(IConvertModel[bool]):
|
class DependenceModel(IConvertModel[bool]):
|
||||||
def __init__(self, queries:Sequence[IConvertModel[bool]]) -> None:
|
def __init__(self, queries:Sequence[IConvertModel[bool]]) -> None:
|
||||||
@@ -52,14 +59,10 @@ class DependenceModel(IConvertModel[bool]):
|
|||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return iter(self.queries)
|
return iter(self.queries)
|
||||||
|
|
||||||
def Load(self, data:str):
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def Save(self) -> str:
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
SignalListener = Callable[[ISignal], None]
|
SignalListener = Callable[[ISignal], None]
|
||||||
|
|
||||||
|
|
||||||
class Architecture:
|
class Architecture:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def FormatType(t:type) -> str:
|
def FormatType(t:type) -> str:
|
||||||
@@ -78,14 +81,11 @@ class Architecture:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def InternalReset(cls) -> None:
|
def InternalReset(cls) -> None:
|
||||||
# Register System
|
# Register System
|
||||||
cls._RegisterHistory.clear()
|
cls._RegisteredObjects.clear()
|
||||||
cls._UncompleteTargets.clear()
|
cls._RegisteringRuntime.clear()
|
||||||
cls._Completer.clear()
|
# Signal Listener
|
||||||
cls._Dependences.clear()
|
|
||||||
cls._Childs.clear()
|
|
||||||
# Event Listener
|
|
||||||
cls._SignalListener.clear()
|
cls._SignalListener.clear()
|
||||||
# Linear Chain for Dependence
|
# Timeline/Chain
|
||||||
cls._TimelineQueues.clear()
|
cls._TimelineQueues.clear()
|
||||||
cls._TimelineContentID = 0
|
cls._TimelineContentID = 0
|
||||||
|
|
||||||
@@ -97,136 +97,79 @@ class Architecture:
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
def ConvertTo(self) -> bool:
|
def ConvertTo(self) -> bool:
|
||||||
return self._queryType in Architecture._Childs
|
return self._queryType in Architecture._RegisteredObjects
|
||||||
|
|
||||||
def Load(self, data:str) -> None:
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
def Save(self) -> str:
|
|
||||||
raise NotImplementedError()
|
|
||||||
|
|
||||||
_RegisterHistory: Set[type] = set()
|
|
||||||
_UncompleteTargets: Dict[type,Any] = {}
|
|
||||||
_Completer: Dict[type,Action] = {}
|
|
||||||
_Dependences: Dict[type,DependenceModel] = {}
|
|
||||||
_Childs: Dict[type,Any] = {}
|
|
||||||
|
|
||||||
class Registering(IConvertModel[bool]):
|
class Registering(IConvertModel[bool]):
|
||||||
def __init__(self,registerSlot:type) -> None:
|
def __init__(self, registerSlot:type, target:Any, dependences:DependenceModel, action:Action) -> None:
|
||||||
self._registerSlot:type = registerSlot
|
self.registerSlot = registerSlot
|
||||||
|
self.target = target
|
||||||
|
self.dependences = dependences
|
||||||
|
self.action = action
|
||||||
|
|
||||||
@override
|
@override
|
||||||
def ConvertTo(self) -> bool:
|
def ConvertTo(self) -> bool:
|
||||||
return self._registerSlot in Architecture._Childs
|
return self.dependences.ConvertTo()
|
||||||
|
|
||||||
@override
|
_RegisteringRuntime: Dict[type, Registering] = {}
|
||||||
def Load(self,data:str) -> None:
|
_RegisteredObjects: Dict[type, Any] = {}
|
||||||
raise InvalidOperationError(f"Cannot use {self.__class__.__name__} to load type")
|
|
||||||
|
|
||||||
@override
|
|
||||||
def Save(self) -> str:
|
|
||||||
return f"{Architecture.FormatType(self._registerSlot)}[{self.ConvertTo()}]"
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _InternalRegisteringComplete(cls) -> tuple[bool,Set[type]]:
|
def _InternalRegisteringComplete(cls) -> None:
|
||||||
resultSet: Set[type] = set()
|
CompletedSet: Set[Architecture.Registering] = set()
|
||||||
stats: bool = False
|
for dependence in cls._RegisteringRuntime.keys():
|
||||||
for dependence in cls._Dependences.keys():
|
if cls._RegisteringRuntime[dependence].dependences.ConvertTo():
|
||||||
if cls._Dependences[dependence].ConvertTo():
|
CompletedSet.add(cls._RegisteringRuntime[dependence])
|
||||||
resultSet.add(dependence)
|
for complete in CompletedSet:
|
||||||
stats = True
|
del cls._RegisteringRuntime[complete.registerSlot]
|
||||||
return stats,resultSet
|
complete.action()
|
||||||
|
cls._RegisteredObjects[complete.registerSlot] = complete.target
|
||||||
|
if len(CompletedSet) > 0:
|
||||||
|
cls._InternalRegisteringComplete()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _InternalRegisteringUpdate(cls, internalUpdateBuffer:Set[type]):
|
def Register(cls, slot:type, target:Any, action:Action, *dependences:type) -> DependenceModel:
|
||||||
for complete in internalUpdateBuffer:
|
if slot in cls._RegisteringRuntime:
|
||||||
cls._Dependences.pop(complete, None)
|
|
||||||
for complete in internalUpdateBuffer:
|
|
||||||
cls._Completer[complete]()
|
|
||||||
cls._Completer.pop(complete, None)
|
|
||||||
for complete in internalUpdateBuffer:
|
|
||||||
cls._Childs[complete] = cls._UncompleteTargets[complete]
|
|
||||||
cls._UncompleteTargets.pop(complete, None)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def Register(cls, slot:type, target:Any, completer:Action, *dependences:type) -> 'Architecture.Registering':
|
|
||||||
if slot in cls._RegisterHistory:
|
|
||||||
raise InvalidOperationError("Illegal duplicate registrations")
|
raise InvalidOperationError("Illegal duplicate registrations")
|
||||||
|
cls._RegisteringRuntime[slot] = Architecture.Registering(slot, target, DependenceModel(Architecture.TypeQuery(dependence) for dependence in dependences), action)
|
||||||
cls._RegisterHistory.add(slot)
|
cls._InternalRegisteringComplete()
|
||||||
cls._Completer[slot] = completer
|
return cls._RegisteringRuntime[slot].dependences
|
||||||
cls._UncompleteTargets[slot] = target
|
|
||||||
|
|
||||||
# 过滤掉自身依赖
|
|
||||||
filtered_deps = [dep for dep in dependences if dep != slot]
|
|
||||||
type_queries = [cls.TypeQuery(dep) for dep in filtered_deps]
|
|
||||||
cls._Dependences[slot] = DependenceModel(type_queries)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
has_complete, buffer = cls._InternalRegisteringComplete()
|
|
||||||
if not has_complete:
|
|
||||||
break
|
|
||||||
cls._InternalRegisteringUpdate(buffer)
|
|
||||||
|
|
||||||
return cls.Registering(slot)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def RegisterGeneric[T](cls, target:T, completer:Action, *dependences:type) -> 'Architecture.Registering':
|
|
||||||
return cls.Register(type(target), target, completer, *dependences)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def Contains(cls, type_:type) -> bool:
|
def Contains(cls, type_:type) -> bool:
|
||||||
return type_ in cls._Childs
|
return type_ in cls._RegisteredObjects
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def ContainsGeneric[T](cls) -> bool:
|
|
||||||
return cls.Contains(type(T))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def InternalGet(cls, type_:type) -> Any:
|
|
||||||
return cls._Childs[type_]
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def Get(cls, type_:type) -> Any:
|
def Get(cls, type_:type) -> Any:
|
||||||
return cls.InternalGet(type_)
|
return cls._RegisteredObjects[type_]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def GetGeneric[T](cls) -> T:
|
def Unregister(cls, slot:type) -> bool:
|
||||||
return cls.Get(type(T))
|
if slot in cls._RegisteredObjects:
|
||||||
|
del cls._RegisteredObjects[slot]
|
||||||
|
return True
|
||||||
|
if slot in cls._RegisteringRuntime:
|
||||||
|
del cls._RegisteringRuntime[slot]
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Signal & Update
|
#region Signal & Update
|
||||||
|
|
||||||
_SignalListener: Dict[type, Set[SignalListener]] = {}
|
_SignalListener: Dict[type, List[SignalListener]] = {}
|
||||||
|
|
||||||
class Listening:
|
|
||||||
def __init__(self, action:SignalListener, type_:type):
|
|
||||||
self._action = action
|
|
||||||
self._type = type_
|
|
||||||
|
|
||||||
def StopListening(self):
|
|
||||||
if self._type in Architecture._SignalListener:
|
|
||||||
Architecture._SignalListener[self._type].discard(self._action)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def AddListenerGeneric[Signal](cls, slot:type, listener:SignalListener) -> 'Architecture.Listening':
|
def AddListener(cls, slot:type, listener:SignalListener) -> None:
|
||||||
if slot not in cls._SignalListener:
|
if slot not in cls._SignalListener:
|
||||||
cls._SignalListener[slot] = set()
|
cls._SignalListener[slot] = []
|
||||||
|
|
||||||
def action(signal:ISignal):
|
cls._SignalListener[slot].append(listener)
|
||||||
if isinstance(signal, slot):
|
|
||||||
listener(signal)
|
|
||||||
|
|
||||||
result = cls.Listening(action, slot)
|
|
||||||
cls._SignalListener[slot].add(action)
|
|
||||||
return result
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def SendMessage(cls, slot:type, signal:ISignal):
|
def SendMessage(cls, slot:type, signal:ISignal):
|
||||||
if slot in cls._SignalListener:
|
if slot in cls._SignalListener:
|
||||||
for action in cls._SignalListener[slot]:
|
for listener in cls._SignalListener[slot]:
|
||||||
action(signal)
|
listener(signal)
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -285,6 +228,3 @@ class Architecture:
|
|||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user