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

state_machine.py (4382B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dynamicresources\client\ess\bracket\state_machine.py
      2 import logging
      3 import eveui
      4 import gametime
      5 import threadutils
      6 import uthread2
      7 log = logging.getLogger(__name__)
      8 
      9 class StateMachine(object):
     10 
     11     def __init__(self):
     12         self._is_closed = False
     13         self._active_state = None
     14         self._next_state = None
     15         self._is_transitioning = False
     16         self._active_transition = None
     17 
     18     @property
     19     def is_closed(self):
     20         return self._is_closed
     21 
     22     def close(self):
     23         if self._active_transition is not None:
     24             self._active_transition.stop()
     25         if self._active_state is not None:
     26             self._active_state.close()
     27             self._active_state = None
     28         self._is_closed = True
     29 
     30     @threadutils.threaded
     31     def move_to(self, state):
     32         self._next_state = state
     33         if self._is_transitioning:
     34             if self._active_transition is not None:
     35                 self._active_transition.stop()
     36             return
     37         while self._next_state is not None:
     38             state = self._next_state
     39             self._next_state = None
     40             self._move_to(state)
     41 
     42     def _move_to(self, state):
     43         self._is_transitioning = True
     44         try:
     45             if self._active_state is not None:
     46                 if type(self._active_state) == type(state):
     47                     return
     48                 transition = self._active_state.exit()
     49                 self._active_state.close()
     50                 if transition is not None:
     51                     self._run_transition(transition)
     52             if self.is_closed:
     53                 return
     54             if self._next_state is not None:
     55                 state = self._next_state
     56                 self._next_state = None
     57             self._active_state = state
     58             transition = self._active_state.enter()
     59             if transition is not None:
     60                 self._run_transition(transition)
     61         finally:
     62             self._is_transitioning = False
     63 
     64     def _run_transition(self, transition):
     65         self._active_transition = transition
     66         try:
     67             transition.start()
     68             transition.wait()
     69         finally:
     70             self._active_transition = None
     71 
     72 
     73 class State(object):
     74 
     75     def enter(self):
     76         return None
     77 
     78     def exit(self):
     79         return None
     80 
     81     def close(self):
     82         pass
     83 
     84 
     85 class Transition(object):
     86 
     87     def __init__(self):
     88         self._is_started = False
     89         self._is_stopped = False
     90         self._is_closed = False
     91         self._wait_channel = uthread2.queue_channel()
     92         self._waiting_count = 0
     93 
     94     @property
     95     def is_stopped(self):
     96         return self._is_stopped
     97 
     98     def animation(self):
     99         pass
    100 
    101     def on_close(self):
    102         pass
    103 
    104     def sleep(self, duration, interruptable = True):
    105         start = gametime.now()
    106         while (gametime.now() - start).total_seconds() < duration:
    107             if interruptable and self._is_stopped:
    108                 raise TransitionStopped()
    109             eveui.wait_for_next_frame()
    110 
    111     def start(self):
    112         if self._is_closed:
    113             raise RuntimeError('Transition has been closed')
    114         if self._is_started:
    115             raise RuntimeError('Already started')
    116         self._is_started = True
    117         self._perform_transition()
    118 
    119     def wait(self):
    120         if self._is_closed:
    121             return
    122         self._waiting_count += 1
    123         try:
    124             self._wait_channel.receive()
    125         finally:
    126             self._waiting_count -= 1
    127 
    128     def stop(self):
    129         self._is_stopped = True
    130 
    131     def close(self):
    132         if self._is_closed:
    133             return
    134         self.stop()
    135         self._is_closed = True
    136         if self._waiting_count > 0:
    137             self._notify_waiting()
    138         self.on_close()
    139 
    140     @threadutils.threaded
    141     def _perform_transition(self):
    142         try:
    143             self.animation()
    144         except TransitionStopped:
    145             pass
    146         except Exception:
    147             log.exception('Exception raised during transition')
    148 
    149         try:
    150             self.close()
    151         except Exception:
    152             log.exception('Exception when closing a transition')
    153 
    154         self._notify_waiting()
    155 
    156     def _notify_waiting(self):
    157         for _ in range(self._waiting_count):
    158             self._wait_channel.send(None)
    159 
    160 
    161 class TransitionStopped(Exception):
    162     pass