예제 #1
0
파일: __init__.py 프로젝트: giflw/afn-tools
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")
예제 #2
0
 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)
예제 #3
0
파일: __init__.py 프로젝트: giflw/afn-tools
 def __init__(self, bus):
     self.bus = bus
     self.details = {}
     self.autobus_event = Event()
     self.bus.local_services.global_watch(self.local_service_changed)
예제 #4
0
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)