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

viewStateSvc.py (26170B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\services\viewStateSvc.py
      2 import math
      3 import blue
      4 import carbonui.const as uiconst
      5 import eveexceptions
      6 import gametime
      7 import localization
      8 import log
      9 import uthread
     10 from billboards import load_billboard_playlist_for_view, unload_billboard_playlist_for_view
     11 from carbon.common.script.sys.service import Service
     12 from carbonui.control.layer import LayerCore
     13 from carbonui.uicore import uicore
     14 from eve.client.script.ui.services.message_bus.viewMessenger import ViewMessenger
     15 from eve.client.script.ui.view import overlaySettings
     16 from eve.client.script.ui.view.viewStateConst import ViewOverlay, is_entering_character_selection, is_entering_game
     17 from eve.common.script.sys.idCheckers import IsTriglavianSystem
     18 from eveprefs import boot
     19 from fsdBuiltData.client.billboards import AreVideosSupportedForView
     20 from globalConfig import BillboardTakeoverEnabled
     21 
     22 def GetViewStateSvc():
     23     return sm.GetService('viewState')
     24 
     25 
     26 class ViewStateError(Exception):
     27     __guid__ = 'viewstate.ViewStateError'
     28 
     29 
     30 class View(object):
     31     __guid__ = 'viewstate.View'
     32     __notifyevents__ = []
     33     __dependencies__ = []
     34     __layerClass__ = LayerCore
     35     __progressMessageLabel__ = None
     36     __subLayers__ = None
     37     __overlays__ = set()
     38     __suppressedOverlays__ = set()
     39     __exclusiveOverlay__ = set()
     40 
     41     def __init__(self):
     42         self.name = None
     43         self.layer = None
     44         self.scene = None
     45         self._dynamicViewType = None
     46 
     47     def GetDynamicViewType(self):
     48         if self._dynamicViewType is None:
     49             raise RuntimeError('View %s was activated without being set to Primary or Secondary' % self.name)
     50         return self._dynamicViewType
     51 
     52     def SetDynamicViewType(self, viewType):
     53         self._dynamicViewType = viewType
     54 
     55     def LoadView(self, **kwargs):
     56         self.LogInfo('LoadView called on view', self.name, 'kwargs', kwargs)
     57 
     58     def UnloadView(self):
     59         self.LogInfo('UnloadView called on view', self.name)
     60 
     61     def ShowView(self, **kwargs):
     62         self.LogInfo('ShowView called on view', self.name, 'with', kwargs)
     63 
     64     def HideView(self):
     65         self.LogInfo('HideView called on view', self.name)
     66 
     67     def ZoomBy(self, amount):
     68         if self.layer:
     69             self.layer.ZoomBy(amount)
     70 
     71     def IsActive(self):
     72         return sm.GetService('viewState').IsViewActive(self.name)
     73 
     74     def GetProgressText(self, **kwargs):
     75         if self.__progressMessageLabel__:
     76             return localization.GetByLabel(self.__progressMessageLabel__)
     77 
     78     def CanEnter(self, **kwargs):
     79         return True
     80 
     81     def CanExit(self):
     82         return True
     83 
     84     def CheckShouldReopen(self, newKwargs, cachedKwargs):
     85         return newKwargs == cachedKwargs
     86 
     87     def LoadCamera(self, cameraID = None, reopen = False):
     88         pass
     89 
     90     def __repr__(self):
     91         return '%s(name=%s)' % (self.__class__.__name__, self.name)
     92 
     93     def LogInfo(self, *args, **kwargs):
     94         sm.GetService('viewState').LogInfo(self, *args, **kwargs)
     95 
     96     def LogWarn(self, *args, **kwargs):
     97         sm.GetService('viewState').LogWarn(self, *args, **kwargs)
     98 
     99     def LogError(self, *args, **kwargs):
    100         sm.GetService('viewState').LogError(self, *args, **kwargs)
    101 
    102 
    103 class Transition(object):
    104     __guid__ = 'viewstate.Transition'
    105 
    106     def __init__(self, allowReopen = True, fallbackView = None):
    107         self.allowReopen = allowReopen
    108         self.fallbackView = fallbackView
    109         self.transitionReason = None
    110         self.animatedOut = set()
    111 
    112     def StartTransition(self, fromView, toView):
    113         sm.GetService('viewState').LogInfo('Transition starting for', fromView, 'to', toView, '(' + self.__class__.__name__ + ')')
    114 
    115     def EndTransition(self, fromView, toView):
    116         sm.GetService('viewState').LogInfo('Transition ending for', fromView, 'to', toView)
    117         self.transitionReason = None
    118 
    119     def IsActive(self):
    120         return self.active
    121 
    122     def SetTransitionReason(self, reason, allowOverwrite = False):
    123         if reason is None or self.transitionReason is not None and not allowOverwrite:
    124             return
    125         self.transitionReason = reason
    126 
    127     def AnimateUIIn(self, duration = 2):
    128         uthread.new(self._AnimateUIIn, duration)
    129 
    130     def _AnimateUIIn(self, duration = 2):
    131         curveSet = None
    132         for layer, doSleep in ((uicore.layer.main, False), (uicore.layer.viewstate, True)):
    133             if layer in self.animatedOut:
    134                 layer.display = True
    135                 self.animatedOut.remove(layer)
    136             uicore.animations.FadeIn(layer, curveSet=curveSet, duration=duration, sleep=doSleep)
    137 
    138         self.animatedOut = set()
    139 
    140     def AnimateUIOut(self, duration = 0.5):
    141         uthread.new(self._AnimateUIOut, duration)
    142 
    143     def _AnimateUIOut(self, duration = 0.5):
    144         curveSet = None
    145         myCallback = lambda : self.FadeOutEndCallback(uicore.layer.main)
    146         uicore.animations.FadeOut(uicore.layer.main, duration=duration, curveSet=curveSet, callback=myCallback)
    147         myCallback = lambda : self.FadeOutEndCallback(uicore.layer.viewstate)
    148         uicore.animations.FadeOut(uicore.layer.viewstate, duration=duration, sleep=True, curveSet=curveSet, callback=myCallback)
    149 
    150     def FadeOutEndCallback(self, layer, *args):
    151         if layer.display:
    152             self.animatedOut.add(layer)
    153             layer.display = False
    154 
    155     def GetCameraID(self):
    156         return None
    157 
    158 
    159 class ViewType:
    160     __guid__ = 'viewstate.ViewType'
    161     Primary = 0
    162     Secondary = 1
    163     Dynamic = 2
    164 
    165 
    166 class ViewInfo(object):
    167     __guid__ = 'viewstate.ViewInfo'
    168 
    169     def __init__(self, name, view, viewType = ViewType.Primary):
    170         self.name = name
    171         self.view = view
    172         self.viewType = viewType
    173         self.entryArguments = None
    174 
    175     def GetViewType(self):
    176         if self.viewType == ViewType.Dynamic:
    177             return self.view.GetDynamicViewType()
    178         else:
    179             return self.viewType
    180 
    181     def IsPrimary(self):
    182         return self.GetViewType() == ViewType.Primary
    183 
    184     def IsSecondary(self):
    185         return self.GetViewType() == ViewType.Secondary
    186 
    187     def __repr__(self):
    188         return 'ViewInfo(view=%s type=%d)' % (self.view, self.viewType)
    189 
    190 
    191 class ViewStateSvc(Service):
    192     __guid__ = 'svc.viewState'
    193     __servicename__ = 'view state manager'
    194     __displayname__ = 'View State Manager'
    195     __notifyevents__ = ['OnShowUI']
    196     __dependencies__ = ['loading']
    197 
    198     def Run(self, memStream = None):
    199         self.viewLayerParent = None
    200         self.viewInfosByName = {}
    201         self.transitionsByNames = {}
    202         self.overlaysByName = {}
    203         self.overlayLayerParent = None
    204         self.primaryInfo = None
    205         self.secondaryInfo = None
    206         self.activeViewInfo = None
    207         self.activeTransition = None
    208         self.isOpeningView = None
    209         self.lastViewOpenTime = None
    210         self.initialized = False
    211 
    212     def Initialize(self, viewLayerParent):
    213         self.viewLayerParent = viewLayerParent
    214         self.overlayLayerParent = self.viewLayerParent.AddLayer('l_view_overlays', LayerCore)
    215         self.lastViewOpenTime = blue.os.GetWallclockTime()
    216         self.initialized = True
    217 
    218     def ActivateView(self, name, **kwargs):
    219         self.LogInfo('Activating view', name, 'with key words', kwargs)
    220         transitionFailed = False
    221         if self.isOpeningView is not None:
    222             self.LogInfo("Can't activate view", name, '. already busy opening view', self.isOpeningView)
    223             return
    224         self.isOpeningView = name
    225         error = None
    226         try:
    227             newInfo = self.GetViewInfo(name)
    228             oldInfo = self.secondaryInfo or self.primaryInfo
    229             if newInfo.viewType == ViewType.Dynamic:
    230                 if self.primaryInfo is None:
    231                     newInfo.view.SetDynamicViewType(ViewType.Primary)
    232                 else:
    233                     newInfo.view.SetDynamicViewType(ViewType.Secondary)
    234             transition = self.GetTransition(oldInfo, newInfo)
    235             if transition is None and oldInfo is not None and newInfo.name == oldInfo.name:
    236                 self.LogInfo('No valid transition found for view', name, 'to view', name, '. Skipping since it is is already active')
    237             else:
    238                 if oldInfo:
    239                     try:
    240                         if not oldInfo.view.CanExit():
    241                             oldInfo.view.LogInfo('Unable to exit view at present')
    242                             return False
    243                     except:
    244                         log.LogException()
    245 
    246                 try:
    247                     if not newInfo.view.CanEnter(**kwargs):
    248                         newInfo.view.LogInfo('Unable to enter view now. Arguments:', kwargs)
    249                         return False
    250                 except:
    251                     log.LogException()
    252 
    253                 viewOpenTime = blue.os.GetWallclockTime()
    254                 self.activeTransition = transition
    255                 oldViewName = oldInfo.name if oldInfo else None
    256                 newViewName = newInfo.name
    257                 sm.ScatterEvent('OnBeforeViewStateChanged', oldViewName, newViewName)
    258                 try:
    259                     self.activeTransition.StartTransition(oldInfo.view if oldInfo else None, newInfo.view)
    260                     cameraID = self.activeTransition.GetCameraID()
    261                 except:
    262                     cameraID = None
    263                     log.LogException()
    264 
    265                 progressText = newInfo.view.GetProgressText(**kwargs)
    266                 if progressText:
    267                     sm.GetService('loading').ProgressWnd(progressText, '', 1, 2)
    268                 reopen = False
    269                 if newInfo.GetViewType() == ViewType.Secondary:
    270                     if self.secondaryInfo:
    271                         reopen = self.activeTransition.allowReopen and newInfo == self.secondaryInfo
    272                         if reopen:
    273                             try:
    274                                 reopen = newInfo.view.CheckShouldReopen(kwargs, newInfo.entryArguments)
    275                             except:
    276                                 log.LogException()
    277                                 reopen = False
    278 
    279                         self._CloseView(self.secondaryInfo, unload=not reopen)
    280                     else:
    281                         self._CloseView(self.primaryInfo, unload=False)
    282                 else:
    283                     if self.secondaryInfo:
    284                         self._CloseView(self.secondaryInfo)
    285                     if self.primaryInfo:
    286                         if self.activeTransition.allowReopen and newInfo == self.primaryInfo:
    287                             try:
    288                                 self.primaryInfo.view.CheckShouldReopen(kwargs, newInfo.entryArguments)
    289                                 reopen = True
    290                             except:
    291                                 log.LogException()
    292 
    293                             self._CloseView(self.primaryInfo, unload=False)
    294                         else:
    295                             self._CloseView(self.primaryInfo)
    296                 self.activeViewInfo = newInfo
    297                 uthread.new(sm.GetService('audio').LoadBanksForView, newInfo.name)
    298                 if newInfo.GetViewType() == ViewType.Primary:
    299                     self._PrepareBillboards(newInfo, oldInfo)
    300                     self._OpenPrimaryView(newInfo, reopen=reopen, cameraID=cameraID, **kwargs)
    301                 else:
    302                     self._OpenView(newInfo, reopen=reopen, cameraID=cameraID, **kwargs)
    303                 self.UpdateOverlays()
    304                 if progressText is not None:
    305                     sm.GetService('loading').ProgressWnd(progressText, '', 2, 2)
    306                 try:
    307                     transitionFailed = self.activeTransition.EndTransition(oldInfo, newInfo)
    308                 except:
    309                     log.LogException()
    310 
    311                 self._LogViewActivated()
    312                 if oldInfo:
    313                     integer, fractions = self.GetSplitTimeFromTimestamp(self.lastViewOpenTime)
    314                     self._LogViewDeactivated(oldInfo.name, int(integer), int(fractions))
    315                 self.lastViewOpenTime = viewOpenTime
    316                 if newInfo.GetViewType() == ViewType.Primary:
    317                     sm.ScatterEvent('OnClientReady', newInfo.name)
    318                 self.LogInfo('View', name, 'was activated')
    319                 self._NotifyOfViewStateChange(oldViewName, newViewName)
    320         except eveexceptions.UserError as e:
    321             self.LogInfo('UserError raised while making a transition. UserError', e)
    322             if newInfo.GetViewType() == ViewType.Secondary:
    323                 error = e
    324             else:
    325                 raise RuntimeError('UserError raised while transitioning from %s to %s UserError: %s' % (oldInfo, newInfo, e))
    326         finally:
    327             self.isOpeningView = None
    328             if transitionFailed:
    329                 self.ActivateView(self.activeTransition.fallbackView, **kwargs)
    330             self.activeTransition = None
    331             sm.GetService('loading').HideAllLoad()
    332 
    333         if error:
    334             self.LogInfo('Trying to re-enter primary view', self.primaryInfo.name, 'using cached entry arguments', self.primaryInfo.entryArguments)
    335             uthread.new(self.ActivateView, self.primaryInfo.name, **self.primaryInfo.entryArguments).context = 'viewStateSvc::AttemptToRecoverFromUserError'
    336             raise error
    337         return True
    338 
    339     def _NotifyOfViewStateChange(self, old_state, new_state):
    340         sm.ScatterEvent('OnViewStateChanged', old_state, new_state)
    341         if is_entering_character_selection(new_state):
    342             sm.ScatterEvent('OnCharacterSelectionViewEntered')
    343         elif is_entering_game(old_state, new_state):
    344             sm.ScatterEvent('OnGameViewEntered')
    345 
    346     def GetSplitTimeFromTimestamp(self, timestamp):
    347         if not timestamp:
    348             return
    349         secondsSinceTimestamp = gametime.GetSecondsSinceWallclockTime(timestamp)
    350         fractions, integer = math.modf(secondsSinceTimestamp)
    351         return (integer, fractions * 1000000000.0)
    352 
    353     @eveexceptions.EatsExceptions('protoClientLogs')
    354     def _LogViewActivated(self):
    355         message_bus = ViewMessenger(sm.GetService('publicGatewaySvc'))
    356         message_bus.view_activated(self.activeViewInfo.name)
    357 
    358     @eveexceptions.EatsExceptions('protoClientLogs')
    359     def _LogViewDeactivated(self, view_name, seconds_active, nanoseconds_active):
    360         message_bus = ViewMessenger(sm.GetService('publicGatewaySvc'))
    361         message_bus.view_deactivated(view_name, seconds_active, nanoseconds_active)
    362 
    363     def _PrepareBillboards(self, newInfo, oldInfo):
    364         if oldInfo:
    365             unload_billboard_playlist_for_view(oldInfo.name)
    366         if AreVideosSupportedForView(newInfo.name):
    367             locale = str(blue.os.languageID.lower())
    368             if boot.role == 'optic':
    369                 locale = 'zh'
    370             videoOverrides = {}
    371             if IsTriglavianSystem(session.solarsystemid2):
    372                 videoOverrides['triglavianOvertaken'] = True
    373             else:
    374                 videoOverrides['triglavianInvasion'] = BillboardTakeoverEnabled(sm.GetService('machoNet'))
    375             load_billboard_playlist_for_view(newInfo.name, locale, **videoOverrides)
    376 
    377     def StartDependantServices(self, viewInfo):
    378         for serviceName in viewInfo.view.__dependencies__:
    379             setattr(viewInfo.view, serviceName, sm.StartServiceAndWaitForRunningState(serviceName))
    380             self.LogInfo('Dependant service', serviceName, 'has started')
    381 
    382         self.LogInfo('All dependant services started for view', viewInfo.name)
    383 
    384     def _OpenPrimaryView(self, viewInfo, reopen = False, cameraID = None, **kwargs):
    385         blue.SetCrashKeyValues('ViewState', viewInfo.name)
    386         blue.statistics.SetTimelineSectionName(viewInfo.name)
    387         self._OpenView(viewInfo, reopen=reopen, cameraID=cameraID, **kwargs)
    388 
    389     def _OpenView(self, viewInfo, reopen = False, cameraID = None, **kwargs):
    390         self.LogInfo('Re-open view' if reopen else 'Opening view', viewInfo, 'with kwargs', kwargs)
    391         self.StartDependantServices(viewInfo)
    392         showView = True
    393         oldView = self.primaryInfo
    394         if viewInfo.GetViewType() == ViewType.Primary:
    395             if self.activeViewInfo.GetViewType() == ViewType.Secondary:
    396                 showView = False
    397             self.primaryInfo = viewInfo
    398             sm.ScatterEvent('OnPrimaryViewChanged', oldView, self.primaryInfo)
    399         else:
    400             self.secondaryInfo = viewInfo
    401         try:
    402             if showView:
    403                 self.LogInfo('Opening layer', viewInfo.view.layer.name)
    404                 viewInfo.view.layer.OpenView(**kwargs)
    405                 viewInfo.view.layer.pickState = uiconst.TR2_SPS_ON
    406                 viewInfo.view.layer.display = True
    407             else:
    408                 self.LogInfo('Changing the primary layer while a secondary view', self.activeViewInfo.name, 'is active')
    409         except:
    410             log.LogException()
    411 
    412         try:
    413             if reopen:
    414                 self.LogInfo('View', viewInfo.name, 'is being re-opened')
    415             else:
    416                 self.LogInfo('View', viewInfo.name, 'is being loaded.')
    417                 viewInfo.view.LoadView(**dict(lastView=oldView, **kwargs))
    418             if showView:
    419                 self.LogInfo('Showing view', viewInfo.name)
    420                 viewInfo.view.ShowView(**kwargs)
    421             viewInfo.view.LoadCamera(cameraID, reopen)
    422         except:
    423             log.LogException()
    424 
    425         sm.RegisterNotify(viewInfo.view)
    426         sm.ScatterEvent('OnViewLoaded', oldView, self.primaryInfo)
    427         viewInfo.entryArguments = kwargs
    428         self.LogInfo('view', viewInfo, 'opened')
    429 
    430     def _CloseView(self, viewInfo, unload = True):
    431         try:
    432             viewInfo.view.layer.CloseView(recreate=False)
    433         except:
    434             log.LogException()
    435 
    436         viewInfo.view.layer.display = False
    437         try:
    438             viewInfo.view.HideView()
    439             if unload:
    440                 sm.UnregisterNotify(viewInfo.view)
    441                 viewInfo.view.UnloadView()
    442                 self.LogInfo('Unloading view', viewInfo.name)
    443         except:
    444             log.LogException()
    445 
    446         if viewInfo.GetViewType() == ViewType.Primary:
    447             if unload:
    448                 viewInfo.entryArguments = None
    449         else:
    450             self.secondaryInfo = None
    451         sm.ScatterEvent('OnViewClosed', viewInfo.name)
    452 
    453     def ChangePrimaryView(self, name, **kwargs):
    454         self.LogInfo('ChangePrimaryView', name)
    455         while self.isOpeningView:
    456             blue.pyos.synchro.Yield()
    457 
    458         if self.secondaryInfo:
    459             if (self.secondaryInfo.name, name) not in self.transitionsByNames:
    460                 raise ViewStateError('Changing primary view to %s from current active secondary view %s will leave the viewStateSvc in an undefined state' % (name, self.secondaryInfo.name))
    461             viewInfo = self.GetViewInfo(name)
    462             self._CloseView(self.primaryInfo)
    463             self._OpenView(viewInfo, **kwargs)
    464             self.UpdateOverlays()
    465         else:
    466             return self.ActivateView(name, **kwargs)
    467 
    468     def GetTransition(self, oldInfo, newInfo):
    469         oldViewName = oldInfo.name if oldInfo else None
    470         transition = self.transitionsByNames.get((oldViewName, newInfo.name))
    471         if transition is None:
    472             transition = self.transitionsByNames.get((None, newInfo.name))
    473         if transition is None:
    474             raise ViewStateError('There is not a valid transition from %s to %s' % (oldViewName, newInfo.name))
    475         self.LogInfo('Found transition from', oldViewName, 'to', newInfo.name)
    476         return transition
    477 
    478     def GetTransitionByName(self, fromName, toName):
    479         if (fromName, toName) in self.transitionsByNames:
    480             return self.transitionsByNames[fromName, toName]
    481 
    482     def GetView(self, name):
    483         return self.GetViewInfo(name).view
    484 
    485     def HasView(self, name):
    486         return name in self.viewInfosByName
    487 
    488     def GetViewInfo(self, name):
    489         try:
    490             return self.viewInfosByName[name]
    491         except KeyError:
    492             raise ViewStateError('There is no view registered by the name %s' % name)
    493 
    494     def GetCurrentViewInfo(self):
    495         return self.activeViewInfo
    496 
    497     def GetCurrentView(self):
    498         return getattr(self.activeViewInfo, 'view', None)
    499 
    500     def IsInitialized(self):
    501         return self.initialized
    502 
    503     def IsViewActive(self, *names):
    504         return getattr(self.activeViewInfo, 'name', None) in names
    505 
    506     def IsPrimaryViewActive(self, *names):
    507         return getattr(self.primaryInfo, 'name', None) in names
    508 
    509     def GetActiveViewName(self):
    510         return getattr(self.activeViewInfo, 'name', None)
    511 
    512     def HasActiveTransition(self):
    513         if self.activeTransition is not None:
    514             return True
    515         else:
    516             return False
    517 
    518     def AddView(self, name, view, viewType = ViewType.Primary):
    519         self.LogInfo('Adding view', name, view, viewType)
    520         view.name = name
    521         info = ViewInfo(name, view, viewType)
    522         view.layer = self.viewLayerParent.AddLayer('l_%s' % name, view.__layerClass__, view.__subLayers__)
    523         view.layer.state = uiconst.UI_HIDDEN
    524         self.viewInfosByName[name] = info
    525 
    526     def AddTransition(self, fromName, toName, transition = Transition()):
    527         self.LogInfo('Adding transition', fromName or '[All]', toName, transition)
    528         self.transitionsByNames[fromName, toName] = transition
    529 
    530     def AddTransitions(self, fromNames, toNames, transition = Transition()):
    531         for fromName in fromNames:
    532             for toName in toNames:
    533                 self.AddTransition(fromName, toName, transition)
    534 
    535     def GetPrimaryView(self):
    536         try:
    537             return self.primaryInfo.view
    538         except AttributeError:
    539             raise ViewStateError('There is no primary view set')
    540 
    541     def CloseSecondaryView(self, name = None):
    542         while self.isOpeningView:
    543             blue.pyos.synchro.Yield()
    544 
    545         if self.secondaryInfo is None:
    546             self.LogInfo("Can't close secondary view since none is active")
    547         else:
    548             if name is None or self.activeViewInfo.name == name:
    549                 self.LogInfo('closing secondary view', self.secondaryInfo.name)
    550                 args = self.primaryInfo.entryArguments if self.primaryInfo.entryArguments is not None else dict()
    551                 return self.ActivateView(self.primaryInfo.name, **args)
    552             self.LogInfo('The secondary view', name, 'was not closed as is not active')
    553 
    554     def ToggleSecondaryView(self, name, **kwargs):
    555         self.LogInfo('Toggling view', name)
    556         while self.isOpeningView:
    557             blue.pyos.synchro.Yield()
    558 
    559         info = self.GetViewInfo(name)
    560         if info.GetViewType() != ViewType.Secondary:
    561             raise RuntimeError('You can only toggle secondary views (tools)')
    562         if self.IsViewActive(name):
    563             return self.CloseSecondaryView(name)
    564         else:
    565             return self.ActivateView(name, **kwargs)
    566 
    567     def IsCurrentViewPrimary(self):
    568         return self.activeViewInfo.GetViewType() == ViewType.Primary
    569 
    570     def IsCurrentViewSecondary(self):
    571         activeViewInfo = getattr(self, 'activeViewInfo', None)
    572         if activeViewInfo:
    573             return activeViewInfo.GetViewType() == ViewType.Secondary
    574         else:
    575             return False
    576 
    577     def AddOverlay(self, name, overlayClass, subLayers = None):
    578         if name not in self.overlaysByName:
    579             overlay = self.overlayLayerParent.AddLayer('l_%s' % name, overlayClass, subLayers)
    580             overlay.display = False
    581             self.overlaysByName[name] = overlay
    582 
    583     def UpdateOverlays(self, forcedUpdateOnOverlays = ()):
    584         activeOverlays = self._GetOverlaysToEnable()
    585         self.LogInfo('Overlays to enable', activeOverlays)
    586         for name, overlay in self.overlaysByName.items():
    587             try:
    588                 if name in activeOverlays or name in self.activeViewInfo.view.__exclusiveOverlay__:
    589                     if overlay in forcedUpdateOnOverlays:
    590                         overlay.CloseView(recreate=False)
    591                     overlay.OpenView()
    592                     overlay.display = True
    593                     sm.ScatterEvent('OnOverlayActivated', name)
    594                     self.LogInfo('Overlay', name, 'activated')
    595                 else:
    596                     overlay.display = False
    597                     overlay.CloseView(recreate=False)
    598                     self.overlaysByName[name] = uicore.layer.Get(name)
    599                     sm.ScatterEvent('OnOverlayClosed', name)
    600                     self.LogInfo('Overlay', name, 'closed')
    601             except:
    602                 log.LogException()
    603 
    604         if sm.GetService('ui').IsUISuppressed():
    605             sm.GetService('ui').SuppressUI()
    606 
    607     def _GetOverlaysToEnable(self):
    608         activeOverlays = self.primaryInfo.view.__overlays__.copy()
    609         if self.secondaryInfo:
    610             activeOverlays.update(self.secondaryInfo.view.__overlays__)
    611         activeOverlays.difference_update(self.primaryInfo.view.__suppressedOverlays__)
    612         if self.secondaryInfo:
    613             activeOverlays.difference_update(self.secondaryInfo.view.__suppressedOverlays__)
    614             activeOverlays.difference_update(overlaySettings.GetOverlaysDisabledInFullscreen())
    615         return activeOverlays
    616 
    617     def SafeLogoffInProgress(self):
    618         shipUI = self.overlaysByName.get(ViewOverlay.ShipUI, None)
    619         if shipUI is None or shipUI.destroyed:
    620             return False
    621         logoffTimer = getattr(shipUI, 'logoffTimer', None)
    622         if logoffTimer is None or logoffTimer.destroyed:
    623             return False
    624         return logoffTimer.IsVisible()
    625 
    626     def SetTransitionReason(self, fromName, toName, reason):
    627         self.LogInfo('Adding transition reason ', fromName or '[All]', toName, reason)
    628         self.transitionsByNames[fromName, toName].SetTransitionReason(reason)
    629 
    630     def GetActiveTransitionReason(self):
    631         if self.activeTransition is None:
    632             return
    633         return self.activeTransition.transitionReason
    634 
    635     def GetActiveTransition(self):
    636         return self.activeTransition
    637 
    638     def OnShowUI(self):
    639         if sm.GetService('ui').IsUiVisible():
    640             self.UpdateOverlays()