1
0
mirror of https://github.com/MarkParker5/STARK.git synced 2025-07-12 22:50:22 +02:00

update acobjects

create Notifications and DispatchQueue
This commit is contained in:
MarkParker5
2021-11-28 00:06:17 +02:00
parent 5021f887f4
commit 89b60734ed
33 changed files with 264 additions and 57 deletions

View File

@ -1,4 +1,4 @@
from .ACObject import ACObject, Pattern from .ACObject import ACObject, Pattern, classproperty
class ACNumber(ACObject): class ACNumber(ACObject):
value: float value: float
@ -9,14 +9,14 @@ class ACNumber(ACObject):
@classmethod @classmethod
def parse(cls, fromString: str): def parse(cls, fromString: str):
string = string.replace(' ', '').replace(',', '.').replace('%', '')) string = string.replace(' ', '').replace(',', '.').replace('%', '')
value = float(string) value = float(string)
if '%' in stringValue: if '%' in stringValue:
value /= 100 value /= 100
isPercentage = True isPercentage = True
acNumber = ACNumber(value: value) acNumber = ACNumber(value = value)
acNumber.isPercentage = isPercentage acNumber.isPercentage = isPercentage
acNumber.stringValue = stringValue acNumber.stringValue = stringValue

View File

@ -1,8 +1,10 @@
from __future__ import annotations
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Any from typing import Any
from copy import copy from copy import copy
from .. import Pattern from ..Pattern import Pattern
class classproperty(property): class classproperty(property):
def __get__(self, cls, owner): def __get__(self, cls, owner):
@ -24,65 +26,65 @@ class ACObject(ABC):
return cls() return cls()
def __repr__(self): def __repr__(self):
return str(value) return str(self.value)
@classproperty @classproperty
def pattern() -> Pattern: def pattern() -> Pattern:
return Pattern('*') return Pattern('*')
def __lt__(self, other: ACObject) -> bool: def __lt__(self, other: ACObject) -> bool:
return self.value < other: ACObject.value return self.value < other.value
def __le__(self, other: ACObject) -> bool: def __le__(self, other: ACObject) -> bool:
return self.value <= other: ACObject.value return self.value <= other.value
def __gt__(self, other: ACObject) -> bool: def __gt__(self, other: ACObject) -> bool:
return self.value > other: ACObject.value return self.value > other.value
def __ge__(self, other: ACObject) -> bool: def __ge__(self, other: ACObject) -> bool:
return self.value >= other: ACObject.value return self.value >= other.value
def __eq__(self, other: ACObject) -> bool: def __eq__(self, other: ACObject) -> bool:
return self.value == other: ACObject.value return self.value == other.value
def __ne__(self, other: ACObject) -> bool: def __ne__(self, other: ACObject) -> bool:
return self.value != other: ACObject.value return self.value != other.value
def __neg__(self) -> ACObject: def __neg__(self) -> ACObject:
return type(self).__init__(value: -self.value) return type(self).__init__(value = -self.value)
def __abs__(self) -> ACObject: def __abs__(self) -> ACObject:
return type(self).__init__(value: abs(self.value)) return type(self).__init__(value = abs(self.value))
def __round__(self, n) -> ACObject: def __round__(self, n) -> ACObject:
return type(self).__init__(value: round(self.value)) return type(self).__init__(value = round(self.value))
def __floor__(self) -> ACObject: def __floor__(self) -> ACObject:
return type(self).__init__(value: floor(self.value)) return type(self).__init__(value = floor(self.value))
def __ceil__(self) -> ACObject: def __ceil__(self) -> ACObject:
return type(self).__init__(value: ceil(self.value)) return type(self).__init__(value = ceil(self.value))
def __trunc__(self) -> ACObject: def __trunc__(self) -> ACObject:
return type(self).__init__(value: trunc(self.value)) return type(self).__init__(value = trunc(self.value))
def __add__(self, other: ACObject) -> ACObjet: def __add__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value + other: ACObject.value) return type(self).__init__(value = self.value + other.value)
def __sub__(self, other: ACObject) -> ACObjet: def __sub__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value - other: ACObject.value) return type(self).__init__(value = self.value - other.value)
def __mul__(self, other: ACObject) -> ACObjet: def __mul__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value a8 other: ACObject.value) return type(self).__init__(value = self.value * other.value)
def __floordiv__(self, other: ACObject) -> ACObjet: def __floordiv__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value // other: ACObject.value) return type(self).__init__(value = self.value // other.value)
def __div__(self, other: ACObject) -> ACObjet: def __div__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value / other: ACObject.value) return type(self).__init__(value = self.value / other.value)
def __mod__(self, other: ACObject) -> ACObjet: def __mod__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value % other: ACObject.value) return type(self).__init__(value = self.value % other.value)
def __pow__(self, other: ACObject) -> ACObjet: def __pow__(self, other: ACObject) -> ACObjet:
return type(self).__init__(value: self.value ** other: ACObject.value) return type(self).__init__(value = self.value ** other.value)

