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

state.py (10583B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\dynamicresources\client\ess\state.py
      2 import datetime
      3 from collections import OrderedDict
      4 import codereload
      5 import enum
      6 import gametime
      7 import immutable
      8 import signals
      9 import weakness
     10 UNCHANGED = object()
     11 
     12 class EssStateProvider(object):
     13 
     14     def __init__(self, state, on_fetch_request = None):
     15         self._next_token_id = 1
     16         self._state = state
     17         self._subscribers = OrderedDict()
     18         self._need_fetch = False
     19         self.on_fetch_request = signals.Signal()
     20         if on_fetch_request is not None:
     21             self.on_fetch_request.connect(on_fetch_request)
     22 
     23     @property
     24     def state(self):
     25         self._signal_fetch_if_needed()
     26         return self._state
     27 
     28     @state.setter
     29     def state(self, state):
     30         if state != self.state:
     31             old_state = self.state
     32             self._state = state
     33             self.notify_subscribers(old_state, state)
     34 
     35     @property
     36     def has_subscribers(self):
     37         return len(self._subscribers) > 0
     38 
     39     def mark_need_fetch(self):
     40         self._need_fetch = True
     41 
     42     def notify_subscribers(self, old_state, new_state):
     43         subscribers = self._subscribers
     44         self._subscribers = OrderedDict()
     45         for token, (callback, lens) in subscribers.items():
     46             new_lens_state = lens(new_state)
     47             if lens(old_state) != new_lens_state:
     48                 try:
     49                     callback(new_lens_state)
     50                 except ReferenceError:
     51                     pass
     52 
     53             else:
     54                 self._subscribers[token] = (callback, lens)
     55 
     56     def evolve(self, **kwargs):
     57         self.state = self.state.evolve(**kwargs)
     58 
     59     def read(self):
     60         return self.state
     61 
     62     def watch(self, callback):
     63         return (self.state, self.subscribe(callback))
     64 
     65     def select(self, callback, lens):
     66         return (lens(self.state), self.subscribe(callback, lens))
     67 
     68     def subscribe(self, callback, lens = None):
     69         if lens is None:
     70             lens = lambda s: s
     71         token_id = self._get_next_token_id()
     72         self._subscribers[token_id] = (weakness.callable_proxy(callback), lens)
     73         self._signal_fetch_if_needed()
     74         return SubscriptionToken(self, token_id)
     75 
     76     def unsubscribe(self, token):
     77         if isinstance(token, SubscriptionToken):
     78             token = token.id
     79         try:
     80             del self._subscribers[token]
     81         except (IndexError, KeyError):
     82             pass
     83 
     84     def _signal_fetch_if_needed(self):
     85         if self._need_fetch:
     86             self._need_fetch = False
     87             self.on_fetch_request()
     88 
     89     def _get_next_token_id(self):
     90         token_id = self._next_token_id
     91         self._next_token_id += 1
     92         return token_id
     93 
     94 
     95 class SubscriptionToken(object):
     96 
     97     def __init__(self, provider, token_id):
     98         self.provider = provider
     99         self.id = token_id
    100 
    101     def __del__(self):
    102         self.unsubscribe()
    103 
    104     def unsubscribe(self):
    105         self.provider.unsubscribe(self.id)
    106 
    107 
    108 @codereload.reloadable_enum
    109 
    110 class EssStatus(enum.Enum):
    111     offline = 1
    112     loading = 2
    113     online = 3
    114 
    115 
    116 class EssState(object):
    117     __metaclass__ = immutable.Immutable
    118 
    119     def __init__(self, status, ess_item_id, in_range, main_bank, reserve_bank):
    120         self.status = status
    121         self.ess_item_id = ess_item_id
    122         self.in_range = in_range
    123         self.main_bank = main_bank
    124         self.reserve_bank = reserve_bank
    125 
    126     @property
    127     def online(self):
    128         return self.status == EssStatus.online
    129 
    130     @property
    131     def offline(self):
    132         return self.status == EssStatus.offline
    133 
    134     @property
    135     def loading(self):
    136         return self.status == EssStatus.loading
    137 
    138     @property
    139     def out_of_range(self):
    140         return not self.in_range
    141 
    142     def evolve(self, status = UNCHANGED, ess_item_id = UNCHANGED, in_range = UNCHANGED, main_bank = UNCHANGED, reserve_bank = UNCHANGED):
    143         return EssState(status=changed(status, self.status), ess_item_id=changed(ess_item_id, self.ess_item_id), in_range=changed(in_range, self.in_range), main_bank=changed(main_bank, self.main_bank), reserve_bank=changed(reserve_bank, self.reserve_bank))
    144 
    145     def __eq__(self, other):
    146         return self is other or isinstance(other, EssState) and self.status == other.status and self.ess_item_id == other.ess_item_id and self.in_range == other.in_range and self.main_bank == other.main_bank and self.reserve_bank == other.reserve_bank
    147 
    148     def __ne__(self, other):
    149         return not self.__eq__(other)
    150 
    151     def __hash__(self):
    152         return hash((self.status,
    153          self.ess_item_id,
    154          self.in_range,
    155          self.main_bank,
    156          self.reserve_bank))
    157 
    158     def __repr__(self):
    159         return u'EssState(status={!r}, ess_item_id={!r}, in_range={!r}, main_bank={!r}, reserve_bank={!r})'.format(self.status, self.ess_item_id, self.in_range, self.main_bank, self.reserve_bank)
    160 
    161 
    162 class MainBankState(object):
    163     __metaclass__ = immutable.Immutable
    164 
    165     def __init__(self, balance, link, link_result):
    166         self.balance = balance
    167         self.link = link
    168         self.link_result = link_result
    169 
    170     def is_hacking(self, character_id):
    171         return self.link is not None and self.link.character_id == character_id
    172 
    173     def evolve(self, balance = UNCHANGED, link = UNCHANGED, link_result = UNCHANGED):
    174         return MainBankState(balance=changed(balance, self.balance), link=changed(link, self.link), link_result=changed(link_result, self.link_result))
    175 
    176     def __eq__(self, other):
    177         return self is other or isinstance(other, MainBankState) and self.balance == other.balance and self.link == other.link and self.link_result == other.link_result
    178 
    179     def __ne__(self, other):
    180         return not self.__eq__(other)
    181 
    182     def __hash__(self):
    183         return hash((self.balance, self.link, self.link_result))
    184 
    185     def __repr__(self):
    186         return u'MainBankState(balance={!r}, link={!r}, link_result={!r})'.format(self.balance, self.link, self.link_result)
    187 
    188 
    189 class MainBankLink(object):
    190     __metaclass__ = immutable.Immutable
    191 
    192     def __init__(self, link_id, character_id, start, end):
    193         self.link_id = link_id
    194         self.character_id = character_id
    195         self.start = start
    196         self.end = end
    197 
    198     @property
    199     def remaining(self):
    200         remaining = self.end - gametime.now_sim()
    201         if remaining.total_seconds() < 0.0:
    202             return datetime.timedelta()
    203         return remaining
    204 
    205     @property
    206     def duration(self):
    207         return self.end - self.start
    208 
    209     def evolve(self, link_id = UNCHANGED, character_id = UNCHANGED, start = UNCHANGED, end = UNCHANGED):
    210         return MainBankLink(link_id=changed(link_id, self.link_id), character_id=changed(character_id, self.character_id), start=changed(start, self.start), end=changed(end, self.end))
    211 
    212     def __eq__(self, other):
    213         return self is other or isinstance(other, MainBankLink) and self.link_id == other.link_id and self.character_id == other.character_id and self.start == other.start and self.end == other.end
    214 
    215     def __ne__(self, other):
    216         return not self.__eq__(other)
    217 
    218     def __hash__(self):
    219         return hash((self.link_id,
    220          self.character_id,
    221          self.start,
    222          self.end))
    223 
    224     def __repr__(self):
    225         return u'MainBankLink(link_id={!r}, character_id={!r}, start={!r}, end={!r})'.format(self.link_id, self.character_id, self.start, self.end)
    226 
    227 
    228 class MainBankLinkResult(object):
    229     __metaclass__ = immutable.Immutable
    230 
    231     def __init__(self, link_id, character_id, successful):
    232         self.link_id = link_id
    233         self.character_id = character_id
    234         self.successful = successful
    235 
    236     def evolve(self, link_id = UNCHANGED, character_id = UNCHANGED, successful = UNCHANGED):
    237         return MainBankLinkResult(link_id=changed(link_id, self.link_id), character_id=changed(character_id, self.character_id), successful=changed(successful, self.successful))
    238 
    239     def __eq__(self, other):
    240         return self is other or isinstance(other, MainBankLinkResult) and self.link_id == other.link_id and self.character_id == other.character_id and self.successful == other.successful
    241 
    242     def __ne__(self, other):
    243         return not self.__eq__(other)
    244 
    245     def __hash__(self):
    246         return hash((self.link_id, self.character_id, self.successful))
    247 
    248     def __repr__(self):
    249         return u'MainBankLinkResult(link_id={!r}, character_id={!r}, successful={!r})'.format(self.link_id, self.character_id, self.successful)
    250 
    251 
    252 class ReserveBankState(object):
    253     __metaclass__ = immutable.Immutable
    254 
    255     def __init__(self, balance, pulses_total, pulses_remaining, last_pulse_start, link_count, linked):
    256         self.balance = balance
    257         self.pulses_total = pulses_total
    258         self.pulses_remaining = pulses_remaining
    259         self.last_pulse_start = last_pulse_start
    260         self.link_count = link_count
    261         self.linked = linked
    262 
    263     @property
    264     def locked(self):
    265         return self.pulses_remaining == 0
    266 
    267     @property
    268     def unlocked(self):
    269         return self.pulses_remaining > 0
    270 
    271     def evolve(self, balance = UNCHANGED, pulses_total = UNCHANGED, pulses_remaining = UNCHANGED, last_pulse_start = UNCHANGED, link_count = UNCHANGED, linked = UNCHANGED):
    272         return ReserveBankState(balance=changed(balance, self.balance), pulses_total=changed(pulses_total, self.pulses_total), pulses_remaining=changed(pulses_remaining, self.pulses_remaining), last_pulse_start=changed(last_pulse_start, self.last_pulse_start), link_count=changed(link_count, self.link_count), linked=changed(linked, self.linked))
    273 
    274     def __eq__(self, other):
    275         return self is other or isinstance(other, ReserveBankState) and self.balance == other.balance and self.pulses_total == other.pulses_total and self.pulses_remaining == other.pulses_remaining and self.last_pulse_start == other.last_pulse_start and self.link_count == other.link_count and self.linked == other.linked
    276 
    277     def __ne__(self, other):
    278         return not self.__eq__(other)
    279 
    280     def __hash__(self):
    281         return hash((self.balance,
    282          self.pulses_total,
    283          self.pulses_remaining,
    284          self.last_pulse_start,
    285          self.link_count,
    286          self.linked))
    287 
    288     def __repr__(self):
    289         return u'ReserveBankState(balance={!r}, pulses_total={!r}, pulses_remaining={!r}, last_pulse_start={!r}, link_count={!r}, linked={!r})'.format(self.balance, self.pulses_total, self.pulses_remaining, self.last_pulse_start, self.link_count, self.linked)
    290 
    291 
    292 def changed(value, default):
    293     if value is not UNCHANGED:
    294         return value
    295     return default