NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

componentregistry.py (6038B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\spacecomponents\common\componentregistry.py
      2 from __future__ import absolute_import
      3 from collections import defaultdict
      4 from ccpProfile import TimedFunction
      5 from .componentmessenger import ComponentMessenger
      6 from eveexceptions.exceptionEater import ExceptionEater
      7 from spacecomponents.common.componentclass import ComponentClass
      8 from spacecomponents.common.data import get_space_component_names_for_type, get_space_component_for_type
      9 
     10 class UnregisteredComponentError(Exception):
     11     pass
     12 
     13 
     14 class ComponentInstanceAlreadyExists(Exception):
     15     pass
     16 
     17 
     18 def ExportCall(func):
     19     func.isExportedComponentCall = True
     20     return func
     21 
     22 
     23 class ComponentRegistry(object):
     24     asyncFuncs = None
     25 
     26     def __init__(self, asyncFuncs, eventLogger, componentClassTypes, typeIDToClassMapping):
     27         self.asyncFuncs = asyncFuncs
     28         self.eventLogger = eventLogger
     29         self.componentClassTypes = {componentName:ComponentClass(componentName, componentClass) for componentName, componentClass in componentClassTypes.iteritems()}
     30         self.componentNames = tuple(self.componentClassTypes.keys())
     31         self.typeIDToClassMapping = typeIDToClassMapping
     32         self.itemIDToComponentInstances = {}
     33         self.componentNameToItemIDs = defaultdict(dict)
     34         self.messenger = ComponentMessenger()
     35 
     36     @TimedFunction('SpaceComponent::ComponentRegistry::GetComponentClassesForTypeID')
     37     def GetComponentClassesForTypeID(self, typeID):
     38         componentClassesForTypeID = self.typeIDToClassMapping.get(typeID, None)
     39         if componentClassesForTypeID is None:
     40             componentClassesForTypeID = self.RegisterComponentsForType(typeID)
     41         return componentClassesForTypeID
     42 
     43     @TimedFunction('SpaceComponent::ComponentRegistry::RegisterComponentsForType')
     44     def RegisterComponentsForType(self, typeID):
     45         componentNames = get_space_component_names_for_type(typeID, component_names=self.componentNames)
     46         componentClassesForTypeID = []
     47         for componentName in componentNames:
     48             componentClassesForTypeID.append(self.componentClassTypes[componentName])
     49 
     50         self.typeIDToClassMapping[typeID] = componentClassesForTypeID
     51         return componentClassesForTypeID
     52 
     53     def GetComponentsByItemID(self, itemID):
     54         return self.itemIDToComponentInstances[itemID]
     55 
     56     def GetAllComponentInstancesWithAttribute(self, itemID, attribute):
     57         components_by_name = self.GetComponentsByItemID(itemID)
     58         instances_with_attribute = [ instance for instance in components_by_name.itervalues() if hasattr(instance, attribute) ]
     59         return instances_with_attribute
     60 
     61     def CreateComponentInstances(self, itemID, typeID):
     62         componentClassesForTypeID = self.GetComponentClassesForTypeID(typeID)
     63         components = self._GetComponentsByItemId(itemID)
     64         for componentClass in componentClassesForTypeID:
     65             if componentClass.componentName in components:
     66                 continue
     67             attributes = get_space_component_for_type(typeID, componentClass.componentName)
     68             with ExceptionEater('Error creating a component %s' % componentClass.componentName):
     69                 instance = componentClass.factoryMethod(itemID, typeID, attributes, self)
     70                 components[componentClass.componentName] = instance
     71                 self.componentNameToItemIDs[componentClass.componentName][itemID] = instance
     72 
     73         return components
     74 
     75     def _GetComponentsByItemId(self, itemId):
     76         if itemId in self.itemIDToComponentInstances:
     77             components = self.itemIDToComponentInstances[itemId]
     78         else:
     79             components = {}
     80             self.itemIDToComponentInstances[itemId] = components
     81         return components
     82 
     83     def AddComponentInstanceToItem(self, componentName, itemId, typeID, attributes):
     84         components = self._GetComponentsByItemId(itemId)
     85         componentClass = self.componentClassTypes[componentName]
     86         instance = componentClass.factoryMethod(itemId, typeID, attributes, self)
     87         components[componentName] = instance
     88         self.componentNameToItemIDs[componentName][itemId] = instance
     89         return instance
     90 
     91     def DeleteComponentInstances(self, itemID):
     92         self.messenger.DeleteSubscriptionsForItem(itemID)
     93         instance = self.itemIDToComponentInstances.pop(itemID)
     94         for componentName in instance:
     95             del self.componentNameToItemIDs[componentName][itemID]
     96 
     97     def GetInstancesWithComponentClass(self, componentName):
     98         return self.componentNameToItemIDs[componentName].values()
     99 
    100     def SendMessageToItem(self, itemID, messageName, *args, **kwargs):
    101         self.messenger.SendMessageToItem(itemID, messageName, *args, **kwargs)
    102 
    103     def SendMessageToAllItems(self, messageName, *args, **kwargs):
    104         self.messenger.SendMessageToAllItems(messageName, *args, **kwargs)
    105 
    106     def SubscribeToItemMessage(self, itemID, messageName, messageHandler):
    107         self.GetComponentsByItemID(itemID)
    108         self.messenger.SubscribeToItemMessage(itemID, messageName, messageHandler)
    109 
    110     def GetComponentForItem(self, itemID, componentClassID):
    111         return self.itemIDToComponentInstances[itemID][componentClassID]
    112 
    113     def UnsubscribeFromItemMessage(self, itemID, messageName, messageHandler):
    114         self.messenger.UnsubscribeFromItemMessage(itemID, messageName, messageHandler)
    115 
    116     def CallComponent(self, session, itemID, componentClassName, methodName, *args, **kwargs):
    117         try:
    118             component = self.GetComponentForItem(itemID, componentClassName)
    119         except KeyError:
    120             return
    121 
    122         method = getattr(component, methodName)
    123         if not getattr(method, 'isExportedComponentCall', False):
    124             raise RuntimeError("The method '%s' is not exported on component '%s'" % (methodName, componentClassName))
    125         return method(session, *args, **kwargs)
    126 
    127     @staticmethod
    128     def GetServiceForComponent(serviceName):
    129         return sm.GetService(serviceName)