View File

@ -1,4 +1,4 @@
from .ACObject import ACObject, Pattern from .ACObject import ACObject, Pattern, classproperty
class ACString(ACObject): class ACString(ACObject):
value: str value: str
@ -7,8 +7,8 @@ class ACString(ACObject):
self.value = string self.value = string
@classmethod @classmethod
def parse(class, fromString: str): def parse(cls, fromString: str):
acString = ACString(value: string) acString = cls(value = string)
acString.stringValue = string acString.stringValue = string
return acString return acString

View File

@ -1,11 +1,14 @@
from __future__ import annotations
from typing import Optional
from datetime import datetime, timedelta from datetime import datetime, timedelta
from .ACObject import ACObject, Pattern from .ACObject import ACObject, Pattern, classproperty
from . import ACTimeInterval
class ACTime(ACObject): class ACTime(ACObject):
value: datetime value: datetime
def __init__(self, value: time = datetime.now()): def __init__(self, value: Optional[datetime] = None):
self.value = value self.value = value or datetime.now()
def addingInterval(self, timeinterval: ACTimeInterval) -> ACTime: def addingInterval(self, timeinterval: ACTimeInterval) -> ACTime:
return ACTime(self.value + timedelta(seconds = timeinterval.value)) return ACTime(self.value + timedelta(seconds = timeinterval.value))

View File

@ -1,4 +1,5 @@
from .ACObject import ACObject, Pattern from __future__ import annotations
from .ACObject import ACObject, Pattern, classproperty
class ACTimeInterval(ACObject): class ACTimeInterval(ACObject):
value: float # seconds value: float # seconds
@ -14,7 +15,7 @@ class ACTimeInterval(ACObject):
hours += days * 24 hours += days * 24
minutes += hours * 60 minutes += hours * 60
seconds += minutes * 60 seconds += minutes * 60
return ACTimeInterval(value: seconds) return ACTimeInterval(value = seconds)
@classmethod @classmethod
def parse(cls, fromString: str) -> ACObject: def parse(cls, fromString: str) -> ACObject:

View File

@ -1,4 +1,5 @@
from .ACObject import ACString, Pattern from .ACObject import Pattern, classproperty
from . import ACString
class ACWord(ACString): class ACWord(ACString):

View File

@ -0,0 +1,6 @@
from .ACObject import ACObject
from .ACNumber import ACNumber
from .ACString import ACString
from .ACWord import ACWord
from .ACTime import ACTime
from .ACTimeInterval import ACTimeInterval

View File

@ -1,8 +1,8 @@
from typing import Callable from typing import Callable
from abc import ABC from abc import ABC
from ..Pattern import ACObject, Pattern from ..ACObjects import ACObject
from .CommandsManager import CommandsManager from ..Pattern import Pattern
class Command(ABC): class Command(ABC):
name: str name: str
@ -12,6 +12,9 @@ class Command(ABC):
def __init__(self, name, patterns = [], primary = True): def __init__(self, name, patterns = [], primary = True):
self._name = name self._name = name
self._patterns = patterns self._patterns = patterns
self.primary = primary
from .CommandsManager import CommandsManager
CommandsManager().append(self) CommandsManager().append(self)
def start(self, params: dict[str, ACObject]): def start(self, params: dict[str, ACObject]):
@ -30,7 +33,7 @@ class Command(ABC):
@classmethod @classmethod
def new(cls, *args, **kwargs): def new(cls, *args, **kwargs):
def creator(func): def creator(func) -> Command:
cmd: Command = cls(func.__name__, *args, **kwargs) cmd: Command = cls(func.__name__, *args, **kwargs)
cmd.setStart(func) cmd.setStart(func)
return cmd return cmd

