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

behaviortree.py (4194B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\behaviors\behaviortree.py
      2 from collections import deque
      3 import gametime
      4 from ccpProfile import TimedFunction
      5 import logging
      6 import signals
      7 from eveexceptions.exceptionEater import ExceptionEater
      8 logger = logging.getLogger(__name__)
      9 TICK_END_MARKER = None
     10 MESSAGE_REQUEST_RESET = 'OnRequestReset'
     11 MESSAGE_STEP = 'OnStep'
     12 MESSAGE_RESET = 'OnReset'
     13 MESSAGE_TICK_DONE = 'OnTickDone'
     14 MESSAGE_BLOCK_RESET = 'OnBlockReset'
     15 
     16 class UnrecoverableBehaviorError(Exception):
     17     pass
     18 
     19 
     20 class BehaviorTree(object):
     21 
     22     def __init__(self, behaviorId = None, scopeType = None):
     23         self.behaviorId = behaviorId
     24         self.scopeType = scopeType
     25         self._tasks = deque()
     26         self._rootTask = None
     27         self._isResetRequested = False
     28         self._isResetBlocked = False
     29         self._messenger = signals.Messenger()
     30 
     31     def Release(self):
     32         with ExceptionEater('CleanUp behavior tree'):
     33             if self._rootTask is not None:
     34                 self._rootTask.CleanUp()
     35                 logger.debug('Cleaned up behaviors for behaviortree')
     36         self._rootTask = None
     37         self._messenger = None
     38 
     39     def StartRootTask(self, rootTask):
     40         self._rootTask = rootTask
     41         rootTask.SetExitObserver(self.OnRootTaskTerminated)
     42         self.StartTask(rootTask)
     43 
     44     def AddEndMarker(self):
     45         self._tasks.append(TICK_END_MARKER)
     46 
     47     def StartTask(self, task):
     48         self._tasks.appendleft(task)
     49 
     50     def StartTaskNextTick(self, task):
     51         self._tasks.append(task)
     52 
     53     def GetTaskList(self):
     54         return list(self._tasks)
     55 
     56     def GetRootTask(self):
     57         return self._rootTask
     58 
     59     @TimedFunction('behaviors::behaviortree::BehaviorTree::Tick')
     60     def Tick(self, context):
     61         startTime = gametime.GetWallclockTimeNow()
     62         self.ProcessResetRequest()
     63         self.AddEndMarker()
     64         while self.Step(context):
     65             pass
     66 
     67         self.SendMessage(MESSAGE_TICK_DONE, context)
     68         updateTime = gametime.GetWallclockTimeNow() - startTime
     69         context.statistics.update(updateTime)
     70 
     71     @TimedFunction('behaviors::behaviortree::BehaviorTree::Step')
     72     def Step(self, context):
     73         task = self._tasks.popleft()
     74         moreTasks = True
     75         if task is TICK_END_MARKER:
     76             moreTasks = False
     77         else:
     78             task.Tick(self, context)
     79             context.statistics.add_tick()
     80         self.SendMessage(MESSAGE_STEP, task=task)
     81         return moreTasks
     82 
     83     def BlockReset(self, blockingTask):
     84         self._SetBlockReset(True, blockingTask)
     85 
     86     def UnblockReset(self, blockingTask):
     87         self._SetBlockReset(False, blockingTask)
     88 
     89     def _SetBlockReset(self, isBlocking, blockingTask):
     90         self.SendMessage(MESSAGE_BLOCK_RESET, isBlocking, blockingTask)
     91         self._isResetBlocked = isBlocking
     92 
     93     def RequestReset(self, requestedBy = None):
     94         logger.debug("requested reset for behavior=%s by task=%s name='%s'", self.behaviorId, requestedBy.__class__.__name__, getattr(getattr(requestedBy, 'attributes', None), 'name', None))
     95         self._isResetRequested = True
     96         self.SendMessage(MESSAGE_REQUEST_RESET, requestedBy=requestedBy)
     97         self._UpdateStatistics(requestedBy)
     98 
     99     def _UpdateStatistics(self, requestedBy):
    100         self.GetRootTask().context.statistics.update_request_reset(requestedBy)
    101 
    102     @TimedFunction('behaviors::behaviortree::BehaviorTree::Reset')
    103     def Reset(self):
    104         self._tasks.clear()
    105         self._rootTask.CleanUp()
    106         self.StartTask(self._rootTask)
    107         self.SendMessage(MESSAGE_RESET)
    108 
    109     def ProcessResetRequest(self):
    110         if self._isResetRequested and not self._isResetBlocked:
    111             self._isResetRequested = False
    112             self.Reset()
    113 
    114     def HasResetRequest(self):
    115         return self._isResetRequested
    116 
    117     def OnRootTaskTerminated(self, rootTask):
    118         self.RequestReset(requestedBy=rootTask)
    119 
    120     def GetMessenger(self):
    121         return self._messenger
    122 
    123     def SendMessage(self, messageName, *args, **kwargs):
    124         self._messenger.SendMessage(messageName, *args, **kwargs)
    125 
    126     def GetBehaviorId(self):
    127         return self.behaviorId