class _PreBattleDispatcher(ListenersCollection): """ Dispatcher is a class that handles all actions from player related to prebattles: select, join, create, etc. Also dispatcher itself is a listeners collection that is used for global listening of prebattle events. """ gameSession = dependency.descriptor(IGameSessionController) rentals = dependency.descriptor(IRentalsController) igrCtrl = dependency.descriptor(IIGRController) falloutCtrl = dependency.descriptor(IFalloutController) eventsCache = dependency.descriptor(IEventsCache) def __init__(self): """ In init we're setting default request context, factories composite default entity and supported listeners class. """ super(_PreBattleDispatcher, self).__init__() self.__requestCtx = PrbCtrlRequestCtx() self.__factories = ControlFactoryComposite() self.__entity = NotSupportedEntity() self.__prevEntity = NotSupportedEntity() self._setListenerClass(IGlobalListener) def __del__(self): """ Just a mark for logs that shows us when dispatcher was deleted. """ LOG_DEBUG('_PreBattleDispatcher deleted') def start(self): """ Start is called when dispatcher should start its job and process events. """ g_eventDispatcher.init(self) result = self.__setDefault() self.__startListening() initDevFunctional() if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0: g_eventDispatcher.loadHangar() if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden( ): g_eventDispatcher.addSpecBattlesToCarousel() def stop(self): """ Is called when its time to stop dispatchers work. """ self.__stopListening() finiDevFunctional() self.__clear(woEvents=True) g_eventDispatcher.fini() def getEntity(self): """ Getter for current entity. Returns: current prebattle entity """ return self.__entity def getControlFactories(self): """ Getter for factories composite. Returns: control factories """ return self.__factories def getFunctionalState(self): """ Gets current functional state. Returns: current functional state """ factory = self.__factories.get(self.__entity.getCtrlType()) if factory is not None: return factory.createStateEntity(self.__entity) else: return FunctionalState() @async @process def create(self, ctx, callback=None): """ Asynchronous method for prebattle creation. Using given context its creates entry point via factories and uses it to create new prebattle. Current entity will be destroyed. Args: ctx: creation context callback: request callback """ if ctx.getRequestType() != _RQ_TYPE.CREATE: LOG_ERROR('Invalid context to create prebattle/unit', ctx) if callback is not None: callback(False) return else: entry = self.__factories.createEntry(ctx) if entry is None: LOG_ERROR('Entry not found', ctx) if callback is not None: callback(False) return if not entry.canCreate(): if callback is not None: callback(False) return ctx.addFlags(entry.getFunctionalFlags() | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to create', ctx) self.__requestCtx = ctx entry.create(ctx, callback=callback) return @async @process def join(self, ctx, callback=None): """ Asynchronous method for prebattle joining. Using given context its creates entry point via factories and uses it to join another prebattle. Current entity will be destroyed. Args: ctx: join context callback: request callback """ if ctx.getRequestType() != _RQ_TYPE.JOIN: LOG_ERROR('Invalid context to join prebattle/unit', ctx) if callback is not None: callback(False) return else: entry = self.__factories.createEntry(ctx) if entry is None: LOG_ERROR('Entry not found', ctx) if callback is not None: callback(False) return if not entry.canJoin(): if callback is not None: callback(False) return ctx.addFlags(entry.getFunctionalFlags() | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to join', ctx) self.__requestCtx = ctx entry.join(ctx, callback=callback) return @async @process def leave(self, ctx, callback=None): """ Asynchronous method for prebattle leaving. Using given context its leaves current entity. Args: ctx: leave context callback: request callback """ if ctx.getRequestType() != _RQ_TYPE.LEAVE: LOG_ERROR('Invalid context to leave prebattle/unit', ctx) if callback is not None: callback(False) return elif self.__requestCtx.isProcessing(): LOG_ERROR('Request is processing', self.__requestCtx) if callback is not None: callback(False) return else: entity = self.__entity meta = entity.getConfirmDialogMeta(ctx) if meta: result = yield DialogsInterface.showDialog(meta) if not result: if callback is not None: callback(False) return if not entity.isActive(): if callback is not None: callback(False) return ctrlType = ctx.getCtrlType() if entity.hasLockedState(): entityType = entity.getEntityType() SystemMessages.pushI18nMessage( messages.getLeaveDisabledMessage(ctrlType, entityType), type=SystemMessages.SM_TYPE.Warning) if callback is not None: callback(False) return LOG_DEBUG('Request to leave formation', ctx) self.__requestCtx = ctx entity.leave(ctx, callback=callback) return @async @process def unlock(self, unlockCtx, callback=None): """ Asynchronous method to leave from prebattle if player is in formation and shows confirmation dialog. Args: unlockCtx: unlock context callback: request callback """ if isinstance(self.__entity, NotSupportedEntity): if callback is not None: callback(True) return else: state = self.getFunctionalState() ctrlType = state.ctrlTypeID factory = self.__factories.get(ctrlType) if factory is None: LOG_ERROR('Factory is not found', state) if callback is not None: callback(True) return ctx = factory.createLeaveCtx(unlockCtx.getFlags(), self.__entity.getEntityType()) result = yield self.leave(ctx) if callback is not None: callback(result) return @async @process def select(self, entry, callback=None): """ Asynchronous method to select prebattle mode and leave current mode if given entry is not just visual. Args: entry: newly selected entry point callback: request callback """ ctx = entry.makeDefCtx() ctx.addFlags(entry.getModeFlags() & FUNCTIONAL_FLAG.LOAD_PAGE | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return else: if entry.isVisualOnly(): result = True else: result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to select', ctx) self.__requestCtx = ctx entry.select(ctx, callback=callback) return @async def sendPrbRequest(self, ctx, callback=None): """ Asynchronous method for send request to prebattle. Args: ctx: request context callback: request callback """ self.__entity.request(ctx, callback=callback) def getPlayerInfo(self): """ Gets information of player (is creator, is ready, etc.) in current active entity. Returns: current player info """ factory = self.__factories.get(self.__entity.getCtrlType()) if factory is not None: return factory.createPlayerInfo(self.__entity) else: return PlayerDecorator() def doAction(self, action=None): """ Processes action that comes from GUI by current entity. Args: action: given player's action Returns: was this action successful """ if not g_currentVehicle.isPresent(): SystemMessages.pushMessage(messages.getInvalidVehicleMessage( PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT), type=SystemMessages.SM_TYPE.Error) return False LOG_DEBUG('Do GUI action', action) return self.__entity.doAction(action) @async @process def doSelectAction(self, action, callback=None): """ Processes action that comes from GUI to change to another mode. Args: action: given player's select action callback: request callback """ selectResult = self.__entity.doSelectAction(action) if selectResult.isProcessed: result = True if selectResult.newEntry is not None: result = yield self.select(selectResult.newEntry) if callback is not None: callback(result) return else: entry = self.__factories.createEntryByAction(action) if entry is not None: result = yield self.select(entry) if callback is not None: callback(result) return if callback is not None: callback(False) return @async @process def doLeaveAction(self, action, callback=None): """ Processes action that comes from GUI to leave current mode. Args: action: given player's leave action callback: callback function or None """ factory = self.__factories.get(self.__entity.getCtrlType()) if factory is None: LOG_ERROR('Factory is not found', self.__entity) if callback is not None: callback(True) return else: flags = FUNCTIONAL_FLAG.UNDEFINED if action.isExit: flags = FUNCTIONAL_FLAG.EXIT elif self.__entity.canKeepMode(): flags = self.__entity.getModeFlags() ctx = factory.createLeaveCtx( flags, entityType=self.__entity.getEntityType()) if self.__entity.isInCoolDown(ctx.getRequestType()): if callback is not None: callback(True) return self.__entity.setCoolDown(ctx.getRequestType(), ctx.getCooldown()) result = yield self.leave(ctx) if callback is not None: callback(result) return def getGUIPermissions(self): """ Gets available action in GUI for current player. Returns: current GUI permissions """ return self.__entity.getPermissions() def isRequestInProcess(self): """ Is current request in process. Returns: is request in process now """ return self.__requestCtx.isProcessing() def restorePrevious(self): """ Trying to set current entity to previous. Returns: initialization result as flags """ return self.__setEntity( CreatePrbEntityCtx(self.__prevEntity.getCtrlType(), self.__prevEntity.getEntityType(), flags=self.__prevEntity.getFunctionalFlags())) def pe_onArenaCreated(self): """ Player event listener for arena creation. Updates UI. """ if self.__entity.hasLockedState(): g_eventDispatcher.updateUI() def pe_onArenaJoinFailure(self, errorCode, errorStr): """ Player event listener for arena join failure. Pushes system message. Args: errorCode: join error code errorStr: join error message """ SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error) def pe_onKickedFromArena(self, reasonCode): """ Player event listener for arena kick. Resets state and pushes system message. Args: reasonCode: kick reason code """ self.__entity.resetPlayerState() SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode), type=SystemMessages.SM_TYPE.Error) def pe_onPrebattleAutoInvitesChanged(self): """ Player event listener for autoinvites state. Controls chat tab visibility of spec battles and updates UI. """ if GUI_SETTINGS.specPrebatlesVisible: isHidden = prb_getters.areSpecBattlesHidden() if isHidden: g_eventDispatcher.removeSpecBattlesFromCarousel() else: g_eventDispatcher.addSpecBattlesToCarousel() g_eventDispatcher.updateUI() def pe_onPrebattleInviteError(self, inviteID, errorCode, errorStr): """ Player event listener for prebattle invitation failed. Resets current entity to default. """ self.__unsetEntity() self.__setDefault() def pe_onPrebattleJoined(self): """ Player event listener for prebattle join. Sets entity to proper legacy or resets to default. """ if prb_getters.getClientPrebattle() is not None: self.__setLegacy(self.__requestCtx.getFlags()) else: LOG_ERROR('ClientPrebattle is not defined') self.__setDefault() g_eventDispatcher.loadHangar() return def pe_onPrebattleJoinFailure(self, errorCode): """ Player event listener for prebattle join filure. Pushes system message and resets current entity to default. Args: errorCode: join error code """ SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error) self.__setDefault() g_eventDispatcher.loadHangar() def pe_onPrebattleLeft(self): """ Player event listener for prebattle left. Tries to keep current mode or just unsets current entity. """ flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: prbType = self.__entity.getEntityType() self.__unsetEntity(self.__requestCtx) self.__setLegacy(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def pe_onKickedFromPrebattle(self, kickReason): """ Player event listener for prebattle kick. Resets current entity to default. """ self.__unsetEntity() self.__setDefault() def ctrl_onLegacyIntroModeJoined(self, prbType): """ Prebattle control events listener for legacy intro join. Sets new legacy entity. Args: prbType: joined prebattle type """ self.__setLegacy(flags=self.__requestCtx.getFlags(), prbType=prbType) def ctrl_onLegacyIntroModeLeft(self): """ Prebattle control events listener for legacy intro leave. Unsets current legacy entity and inits default state if it is not switch. """ flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def ctrl_onLegacyInited(self): """ Prebattle control events listener for legacy init. Sets new legacy entity. """ self.__setLegacy(flags=self.__requestCtx.getFlags()) def ctrl_onUnitIntroModeJoined(self, prbType, flags): """ Prebattle control events listener for unit intro mode join. Sets new unit entity. Args: prbType: intro prebattle type flags: functional flags """ self.__setUnit(flags=flags, prbType=prbType) def ctrl_onUnitBrowserModeLeft(self, prbType): """ Prebattle control events listener for unit browser mode leave. Unsets current unit entity and tries to init intro mode if it is not switch. Args: prbType: intro prebattle type """ flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: unitEntity = self.__entity if unitEntity.canKeepMode(): prbType = unitEntity.getIntroType() flags |= unitEntity.getModeFlags() self.__unsetEntity(self.__requestCtx) self.__setUnit(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def ctrl_onUnitIntroModeLeft(self): """ Prebattle control events listener for unit intro leave. Unsets current unit entity and inits default state if it is not switch. """ flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def unitMgr_onUnitJoined(self, unitMgrID, prbType): """ Unit manager event listener for unit join. Sets unit entity if we're not already joined to it. Args: unitMgrID: unit manager identifier prbType: unit prebattle type """ entity = self.__entity ctx = JoinUnitCtx(unitMgrID, prbType) if entity.isPlayerJoined(ctx): entity.rejoin() else: self.__setUnit(flags=self.__requestCtx.getFlags(), prbType=self.__requestCtx.getEntityType()) def unitMgr_onUnitLeft(self, unitMgrID): """ Unit manager listener for unit left. Tries to keep current mode or just unsets current entity. Args: unitMgrID: unit manager identifier """ flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: unitEntity = self.__entity if unitEntity.canKeepMode(): prbType = unitEntity.getEntityType() flags |= unitEntity.getModeFlags( ) | FUNCTIONAL_FLAG.UNIT_BROWSER self.__unsetEntity(self.__requestCtx) self.__setUnit(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def unitMgr_onUnitRestored(self, unitMgrID): """ Unit manager event listener for unit restoration. Args: unitMgrID: unit manager identifier """ self.__entity.restore() def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, errorCode, errorString): """ Unit manager event listener for unit request error. Pushes system message. Args: requestID: request identifier unitMgrID: unit manager identifier errorCode: request error code errorString: request error message """ if errorCode not in IGNORED_UNIT_MGR_ERRORS: msgType, msgBody = messages.getUnitMessage(errorCode, errorString) SystemMessages.pushMessage(msgBody, type=msgType) self.__requestCtx.stopProcessing() if errorCode in ENTER_UNIT_MGR_ERRORS: self.restorePrevious() def unitBrowser_onErrorReceived(self, errorCode, errorString): """ Unit browser event listener for request error. Pushes system message and resets current entity to default. Args: errorCode: request error code errorString: request error message """ if errorCode not in IGNORED_UNIT_BROWSER_ERRORS: msgType, msgBody = messages.getUnitBrowserMessage( errorCode, errorString) SystemMessages.pushMessage(msgBody, type=msgType) self.__unsetEntity() self.__setDefault() def ctrl_onPreQueueJoined(self, queueType): """ Prebattle control events for pre queue join. Sets pre queue entity. Args: queueType: queue type """ self.__setPreQueue(flags=self.__requestCtx.getFlags(), queueType=queueType) def ctrl_onPreQueueJoinFailure(self, errorCode): """ Player event listener for prequeue join filure. Resets current entity to default. Args: errorCode: join error code """ self.__setDefault() def ctrl_onPreQueueLeft(self): """ Prebattle control events for pre queue leave. Unsets current unit entity and inits default state if it is not switch. """ flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock): """ Game session listener for ban notification. Resets current entity to default. Args: isPlayTimeBan: is ban for play time timeTillBlock: time when block will be activated """ if prb_getters.isParentControlActivated(): self.__entity.resetPlayerState() key = '#system_messages:gameSessionControl/korea/{0:>s}' if isPlayTimeBan: SystemMessages.pushI18nMessage( key.format('playTimeNotification'), timeTillBlock, type=SystemMessages.SM_TYPE.Warning) else: notifyStartTime, blockTime = self.gameSession.getCurfewBlockTime( ) formatter = lambda t: time.strftime('%H:%M', time.localtime(t)) SystemMessages.pushI18nMessage( key.format('midnightNotification'), type=SystemMessages.SM_TYPE.Warning, preBlockTime=formatter(notifyStartTime), blockTime=formatter(blockTime)) def rc_onRentChange(self, vehicles): """ Rental listener for vehicles state update. Resets current player's state. Args: vehicles: list of affected vehicle intCDs """ if g_currentVehicle.isPresent( ) and g_currentVehicle.item.intCD in vehicles and g_currentVehicle.isDisabledInRent( ) and g_currentVehicle.isInPrebattle(): self.__entity.resetPlayerState() def igr_onRoomChange(self, roomType, xpFactor): """ IGR listener for room state. Resets current player's state when he is in premium IGR, joined some prebattle and this room is no more premium. Args: roomType: new IGR room type xpFactor: xp boost factor """ if roomType != IGR_TYPE.PREMIUM: if g_currentVehicle.isPremiumIGR( ) and g_currentVehicle.isInPrebattle(): self.__entity.resetPlayerState() def __startListening(self): """ Subscribes to player and system events. """ g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle g_playerEvents.onArenaCreated += self.pe_onArenaCreated g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged g_playerEvents.onPrebattleInvitationsError += self.pe_onPrebattleInviteError if self.gameSession.lastBanMsg is not None: self.gs_onTillBanNotification(*self.gameSession.lastBanMsg) self.gameSession.onTimeTillBan += self.gs_onTillBanNotification self.rentals.onRentChangeNotify += self.rc_onRentChange self.igrCtrl.onIgrTypeChanged += self.igr_onRoomChange unitMgr = prb_getters.getClientUnitMgr() if unitMgr: unitMgr.onUnitJoined += self.unitMgr_onUnitJoined unitMgr.onUnitLeft += self.unitMgr_onUnitLeft unitMgr.onUnitRestored += self.unitMgr_onUnitRestored unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived else: LOG_ERROR('Unit manager is not defined') unitBrowser = prb_getters.getClientUnitBrowser() if unitBrowser: unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived else: LOG_ERROR('Unit browser is not defined') g_prbCtrlEvents.onLegacyIntroModeJoined += self.ctrl_onLegacyIntroModeJoined g_prbCtrlEvents.onLegacyIntroModeLeft += self.ctrl_onLegacyIntroModeLeft g_prbCtrlEvents.onLegacyInited += self.ctrl_onLegacyInited g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft g_prbCtrlEvents.onUnitBrowserModeLeft += self.ctrl_onUnitBrowserModeLeft g_prbCtrlEvents.onPreQueueJoined += self.ctrl_onPreQueueJoined g_prbCtrlEvents.onPreQueueJoinFailure += self.ctrl_onPreQueueJoinFailure g_prbCtrlEvents.onPreQueueLeft += self.ctrl_onPreQueueLeft return def __stopListening(self): """ Unsubscribe from player and system events. """ g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle g_playerEvents.onArenaCreated -= self.pe_onArenaCreated g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged g_playerEvents.onPrebattleInvitationsError -= self.pe_onPrebattleInviteError self.gameSession.onTimeTillBan -= self.gs_onTillBanNotification self.rentals.onRentChangeNotify -= self.rc_onRentChange self.igrCtrl.onIgrTypeChanged -= self.igr_onRoomChange unitMgr = prb_getters.getClientUnitMgr() if unitMgr: unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived unitBrowser = prb_getters.getClientUnitBrowser() if unitBrowser: unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived g_prbCtrlEvents.clear() def __clear(self, woEvents=False): """ Clears dispatchers current state and attributes. Args: woEvents: flag that we should not raise any events """ if self.__requestCtx: self.__requestCtx.clear() self.__requestCtx = None if self.__factories is not None: self.__factories.clear() self.__factories = None if self.__entity is not None: self.__entity.fini(woEvents=woEvents) self.__entity = None self.__prevEntity = None g_eventDispatcher.removeSpecBattlesFromCarousel() self.clear() return def __setLegacy(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0): """ Sets current entity to legacy and stops request processing. Args: flags: functional flags prbType: prebattle type Returns: initialization result as flags """ return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.LEGACY, prbType, flags=flags, initCtx=self.__requestCtx)) def __setUnit(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0): """ Sets current entity to unit and stops request processing. Args: flags: functional flags prbType: prebattle type Returns: initialization result as flags """ return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.UNIT, prbType, flags=flags, initCtx=self.__requestCtx)) def __setPreQueue(self, flags=FUNCTIONAL_FLAG.UNDEFINED, queueType=0): """ Sets current entity to queue and stops request processing. Args: flags: functional flags queueType: queue type Returns: initialization result as flags """ return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.PREQUEUE, queueType, flags=flags, initCtx=self.__requestCtx)) def __setDefault(self): """ Sets current entity to default (allowing the system to initialize by itself) and stops request processing. Returns: initialization result as flags """ return self.__setEntity( CreatePrbEntityCtx(flags=FUNCTIONAL_FLAG.DEFAULT)) def __validateJoinOp(self, ctx): """ Validates join operation: is request in process, is player already joined, or current entity has locked state. Args: ctx: join request context Returns: was validation passed """ if self.__requestCtx.isProcessing(): LOG_ERROR('Request is processing', self.__requestCtx) return False if self.__entity.isPlayerJoined(ctx): LOG_DEBUG('Player already joined', ctx) self.__entity.showGUI(ctx) return False if self.__entity.hasLockedState(): SystemMessages.pushI18nMessage( '#system_messages:prebattle/hasLockedState', type=SystemMessages.SM_TYPE.Warning) return False return True def __unsetEntity(self, ctx=None): """ Unset current entity. Args: ctx: leave, join or create request context """ if not isinstance(self.__entity, NotSupportedEntity): self._invokeListeners('onPrbEntitySwitching') self.__entity.fini(ctx=ctx) self.__prevEntity = self.__entity self.__entity = NotSupportedEntity() self.__requestCtx.stopProcessing(result=True) def __setEntity(self, ctx): """ Set current entity and clear request context. Args: ctx: set entity context Returns: integer containing initialization result as flags """ created = self.__factories.createEntity(ctx) if created is not None: if created.getEntityFlags( ) & FUNCTIONAL_FLAG.SET_GLOBAL_LISTENERS > 0: created.addMutualListeners(self) self.__entity = created self.__prevEntity = NotSupportedEntity() flag = self.__entity.init(ctx=ctx) self._invokeListeners('onPrbEntitySwitched') ctx.clearFlags() ctx.addFlags(flag | created.getFunctionalFlags()) LOG_DEBUG('Entity have been updated', ctx.getFlagsToStrings()) ctx.clear() currentCtx = self.__requestCtx self.__requestCtx = PrbCtrlRequestCtx() currentCtx.stopProcessing(result=True) g_eventDispatcher.updateUI() return ctx.getFlags()
class _PreBattleDispatcher(ListenersCollection): gameSession = dependency.descriptor(IGameSessionController) rentals = dependency.descriptor(IRentalsController) igrCtrl = dependency.descriptor(IIGRController) eventsCache = dependency.descriptor(IEventsCache) def __init__(self): super(_PreBattleDispatcher, self).__init__() self.__requestCtx = PrbCtrlRequestCtx() self.__factories = ControlFactoryComposite() self.__entity = NotSupportedEntity() self.__prevEntity = NotSupportedEntity() self.__isStarted = False self._setListenerClass(IGlobalListener) def __del__(self): LOG_DEBUG('_PreBattleDispatcher deleted') def start(self): if self.__isStarted: return self.__isStarted = True g_eventDispatcher.init(self) result = self.__setDefault() self.__startListening() initDevFunctional() if result & FUNCTIONAL_FLAG.LOAD_PAGE == 0: g_eventDispatcher.loadHangar() if GUI_SETTINGS.specPrebatlesVisible and not prb_getters.areSpecBattlesHidden( ): g_eventDispatcher.addSpecBattlesToCarousel() def stop(self): if not self.__isStarted: return self.__isStarted = False self.__stopListening() finiDevFunctional() self.__clear(woEvents=True) g_eventDispatcher.fini() def getEntity(self): return self.__entity def getControlFactories(self): return self.__factories def getFunctionalState(self): factory = self.__factories.get(self.__entity.getCtrlType()) return factory.createStateEntity( self.__entity) if factory is not None else FunctionalState() @async @process def create(self, ctx, callback=None): if ctx.getRequestType() != _RQ_TYPE.CREATE: LOG_ERROR('Invalid context to create prebattle/unit', ctx) if callback is not None: callback(False) return else: entry = self.__factories.createEntry(ctx) if entry is None: LOG_ERROR('Entry not found', ctx) if callback is not None: callback(False) return if not entry.canCreate(): if callback is not None: callback(False) return ctx.addFlags(entry.getFunctionalFlags() | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to create', ctx) self.__requestCtx = ctx entry.create(ctx, callback=callback) return @async @process def join(self, ctx, callback=None): if ctx.getRequestType() != _RQ_TYPE.JOIN: LOG_ERROR('Invalid context to join prebattle/unit', ctx) if callback is not None: callback(False) return else: entry = self.__factories.createEntry(ctx) if entry is None: LOG_ERROR('Entry not found', ctx) if callback is not None: callback(False) return if not entry.canJoin(): if callback is not None: callback(False) return ctx.addFlags(entry.getFunctionalFlags() | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to join', ctx) self.__requestCtx = ctx entry.join(ctx, callback=callback) return @async def leave(self, ctx, callback=None, ignoreConfirmation=False): if ctx.getRequestType() != _RQ_TYPE.LEAVE: LOG_ERROR('Invalid context to leave prebattle/unit', ctx) if callback is not None: callback(False) return elif self.__requestCtx.isProcessing(): LOG_ERROR('Request is processing', self.__requestCtx) if callback is not None: callback(False) return else: entity = self.__entity if not ignoreConfirmation: meta = entity.getConfirmDialogMeta(ctx) if meta: entity.showDialog( meta, lambda result: self.__leaveCallback( result, ctx, callback)) return self.__leaveLogic(ctx, callback) return def __leaveCallback(self, result, ctx, callback=None): if not result: if callback is not None: callback(False) return else: self.__leaveLogic(ctx, callback) return def __leaveLogic(self, ctx, callback): entity = self.__entity if not entity.isActive(): if callback is not None: callback(False) return else: ctrlType = ctx.getCtrlType() if entity.hasLockedState(): entityType = entity.getEntityType() SystemMessages.pushI18nMessage( messages.getLeaveDisabledMessage(ctrlType, entityType), type=SystemMessages.SM_TYPE.Warning) if callback is not None: callback(False) return LOG_DEBUG('Request to leave formation', ctx) self.__requestCtx = ctx entity.leave(ctx, callback=callback) return @async @process def unlock(self, unlockCtx, callback=None): if isinstance(self.__entity, NotSupportedEntity): if callback is not None: callback(True) return else: state = self.getFunctionalState() ctrlType = state.ctrlTypeID factory = self.__factories.get(ctrlType) if factory is None: LOG_ERROR('Factory is not found', state) if callback is not None: callback(True) return ctx = factory.createLeaveCtx(unlockCtx.getFlags(), self.__entity.getEntityType()) result = yield self.leave(ctx) if callback is not None: callback(result) return @async @process def select(self, entry, callback=None): ctx = entry.makeDefCtx() ctx.addFlags(entry.getModeFlags() & FUNCTIONAL_FLAG.LOAD_PAGE | FUNCTIONAL_FLAG.SWITCH) if not self.__validateJoinOp(ctx): if callback is not None: callback(False) return else: if entry.isVisualOnly(): result = True else: result = yield self.unlock(ctx) if not result: if callback is not None: callback(False) return ctx.setForced(True) LOG_DEBUG('Request to select', ctx) self.__requestCtx = ctx entry.select(ctx, callback=callback) return @async def sendPrbRequest(self, ctx, callback=None): self.__entity.request(ctx, callback=callback) def getPlayerInfo(self): factory = self.__factories.get(self.__entity.getCtrlType()) return factory.createPlayerInfo( self.__entity) if factory is not None else PlayerDecorator() def doAction(self, action=None): if not g_currentVehicle.isPresent(): SystemMessages.pushMessage(messages.getInvalidVehicleMessage( PREBATTLE_RESTRICTION.VEHICLE_NOT_PRESENT), type=SystemMessages.SM_TYPE.Error) return False LOG_DEBUG('Do GUI action', action) return self.__entity.doAction(action) @async @process def doSelectAction(self, action, callback=None): selectResult = self.__entity.doSelectAction(action) if selectResult.isProcessed: result = True if selectResult.newEntry is not None: result = yield self.select(selectResult.newEntry) if callback is not None: callback(result) return else: entry = self.__factories.createEntryByAction(action) if entry is not None: result = yield self.select(entry) if callback is not None: callback(result) return if callback is not None: callback(False) return @async @process def doLeaveAction(self, action, callback=None): factory = self.__factories.get(self.__entity.getCtrlType()) if factory is None: LOG_ERROR('Factory is not found', self.__entity) if callback is not None: callback(True) return else: flags = FUNCTIONAL_FLAG.UNDEFINED if action.isExit: flags = FUNCTIONAL_FLAG.EXIT elif self.__entity.canKeepMode(): flags = self.__entity.getModeFlags() ctx = factory.createLeaveCtx( flags, entityType=self.__entity.getEntityType()) if self.__entity.isInCoolDown(ctx.getRequestType()): if callback is not None: callback(True) return self.__entity.setCoolDown(ctx.getRequestType(), ctx.getCooldown()) result = yield self.leave( ctx, ignoreConfirmation=action.ignoreConfirmation) if callback is not None: callback(result) return def getGUIPermissions(self): return self.__entity.getPermissions() def isRequestInProcess(self): return self.__requestCtx.isProcessing() def restorePrevious(self): return self.__setEntity( CreatePrbEntityCtx(self.__prevEntity.getCtrlType(), self.__prevEntity.getEntityType(), flags=self.__prevEntity.getFunctionalFlags())) def pe_onArenaCreated(self): if self.__entity.hasLockedState(): g_eventDispatcher.updateUI() def pe_onArenaJoinFailure(self, errorCode, errorStr): SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error) def pe_onKickedFromArena(self, reasonCode): self.__entity.resetPlayerState() SystemMessages.pushMessage(messages.getKickReasonMessage(reasonCode), type=SystemMessages.SM_TYPE.Error) def pe_onPrebattleAutoInvitesChanged(self): if GUI_SETTINGS.specPrebatlesVisible: isHidden = prb_getters.areSpecBattlesHidden() if isHidden: g_eventDispatcher.removeSpecBattlesFromCarousel() else: g_eventDispatcher.addSpecBattlesToCarousel() g_eventDispatcher.updateUI() def pe_onPrebattleInviteError(self, inviteID, errorCode, errorStr): self.__unsetEntity() self.__setDefault() def pe_onPrebattleJoined(self): if prb_getters.getClientPrebattle() is not None: self.__setLegacy(self.__requestCtx.getFlags()) else: LOG_ERROR('ClientPrebattle is not defined') self.__setDefault() g_eventDispatcher.loadHangar() return def pe_onPrebattleJoinFailure(self, errorCode): SystemMessages.pushMessage(messages.getJoinFailureMessage(errorCode), type=SystemMessages.SM_TYPE.Error) self.__setDefault() g_eventDispatcher.loadHangar() def pe_onPrebattleLeft(self): flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: prbType = self.__entity.getEntityType() self.__unsetEntity(self.__requestCtx) self.__setLegacy(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def pe_onKickedFromPrebattle(self, kickReason): self.__unsetEntity() self.__setDefault() def ctrl_onLegacyIntroModeJoined(self, prbType): self.__setLegacy(flags=self.__requestCtx.getFlags(), prbType=prbType) def ctrl_onLegacyIntroModeLeft(self): flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def ctrl_onLegacyInited(self): self.__setLegacy(flags=self.__requestCtx.getFlags()) def ctrl_onUnitIntroModeJoined(self, prbType, flags): self.__setUnit(flags=flags, prbType=prbType) def ctrl_onUnitBrowserModeLeft(self, prbType): flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: unitEntity = self.__entity if unitEntity.canKeepMode(): prbType = unitEntity.getIntroType() flags |= unitEntity.getModeFlags() self.__unsetEntity(self.__requestCtx) self.__setUnit(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def ctrl_onUnitIntroModeLeft(self): flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def unitMgr_onUnitJoined(self, unitMgrID, prbType): entity = self.__entity ctx = JoinUnitCtx(unitMgrID, prbType) if entity.isPlayerJoined(ctx): entity.rejoin() else: self.__setUnit(flags=self.__requestCtx.getFlags(), prbType=self.__requestCtx.getEntityType()) def unitMgr_onUnitLeft(self, unitMgrID, isFinishedAssembling): flags = self.__requestCtx.getFlags() if flags & FUNCTIONAL_FLAG.SWITCH == 0: prbType = 0 if flags & FUNCTIONAL_FLAG.EXIT == 0: unitEntity = self.__entity if unitEntity.canKeepMode(): prbType = unitEntity.getEntityType() flags |= unitEntity.getModeFlags( ) | FUNCTIONAL_FLAG.UNIT_BROWSER self.__unsetEntity(self.__requestCtx) self.__setUnit(flags=flags, prbType=prbType) else: self.__unsetEntity(self.__requestCtx) def unitMgr_onUnitRestored(self, unitMgrID): self.__entity.restore() def unitMgr_onUnitErrorReceived(self, requestID, unitMgrID, errorCode, errorString): if errorCode not in IGNORED_UNIT_MGR_ERRORS: msgType, msgBody = messages.getUnitMessage(errorCode, errorString) SystemMessages.pushMessage(msgBody, type=msgType) self.__requestCtx.stopProcessing() if errorCode in ENTER_UNIT_MGR_ERRORS: self.restorePrevious() def unitMgr_onUnitNotifyReceived(self, unitMgrID, notifyCode, notifyString, argsList): if notifyCode in UNIT_NOTIFICATION_TO_DISPLAY: msgType, msgBody = messages.getUnitMessage(notifyCode, notifyString) SystemMessages.pushMessage(msgBody, type=msgType) self.__requestCtx.stopProcessing() def unitBrowser_onErrorReceived(self, errorCode, errorString): if errorCode not in IGNORED_UNIT_BROWSER_ERRORS: msgType, msgBody = messages.getUnitBrowserMessage( errorCode, errorString) SystemMessages.pushMessage(msgBody, type=msgType) self.__unsetEntity() self.__setDefault() def ctrl_onPreQueueJoined(self, queueType): self.__setPreQueue(flags=self.__requestCtx.getFlags(), queueType=queueType) def ctrl_onPreQueueJoinFailure(self, errorCode): self.__setDefault() def ctrl_onPreQueueLeft(self): flags = self.__requestCtx.getFlags() self.__unsetEntity(self.__requestCtx) if flags & FUNCTIONAL_FLAG.SWITCH == 0: self.__setDefault() def gs_onTillBanNotification(self, isPlayTimeBan, timeTillBlock): if prb_getters.isParentControlActivated(): self.__entity.resetPlayerState() key = '#system_messages:gameSessionControl/korea/{0:>s}' if isPlayTimeBan: SystemMessages.pushI18nMessage( key.format('playTimeNotification'), timeTillBlock, type=SystemMessages.SM_TYPE.Warning) else: _, blockTime = self.gameSession.getCurfewBlockTime() formatter = lambda t: time.strftime('%H:%M', time.localtime(t)) SystemMessages.pushI18nMessage( key.format('midnightNotification'), type=SystemMessages.SM_TYPE.Warning, blockTime=formatter(blockTime)) def rc_onRentChange(self, vehicles): if g_currentVehicle.isPresent( ) and g_currentVehicle.item.intCD in vehicles and g_currentVehicle.isDisabledInRent( ) and g_currentVehicle.isInPrebattle(): self.__entity.resetPlayerState() def igr_onRoomChange(self, roomType, xpFactor): if roomType != IGR_TYPE.PREMIUM: if g_currentVehicle.isPremiumIGR( ) and g_currentVehicle.isInPrebattle(): self.__entity.resetPlayerState() def notifyPrbEntitySwitched(self): if self.__isStarted: self._invokeListeners('onPrbEntitySwitched') def __startListening(self): g_playerEvents.onPrebattleJoined += self.pe_onPrebattleJoined g_playerEvents.onPrebattleJoinFailure += self.pe_onPrebattleJoinFailure g_playerEvents.onPrebattleLeft += self.pe_onPrebattleLeft g_playerEvents.onKickedFromPrebattle += self.pe_onKickedFromPrebattle g_playerEvents.onArenaCreated += self.pe_onArenaCreated g_playerEvents.onArenaJoinFailure += self.pe_onArenaJoinFailure g_playerEvents.onKickedFromArena += self.pe_onKickedFromArena g_playerEvents.onPrebattleAutoInvitesChanged += self.pe_onPrebattleAutoInvitesChanged g_playerEvents.onPrebattleInvitationsError += self.pe_onPrebattleInviteError g_playerEvents.onUpdateSpecBattlesWindow += self.pe_onPrebattleAutoInvitesChanged if self.gameSession.lastBanMsg is not None: self.gs_onTillBanNotification(*self.gameSession.lastBanMsg) self.gameSession.onTimeTillBan += self.gs_onTillBanNotification self.rentals.onRentChangeNotify += self.rc_onRentChange self.igrCtrl.onIgrTypeChanged += self.igr_onRoomChange unitMgr = prb_getters.getClientUnitMgr() if unitMgr: unitMgr.onUnitJoined += self.unitMgr_onUnitJoined unitMgr.onUnitLeft += self.unitMgr_onUnitLeft unitMgr.onUnitRestored += self.unitMgr_onUnitRestored unitMgr.onUnitErrorReceived += self.unitMgr_onUnitErrorReceived unitMgr.onUnitNotifyReceived += self.unitMgr_onUnitNotifyReceived else: LOG_ERROR('Unit manager is not defined') unitBrowser = prb_getters.getClientUnitBrowser() if unitBrowser: unitBrowser.onErrorReceived += self.unitBrowser_onErrorReceived else: LOG_ERROR('Unit browser is not defined') g_prbCtrlEvents.onLegacyIntroModeJoined += self.ctrl_onLegacyIntroModeJoined g_prbCtrlEvents.onLegacyIntroModeLeft += self.ctrl_onLegacyIntroModeLeft g_prbCtrlEvents.onLegacyInited += self.ctrl_onLegacyInited g_prbCtrlEvents.onUnitIntroModeJoined += self.ctrl_onUnitIntroModeJoined g_prbCtrlEvents.onUnitIntroModeLeft += self.ctrl_onUnitIntroModeLeft g_prbCtrlEvents.onUnitBrowserModeLeft += self.ctrl_onUnitBrowserModeLeft g_prbCtrlEvents.onPreQueueJoined += self.ctrl_onPreQueueJoined g_prbCtrlEvents.onPreQueueJoinFailure += self.ctrl_onPreQueueJoinFailure g_prbCtrlEvents.onPreQueueLeft += self.ctrl_onPreQueueLeft g_eventBus.addListener(events.PrbActionEvent.SELECT, self.__onDoSelectAction, scope=EVENT_BUS_SCOPE.LOBBY) g_eventBus.addListener(events.PrbActionEvent.LEAVE, self.__onDoLeaveAction, scope=EVENT_BUS_SCOPE.LOBBY) return def __stopListening(self): g_playerEvents.onPrebattleJoined -= self.pe_onPrebattleJoined g_playerEvents.onPrebattleJoinFailure -= self.pe_onPrebattleJoinFailure g_playerEvents.onPrebattleLeft -= self.pe_onPrebattleLeft g_playerEvents.onKickedFromPrebattle -= self.pe_onKickedFromPrebattle g_playerEvents.onArenaCreated -= self.pe_onArenaCreated g_playerEvents.onArenaJoinFailure -= self.pe_onArenaJoinFailure g_playerEvents.onKickedFromArena -= self.pe_onKickedFromArena g_playerEvents.onPrebattleAutoInvitesChanged -= self.pe_onPrebattleAutoInvitesChanged g_playerEvents.onPrebattleInvitationsError -= self.pe_onPrebattleInviteError g_playerEvents.onUpdateSpecBattlesWindow -= self.pe_onPrebattleAutoInvitesChanged self.gameSession.onTimeTillBan -= self.gs_onTillBanNotification self.rentals.onRentChangeNotify -= self.rc_onRentChange self.igrCtrl.onIgrTypeChanged -= self.igr_onRoomChange unitMgr = prb_getters.getClientUnitMgr() if unitMgr: unitMgr.onUnitJoined -= self.unitMgr_onUnitJoined unitMgr.onUnitLeft -= self.unitMgr_onUnitLeft unitMgr.onUnitRestored -= self.unitMgr_onUnitRestored unitMgr.onUnitErrorReceived -= self.unitMgr_onUnitErrorReceived unitMgr.onUnitNotifyReceived -= self.unitMgr_onUnitNotifyReceived unitBrowser = prb_getters.getClientUnitBrowser() if unitBrowser: unitBrowser.onErrorReceived -= self.unitBrowser_onErrorReceived g_prbCtrlEvents.clear() g_eventBus.removeListener(events.PrbActionEvent.SELECT, self.__onDoSelectAction, scope=EVENT_BUS_SCOPE.LOBBY) g_eventBus.removeListener(events.PrbActionEvent.LEAVE, self.__onDoLeaveAction, scope=EVENT_BUS_SCOPE.LOBBY) def __clear(self, woEvents=False): if self.__requestCtx: self.__requestCtx.clear() self.__requestCtx = None if self.__factories is not None: self.__factories.clear() self.__factories = None if self.__entity is not None: self.__entity.fini(woEvents=woEvents) self.__entity = None self.__prevEntity = None g_eventDispatcher.removeSpecBattlesFromCarousel() self.clear() return def __setLegacy(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0): return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.LEGACY, prbType, flags=flags, initCtx=self.__requestCtx)) def __setUnit(self, flags=FUNCTIONAL_FLAG.UNDEFINED, prbType=0): return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.UNIT, prbType, flags=flags, initCtx=self.__requestCtx)) def __setPreQueue(self, flags=FUNCTIONAL_FLAG.UNDEFINED, queueType=0): return self.__setEntity( CreatePrbEntityCtx(_CTRL_TYPE.PREQUEUE, queueType, flags=flags, initCtx=self.__requestCtx)) def __setDefault(self): return self.__setEntity( CreatePrbEntityCtx(flags=FUNCTIONAL_FLAG.DEFAULT)) def __validateJoinOp(self, ctx): if self.__requestCtx.isProcessing(): LOG_ERROR('Request is processing', self.__requestCtx) return False if self.__entity.isPlayerJoined(ctx): LOG_DEBUG('Player already joined', ctx) self.__entity.showGUI(ctx) return False if self.__entity.hasLockedState(): SystemMessages.pushI18nMessage( '#system_messages:prebattle/hasLockedState', type=SystemMessages.SM_TYPE.Warning) return False return True def __unsetEntity(self, ctx=None): if not isinstance(self.__entity, NotSupportedEntity): self._invokeListeners('onPrbEntitySwitching') self.__entity.fini(ctx=ctx) self.__prevEntity = self.__entity self.__entity = NotSupportedEntity() self.__requestCtx.stopProcessing(result=True) def __setEntity(self, ctx): created = self.__factories.createEntity(ctx) if created is not None: if created.getEntityFlags( ) & FUNCTIONAL_FLAG.SET_GLOBAL_LISTENERS > 0: created.addMutualListeners(self) if self.__entity is not None and not isinstance( self.__entity, NotSupportedEntity): _logger.info( "__setEntity() new entity '%r' was created, previous entity '%r' was stopped", created, self.__entity) self.__entity.fini() self.__entity = created if self.__prevEntity is not None and self.__prevEntity.isActive(): self.__prevEntity.fini() self.__prevEntity = NotSupportedEntity() flag = self.__entity.init(ctx=ctx) self.notifyPrbEntitySwitched() ctx.clearFlags() ctx.addFlags(flag | created.getFunctionalFlags()) LOG_DEBUG('Entity have been updated', ctx.getFlagsToStrings()) ctx.clear() currentCtx = self.__requestCtx self.__requestCtx = PrbCtrlRequestCtx() currentCtx.stopProcessing(result=True) g_eventDispatcher.updateUI() return ctx.getFlags() @process def __onDoSelectAction(self, event): yield self.doSelectAction(event.action) @process def __onDoLeaveAction(self, event): yield self.doLeaveAction(event.action)