2019-05-10 19:50:58 +00:00
|
|
|
import logging
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-10 19:50:58 +00:00
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
2019-05-12 13:56:18 +00:00
|
|
|
|
2019-05-18 19:38:15 +00:00
|
|
|
class Subscription(object):
|
|
|
|
def __init__(self, subscriptee, subscriber):
|
|
|
|
self.subscriptee = subscriptee
|
|
|
|
self.subscriber = subscriber
|
|
|
|
|
|
|
|
def call(self, *args, **kwargs):
|
|
|
|
self.subscriber(*args, **kwargs)
|
|
|
|
|
|
|
|
def cancel(self):
|
|
|
|
self.subscriptee.unwire(self)
|
|
|
|
|
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
class Property(object):
|
2019-07-21 17:40:28 +00:00
|
|
|
def __init__(self, value=None):
|
2019-05-04 14:56:23 +00:00
|
|
|
self.value = value
|
2019-05-18 19:38:15 +00:00
|
|
|
self.subscribers = []
|
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
def getValue(self):
|
|
|
|
return self.value
|
2019-05-18 19:38:15 +00:00
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
def setValue(self, value):
|
2019-07-21 17:40:28 +00:00
|
|
|
if self.value == value:
|
2019-05-10 16:30:53 +00:00
|
|
|
return self
|
2019-05-04 14:56:23 +00:00
|
|
|
self.value = value
|
2019-05-18 19:38:15 +00:00
|
|
|
for c in self.subscribers:
|
2019-05-07 16:47:03 +00:00
|
|
|
try:
|
2019-05-18 19:38:15 +00:00
|
|
|
c.call(self.value)
|
2019-05-07 16:47:03 +00:00
|
|
|
except Exception as e:
|
2019-05-10 20:08:00 +00:00
|
|
|
logger.exception(e)
|
2019-05-05 13:51:33 +00:00
|
|
|
return self
|
2019-05-18 19:38:15 +00:00
|
|
|
|
2019-05-05 13:51:33 +00:00
|
|
|
def wire(self, callback):
|
2019-05-18 19:38:15 +00:00
|
|
|
sub = Subscription(self, callback)
|
|
|
|
self.subscribers.append(sub)
|
2019-07-21 17:40:28 +00:00
|
|
|
if not self.value is None:
|
|
|
|
sub.call(self.value)
|
2019-05-18 19:38:15 +00:00
|
|
|
return sub
|
|
|
|
|
|
|
|
def unwire(self, sub):
|
|
|
|
try:
|
|
|
|
self.subscribers.remove(sub)
|
|
|
|
except ValueError:
|
|
|
|
# happens when already removed before
|
|
|
|
pass
|
2019-05-05 13:51:33 +00:00
|
|
|
return self
|
2019-05-04 14:56:23 +00:00
|
|
|
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
class PropertyManager(object):
|
|
|
|
sharedInstance = None
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
@staticmethod
|
|
|
|
def getSharedInstance():
|
|
|
|
if PropertyManager.sharedInstance is None:
|
|
|
|
PropertyManager.sharedInstance = PropertyManager()
|
|
|
|
return PropertyManager.sharedInstance
|
|
|
|
|
2019-05-07 14:32:53 +00:00
|
|
|
def collect(self, *props):
|
2019-07-21 17:40:28 +00:00
|
|
|
return PropertyManager(
|
|
|
|
{name: self.getProperty(name) if self.hasProperty(name) else Property() for name in props}
|
|
|
|
)
|
2019-05-07 14:32:53 +00:00
|
|
|
|
2019-07-21 17:40:28 +00:00
|
|
|
def __init__(self, properties=None):
|
2019-05-04 14:56:23 +00:00
|
|
|
self.properties = {}
|
2019-05-18 19:38:15 +00:00
|
|
|
self.subscribers = []
|
2019-05-07 14:32:53 +00:00
|
|
|
if properties is not None:
|
|
|
|
for (name, prop) in properties.items():
|
|
|
|
self.add(name, prop)
|
|
|
|
|
|
|
|
def add(self, name, prop):
|
|
|
|
self.properties[name] = prop
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-07 15:09:29 +00:00
|
|
|
def fireCallbacks(value):
|
2019-05-18 19:38:15 +00:00
|
|
|
for c in self.subscribers:
|
2019-05-07 16:47:03 +00:00
|
|
|
try:
|
2019-05-18 19:38:15 +00:00
|
|
|
c.call(name, value)
|
2019-05-07 16:47:03 +00:00
|
|
|
except Exception as e:
|
2019-05-10 20:08:00 +00:00
|
|
|
logger.exception(e)
|
2019-07-21 17:40:28 +00:00
|
|
|
|
2019-05-07 15:09:29 +00:00
|
|
|
prop.wire(fireCallbacks)
|
|
|
|
return self
|
2019-05-07 14:32:53 +00:00
|
|
|
|
2019-05-12 12:35:25 +00:00
|
|
|
def __contains__(self, name):
|
|
|
|
return self.hasProperty(name)
|
|
|
|
|
2019-05-07 14:32:53 +00:00
|
|
|
def __getitem__(self, name):
|
|
|
|
return self.getPropertyValue(name)
|
|
|
|
|
|
|
|
def __setitem__(self, name, value):
|
2019-05-09 20:44:29 +00:00
|
|
|
if not self.hasProperty(name):
|
|
|
|
self.add(name, Property())
|
2019-05-07 14:32:53 +00:00
|
|
|
self.getProperty(name).setValue(value)
|
2019-05-04 14:56:23 +00:00
|
|
|
|
2019-05-12 12:35:25 +00:00
|
|
|
def __dict__(self):
|
2019-07-21 17:40:28 +00:00
|
|
|
return {k: v.getValue() for k, v in self.properties.items()}
|
2019-05-12 12:35:25 +00:00
|
|
|
|
2019-05-09 20:44:29 +00:00
|
|
|
def hasProperty(self, name):
|
|
|
|
return name in self.properties
|
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
def getProperty(self, name):
|
2019-05-09 20:44:29 +00:00
|
|
|
if not self.hasProperty(name):
|
2019-05-07 14:32:53 +00:00
|
|
|
self.add(name, Property())
|
2019-05-04 14:56:23 +00:00
|
|
|
return self.properties[name]
|
2019-05-04 18:26:11 +00:00
|
|
|
|
|
|
|
def getPropertyValue(self, name):
|
|
|
|
return self.getProperty(name).getValue()
|
2019-05-05 17:59:03 +00:00
|
|
|
|
2019-05-07 15:09:29 +00:00
|
|
|
def wire(self, callback):
|
2019-05-18 19:38:15 +00:00
|
|
|
sub = Subscription(self, callback)
|
|
|
|
self.subscribers.append(sub)
|
|
|
|
return sub
|
|
|
|
|
|
|
|
def unwire(self, sub):
|
|
|
|
try:
|
|
|
|
self.subscribers.remove(sub)
|
|
|
|
except ValueError:
|
|
|
|
# happens when already removed before
|
|
|
|
pass
|
2019-05-09 20:44:29 +00:00
|
|
|
return self
|
|
|
|
|
|
|
|
def defaults(self, other_pm):
|
|
|
|
for (key, p) in self.properties.items():
|
|
|
|
if p.getValue() is None:
|
|
|
|
p.setValue(other_pm[key])
|
|
|
|
return self
|
|
|
|
|
2019-05-12 12:35:25 +00:00
|
|
|
def loadConfig(self, filename):
|
|
|
|
cfg = __import__(filename)
|
|
|
|
for name, value in cfg.__dict__.items():
|
|
|
|
if name.startswith("__"):
|
|
|
|
continue
|
|
|
|
self[name] = value
|
|
|
|
return self
|