View File

@ -1,6 +1,7 @@
from typing import Type, Optional from typing import Type, Optional
from . import Command from .Command import Command
from ..Pattern import ACObject from ..ACObjects import ACObject
from .RThread import RThread, Event
class SearchResult: class SearchResult:
command: Command command: Command
@ -32,7 +33,7 @@ class CommandsManager:
name, typeName = key.split(':') name, typeName = key.split(':')
ACType: Type[ACObject] = CommandsManager.classFromString(typeName) ACType: Type[ACObject] = CommandsManager.classFromString(typeName)
try: parameters[name] = ACType.parse(string: value) try: parameters[name] = ACType.parse(string = value)
except: break except: break
else: else:
results.append(SearchResult(command, parameters)) results.append(SearchResult(command, parameters))

View File

@ -1 +0,0 @@
from .ACObject import ACObject

View File

@ -2,7 +2,7 @@ from typing import Type, Optional
import re import re
from .expressions import expressions from .expressions import expressions
from .ACObjects import * from ..ACObjects import *
class Pattern: class Pattern:
origin: str origin: str

View File

@ -1,2 +1,2 @@
from .Pattern import Pattern from .Pattern import Pattern
from .ACObjects import * from ..ACObjects import *

View File

@ -1,2 +1,3 @@
from .Pattern import * from .Pattern import *
from .Command import * from .Commands import *
from .ACObjects import *

View File

@ -1,14 +1,12 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from General import Singleton
class Control(ABC): class Control(Singleton):
# Singleton @abstractmethod
def __new__(cls): def __init__(self):
if not hasattr(cls, 'instance'): pass
cls.instance = super().__new__(cls)
return cls.instance
@abstractmethod @abstractmethod
def start(self): def start(self):
# entry point of the control
pass pass

View File

@ -0,0 +1,67 @@
from typing import Callable, Optional
from time import sleep
from ArchieCore.ACObjects import ACTime, ACTimeInterval
from .. import Singleton, UUID, threadingFunction
from .DispatchQueueItem import DispatchQueueItem
class DispatchQueue(Singleton):
_queue: [DispatchQueueItem] = []
_nearestItemTime: Optional[ACTime] = None
def asyncAt(self, time: ACTime, execute: Callable, *args, **kwargs) -> UUID:
item = DispatchQueueItem(execute = execute, time = time, args = args, kwargs = kwargs)
self.insert(item)
return item.id
def asyncAfter(self, timeinterval: ACTimeInterval, execute: Callable, *args, **kwargs) -> UUID:
time = ACTime().addingInterval(timeinterval)
item = DispatchQueueItem(execute = execute, time = time, timeinterval = timeinterval,
args = args, kwargs = kwargs)
self.insert(item)
return item.id
def repeatEvery(self, timeinterval: ACTimeInterval, execute: Callable, *args, **kwargs) -> UUID:
time = ACTime().addingInterval(timeinterval)
item = DispatchQueueItem(execute = execute, time = time, timeinterval = timeinterval,
repeat = True, args = args, kwargs = kwargs)
self.insert(item)
return item.id
def insert(self, item: DispatchQueueItem):
now = ACTime()
low = 0
high = len(self._queue)
while low < high:
mid = (low + high) // 1
if self._queue[mid].time < now: low = mid + 1
else: high = mid
self._queue.insert(low, item)
self._nearestItemTime = self._queue[0].time
def invalidate(self, id: UUID) -> DispatchQueueItem:
for i, item in enumerate(self._queue):
if item.id != id: continue
if i == 0: self._nearestItemTime = self._queue[1].time if len(self._queue) > 1 else None
return self._queue.pop(i)
@threadingFunction
def loop(self):
while True:
if not self._queue or not self._nearestItemTime or self._nearestItemTime > ACTime():
sleep(0.1)
continue
item = self._queue.pop(0)
item.execute()
if item.repeat:
item.time.addInterval(item.timeinterval)
self.insert(item)
self._nearestItemTime = self._queue[0].time if self._queue else None
DispatchQueue().loop()

View File

