__init__.py (8066B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\blackboards\__init__.py 2 import collections 3 from behaviors.blackboards.scopes import IsReusableScope 4 import signals 5 from ccpProfile import TimedFunction 6 from eveexceptions.exceptionEater import ExceptionEater 7 MessageData = collections.namedtuple('MessageData', ['time', 'value']) 8 9 class MessageChannel(object): 10 11 def __init__(self, name, getTimeFunc, maxLength = 10): 12 self.name = name 13 self.messages = collections.deque(maxlen=maxLength) 14 self.observerSignal = signals.Signal(signalName='observerSignal') 15 self.GetTime = getTimeFunc 16 self.resetOnRespawn = True 17 18 def GetHistoryLength(self): 19 return self.messages.maxlen 20 21 def ClearAllMessages(self): 22 self.messages.clear() 23 self.NotifyObservers(None) 24 25 @TimedFunction('behaviors::blackboards::MessageChannel::SendMessage') 26 def SendMessage(self, messageValue): 27 message = MessageData(self.GetTime(), messageValue) 28 self.messages.appendleft(message) 29 self.NotifyObservers(message) 30 31 def _GetMaxTime(self, maxAge): 32 return self.GetTime() - maxAge 33 34 def _IterMessagesUnderAge(self, maxAge): 35 maxTime = self._GetMaxTime(maxAge) 36 for m in self.messages: 37 if m.time >= maxTime: 38 yield m 39 else: 40 return 41 42 @TimedFunction('behaviors::blackboards::MessageChannel::GetLastMessage') 43 def GetLastMessage(self): 44 if self.messages: 45 return self.messages[0] 46 47 def GetLastMessageWithMaxAge(self, maxAge): 48 if self.messages: 49 m = self.messages[0] 50 if m.time >= self._GetMaxTime(maxAge): 51 return m 52 53 def GetLastMessageValue(self): 54 message = self.GetLastMessage() 55 if message: 56 return message.value 57 else: 58 return None 59 60 def GetLastMessageValueWithMaxAge(self, maxAge): 61 message = self.GetLastMessageWithMaxAge(maxAge) 62 if message: 63 return message.value 64 else: 65 return None 66 67 @TimedFunction('behaviors::blackboards::MessageChannel::GetMessages') 68 def GetMessages(self): 69 return list(self.messages) 70 71 def GetMessagesWithMaxAge(self, maxAge): 72 return [ m for m in self._IterMessagesUnderAge(maxAge) ] 73 74 @TimedFunction('behaviors::blackboards::MessageChannel::NotifyObservers') 75 def NotifyObservers(self, message): 76 self.observerSignal(self.name, message) 77 78 def AddObserver(self, observer): 79 self.observerSignal.connect(observer) 80 81 def RemoveObserver(self, observer): 82 try: 83 self.observerSignal.disconnect(observer) 84 except ValueError: 85 pass 86 87 def RemoveAllObservers(self): 88 self.observerSignal.clear() 89 90 def SetChannelResetOnGroupRespawn(self, reset): 91 self.resetOnRespawn = reset 92 93 def ShouldResetOnRespawn(self): 94 return self.resetOnRespawn 95 96 97 class Blackboard(object): 98 99 def __init__(self, identity, getTimeFunc, maxHistoryLength): 100 self.identity = identity 101 self.getTimeFunc = getTimeFunc 102 self.maxHistoryLength = maxHistoryLength 103 self.messageChannelsByName = {} 104 self.allObserverSignal = signals.Signal(signalName='allObserverSignal') 105 106 def CreateMessageChannel(self, name, maxHistoryLength): 107 if name in self.messageChannelsByName: 108 raise MessageChannelAlreadyExistsError() 109 channel = MessageChannel(name, self.getTimeFunc, maxHistoryLength) 110 channel.AddObserver(self.allObserverSignal) 111 self.messageChannelsByName[name] = channel 112 113 def AddMessageObserver(self, messageType, observer): 114 channel = self.GetMessageChannel(messageType) 115 channel.AddObserver(observer) 116 117 def RemoveMessageObserver(self, messageType, observer): 118 channel = self.GetMessageChannel(messageType) 119 channel.RemoveObserver(observer) 120 121 def GetMessageChannel(self, name): 122 if name not in self.messageChannelsByName: 123 self.CreateMessageChannel(name, self.maxHistoryLength) 124 return self.messageChannelsByName[name] 125 126 def GetMessageChannelList(self): 127 return self.messageChannelsByName.values() 128 129 def SendMessage(self, messageType, messageValue): 130 channel = self.GetMessageChannel(messageType) 131 channel.SendMessage(messageValue) 132 133 def GetLastMessage(self, messageType): 134 channel = self.GetMessageChannel(messageType) 135 return channel.GetLastMessage() 136 137 def GetLastMessageWithMaxAge(self, messageType, maxAge): 138 channel = self.GetMessageChannel(messageType) 139 return channel.GetLastMessageWithMaxAge(maxAge) 140 141 def GetMessages(self, messageType): 142 channel = self.GetMessageChannel(messageType) 143 return channel.GetMessages() 144 145 def GetMessagesWithMaxAge(self, messageType, maxAge): 146 channel = self.GetMessageChannel(messageType) 147 return channel.GetMessagesWithMaxAge(maxAge) 148 149 def GetLastMessageValue(self, messageType): 150 channel = self.GetMessageChannel(messageType) 151 return channel.GetLastMessageValue() 152 153 def GetLastMessageValueWithMaxAge(self, messageType, maxAge): 154 channel = self.GetMessageChannel(messageType) 155 return channel.GetLastMessageValue(maxAge) 156 157 def GetLastMessageValueForAll(self): 158 return {messageType:channel.GetLastMessageValue() for messageType, channel in self.messageChannelsByName.iteritems()} 159 160 def Reset(self): 161 for channel in self.messageChannelsByName.values(): 162 channel.RemoveAllObservers() 163 164 self.allObserverSignal.clear() 165 self.messageChannelsByName.clear() 166 167 def ResetOnGroupRespawn(self): 168 channelNames = self.messageChannelsByName.keys() 169 for channelName in channelNames: 170 channel = self.messageChannelsByName[channelName] 171 if channel.ShouldResetOnRespawn(): 172 channel.RemoveAllObservers() 173 channel.ClearAllMessages() 174 175 for channel in self.messageChannelsByName.itervalues(): 176 channel.AddObserver(self.allObserverSignal) 177 178 179 class BlackboardManager: 180 181 def __init__(self, getTimeFunc, maxHistoryLength): 182 self.blackboardsById = {} 183 self.maxHistoryLength = maxHistoryLength 184 self.getTimeFunc = getTimeFunc 185 self.removedBlackboards = set() 186 187 def CreateBlackboard(self, blackboardId, maxHistoryLength): 188 if blackboardId in self.blackboardsById: 189 raise BlackboardAlreadyExistsError() 190 if not IsReusableScope(blackboardId) and blackboardId in self.removedBlackboards: 191 raise BlackboardDeletedError() 192 bb = Blackboard(blackboardId, self.getTimeFunc, maxHistoryLength) 193 self.blackboardsById[blackboardId] = bb 194 195 def GetBlackboard(self, blackboardId): 196 if blackboardId not in self.blackboardsById: 197 self.CreateBlackboard(blackboardId, self.maxHistoryLength) 198 return self.blackboardsById[blackboardId] 199 200 def RemoveBlackboard(self, blackboardId): 201 if blackboardId in self.blackboardsById: 202 blackboard = self.blackboardsById.pop(blackboardId) 203 blackboard.Reset() 204 if not IsReusableScope(blackboardId): 205 self.removedBlackboards.add(blackboardId) 206 207 def HasBlackboard(self, blackboardId): 208 return blackboardId in self.blackboardsById 209 210 def GetMessageChannel(self, blackboardId, messageType): 211 return self.GetBlackboard(blackboardId).GetMessageChannel(messageType) 212 213 def CleanUp(self): 214 with ExceptionEater('cleaning up'): 215 for blackboard in self.blackboardsById.values(): 216 blackboard.Reset() 217 218 self.blackboardsById.clear() 219 220 def GetBlackboardCount(self): 221 return len(self.blackboardsById) 222 223 224 class MessageChannelAlreadyExistsError(Exception): 225 pass 226 227 228 class BlackboardAlreadyExistsError(Exception): 229 pass 230 231 232 class BlackboardDeletedError(Exception): 233 pass