class _IntrospectionService(servicemodule.ServiceProvider): def __init__(self, bus): self.bus = bus self.details = {} self.autobus_event = Event() self.bus.local_services.global_watch(self.local_service_changed) def local_service_changed(self, service_id, old, new): if old: old.functions.global_unwatch(self.local_service_component_changed) old.events.global_unwatch(self.local_service_component_changed) old.objects.global_unwatch(self.local_service_component_changed) if new: new.functions.global_watch(self.local_service_component_changed) new.events.global_watch(self.local_service_component_changed) new.objects.global_watch(self.local_service_component_changed) self.rebuild_details() def local_service_component_changed(self, name, old, new): self.rebuild_details() def rebuild_details(self): self.details = self.create_details() self.autobus_event(constants.OBJECT_CHANGED, "details", self.details) def create_details(self): # TODO: Consider having this whole thing cached, and only update the # relevant portions of it when services come and go details = {} for service_id, service in self.bus.local_services.items(): service_details = {} details[service_id] = service_details service_details["info"] = service.info for type in ["functions", "events", "objects"]: type_details = {} service_details[type] = type_details for name, info in getattr(service, type).items(): type_details[name] = info return details def __autobus_call__(self, name, args): if name == "get_details": return self.details raise exceptions.NoSuchFunctionException(name) def __autobus_policy__(self, name): return SYNC def __autobus_listen__(self, listener): listener(constants.OBJECT_ADDED, "details", {}, self.details) listener(constants.FUNCTION_ADDED, "get_details", {}) self.autobus_event.listen(listener) def __autobus_unlisten__(self, listener): self.autobus_event.unlisten(listener) listener(constants.OBJECT_REMOVED, "details") listener(constants.FUNCTION_REMOVED, "get_details")
def __init__(self): self.__event = Event() self._functions = PropertyTable() self._functions.global_watch(self.__function_listener) self._events = PropertyTable() self._events.global_watch(self.__event_listener) self._event_table = EventTable() self._event_table.global_listen(self.__event_table_listener) self._objects = PropertyTable() self._objects.global_watch(self.__object_listener) self._object_values = PropertyTable() self._object_values.global_watch(self.__object_values_listener)
def __init__(self, bus): self.bus = bus self.details = {} self.autobus_event = Event() self.bus.local_services.global_watch(self.local_service_changed)
class BaseServiceProvider(ServiceProvider): """ A ServiceProvider that provides basic implementations of its methods. It allows functions to be registered and unregistered, and so on for events and objects. It handles automatically notifying any registered listeners of changes that have happened. The attributes _functions, _events, _event_table, _objects, and _object_values form part of the public interface of this class. """ def __init__(self): self.__event = Event() self._functions = PropertyTable() self._functions.global_watch(self.__function_listener) self._events = PropertyTable() self._events.global_watch(self.__event_listener) self._event_table = EventTable() self._event_table.global_listen(self.__event_table_listener) self._objects = PropertyTable() self._objects.global_watch(self.__object_listener) self._object_values = PropertyTable() self._object_values.global_watch(self.__object_values_listener) def __function_listener(self, name, old, new): if old is not None and new is not None: # Info change self.__event(constants.FUNCTION_UPDATED, name, new) elif old is not None: # Function was removed self.__event(constants.FUNCTION_REMOVED, name) elif new is not None: # Function was added self.__event(constants.FUNCTION_ADDED, name, new) def __event_listener(self, name, old, new): if old is not None and new is not None: # Info change self.__event(constants.EVENT_UPDATED, name, new) elif old is not None: # Event was removed self.__event(constants.EVENT_REMOVED, name) elif new is not None: # Event was added self.__event(constants.EVENT_ADDED, name, new) def __object_listener(self, name, old, new): if old is not None and new is not None: # Info change self.__event(constants.OBJECT_UPDATED, name, new) elif old is not None: # Object was removed self.__event(constants.OBJECT_REMOVED, name) elif new is not None: # Object was added self.__event(constants.OBJECT_ADDED, name, new, self._object_values.get(name, None)) def __object_values_listener(self, name, old, new): # Only issue object change notifications if the object actually exists # in our _objects property table if not name in self._objects: return self.__event(constants.OBJECT_CHANGED, name, new) def __event_table_listener(self, *args): name = args[0] args = args[1:] if name in self._events: self.__event(constants.EVENT_FIRED, name, args) def __autobus_policy__(self, name): return constants.THREAD def __autobus_listen__(self, listener): for name, info in self._functions.items(): listener(constants.FUNCTION_ADDED, name, info) for name, info in self._events.items(): listener(constants.EVENT_ADDED, name, info) for name, info in self._objects.items(): listener(constants.OBJECT_ADDED, name, info, self._object_values.get(name, None)) self.__event.listen(listener) def __autobus_unlisten__(self, listener): self.__event.unlisten(listener) for name in self._functions: listener(constants.FUNCTION_REMOVED, name) for name in self._events: listener(constants.EVENT_REMOVED, name) for name in self._objects: listener(constants.OBJECT_REMOVED, name)