@ -0,0 +1,24 @@
from typing import Callable, Any
from ArchieCore import ACTime, ACTimeInterval
from .. import Identifable, threadingFunction
class DispatchQueueItem(Identifable):
time: ACTime
timeinterval: ACTimeInterval
worker: Callable
args: list[Any]
kwargs: dict[Any, Any]
repeat: bool
def __init__(self, execute: Callable, time: ACTime = ACTime(), timeinterval: ACTimeInterval = ACTimeInterval(0),
repeat: bool = False, args: list[Any] = [], kwargs: dict[Any, Any] = []):
self.time = time
self.timeinterval = timeinterval
self.worker = execute
self.args = args
self.kwargs = kwargs
self.repeat = repeat
@threadingFunction
def execute(self):
self.worker(*self.args, **self.kwargs)

View File

@ -0,0 +1,2 @@
from .DispatchQueue import DispatchQueue
from .DispatchQueueItem import DispatchQueueItem

View File

@ -0,0 +1,11 @@
from __future__ import annotations
from .UUID import UUID
class Identifable():
id: UUID = UUID()
def __eq__(self, other: Identifable) -> bool:
return self.id == other.id
def __ne__(self, other: Identifable) -> bool:
return self.id != other.id

View File

@ -0,0 +1 @@
from uuid import uuid4 as UUID

View File

@ -0,0 +1,2 @@
from .Identifable import Identifable
from .UUID import UUID

View File

@ -0,0 +1,12 @@
from typing import Any, Optional
from .NotificationName import NotificationName
class Notification:
name: NotificationName
object: Any
data: dict
def __init__(self, name: NotificationName, object: Optional[Any], data: dict):
self.name = name
self.object = object
self.data = data

View File

@ -0,0 +1,25 @@
from typing import Any, Optional
from .. import Singleton, UUID
from . import Notification, NotificationName, NotificationObserver, NotificationCallback
class NotificationCenter(Singleton):
_observers: dict[NotificationName, list[NotificationObserver]] = {}
def post(self, name: NotificationName, object: Optional[Any] = None, data: dict = []):
notify = Notification(name = name, object = object, data = data)
for obser in self._observers.get(name) or []:
obser.callback(notify)
def addObserver(self, notificationName: NotificationName, callback: NotificationCallback) -> NotificationObserver:
if not notificationName in self._observers.keys() :
self._observers[notificationName] = []
observer = NotificationObserver(notificationName, callback)
self._observers[notificationName].append(observer)
return observer
def removeObserver(self, observer: NotificationObserver):
if observer in self._observers.get(observer.notificationName) or []:
self._observers.get(observer.notificationName).remove(observer)

View File

@ -0,0 +1,4 @@
from enum import Enum, auto
class NotificationName(Enum):
test = auto()

View File

@ -0,0 +1,15 @@
from typing import Callable
from .. import Identifable, threadingFunction
from . import Notification, NotificationName
NotificationCallback = Callable[[Notification,], None]
class NotificationObserver(Identifable):
notificationName: NotificationName
callback: NotificationCallback
def __init__(self, notificationName: NotificationName, callback: NotificationCallback):
super().__init__()
self.notificationName = notificationName
self.callback = threadingFunction(callback)

View File

@ -0,0 +1,4 @@
from .Notification import Notification
from .NotificationName import NotificationName
from .NotificationObserver import NotificationObserver, NotificationCallback # noqa
from .NotificationCenter import NotificationCenter

9
General/Singleton.py Normal file
View File

@ -0,0 +1,9 @@
from abc import ABC
class Singleton(ABC):
# Singleton
def __new__(cls):
if not hasattr(cls, 'instance'):
cls.instance = super().__new__(cls)
return cls.instance

View File

@ -0,0 +1,7 @@
from threading import Thread
def threadingFunction(func):
def starter(*args, **kwargs):
thread = Thread(target = func, args = args, kwargs = kwargs)
thread.start()
return starter

9
General/__init__.py Normal file
View File

@ -0,0 +1,9 @@
from .Singleton import *
from .Identifable import *
from .ThreadingFunction import threadingFunction
#from .StringProcesser import *
from .DataBase import *
from .DispatchQueue import *
from .Notifications import *
from .SpeechRecognition import *
from .Text2Speech import *