void UGameEngine::PreExit() { FAVIWriter* AVIWriter = FAVIWriter::GetInstance(); if (AVIWriter) { AVIWriter->Close(); } Super::PreExit(); // Stop tracking, automatically flushes. NETWORK_PROFILER(GNetworkProfiler.EnableTracking(false)); CancelAllPending(); // Clean up all worlds for (int32 WorldIndex = 0; WorldIndex < WorldList.Num(); ++WorldIndex) { UWorld* const World = WorldList[WorldIndex].World(); if ( World != NULL ) { World->bIsTearingDown = true; // Cancel any pending connection to a server CancelPending(World); // Shut down any existing game connections ShutdownWorldNetDriver(World); for (FActorIterator ActorIt(World); ActorIt; ++ActorIt) { ActorIt->RouteEndPlay(EEndPlayReason::Quit); } World->GetGameInstance()->Shutdown(); World->FlushLevelStreaming(EFlushLevelStreamingType::Visibility); World->CleanupWorld(); } } }
/** Complete state transition. This is called by the base class when a state transition has concluded and it provides an opportunity for the state machine to perform actions required immediately after this transition. The method can also initiate a further change of state. This is relevant when the state machine is required to perform an autonomous transition from one state to another e.g. this occurs when several interactions are required arising from a single external trigger. */ void CMtLrStateMachine::PostStateTransition() { // Some states are transitory i.e. they require // an automatic transition to the next state if ( CancelPending() || (EStateNetReqRecvd == iCurrentState) || ((CLbsNetworkProtocolBase::EPrivacyResponseAccepted != PrivacyResponseValue()) && ((EStatePrivacyRespRecvd == iCurrentState) || (EStatePrivacyRespRecvdAfterMeasure == iCurrentState))) || (EStatePrivacyReject == iCurrentState) || (EStateMeasureDataRecvd == iCurrentState) || (EStateNetBasedLocSent == iCurrentState) || (EStateLocRespRecvd == iCurrentState) || (EStateLocSentToNet == iCurrentState) || (EStateClientSessToCloseAfterMeasure == iCurrentState) || (EStateSessionsClosed == iCurrentState) || (EStateCancelling == iCurrentState) ) { // Perform a state transition PerformStateTransition(); } }
bool UGameEngine::HandleExitCommand( const TCHAR* Cmd, FOutputDevice& Ar ) { for (int32 WorldIndex = 0; WorldIndex < WorldList.Num(); ++WorldIndex) { UWorld* const World = WorldList[WorldIndex].World(); AGameMode* const GameMode = World->GetAuthGameMode(); if (GameMode) { GameMode->GameEnding(); } // Cancel any pending connection to a server CancelPending(WorldList[WorldIndex]); // Shut down any existing game connections ShutdownWorldNetDriver(World); } Ar.Log( TEXT("Closing by request") ); FPlatformMisc::RequestExit( 0 ); return true; }
/** State transition. This method determines the next state to be adopted by the state machine. */ void CMtLrStateMachine::StateTransition() { if (CancelPending()) { SetMachineAsCancelling(); iCurrentState = EStateCancelling; } else { // Set new state switch (iCurrentState) { case EStateNull: iCurrentState = EStateNetReqRecvd; break; case EStateNetReqRecvd: iCurrentState = EStatePrivacySessStarted; iIsPrivacyRespBeforeMeasureControl = EFalse; break; case EStatePrivacySessStarted: // Location request received? if (iIsLocReqReceived) { iCurrentState = EStateMeasureDataRecvd; } // Privacy response received? else if (iPrivacyResponseRecvd) { iIsPrivacyRespBeforeMeasureControl = ETrue; iPrivacyResponseHandled = ETrue; iCurrentState = EStatePrivacyRespRecvd; // Start timer for when the measurement control is expected StartMeasureControlTimer(); } break; case EStatePrivacyRespRecvd: // Privacy not accepted? if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp) { iCurrentState = EStatePrivacyReject; } else { iCurrentState = EStateMeasureDataRecvd; } break; case EStatePrivacyRespRecvdAfterMeasure: // Privacy not accepted? if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp) { iCurrentState = EStatePrivacyRejectAfterMeasure; } else { iCurrentState = EStateLocRespRecvd; } break; case EStatePrivacyReject: iCurrentState = EStateClientSessToCloseWaitMeasure; break; case EStatePrivacyRejectAfterMeasure: iCurrentState = EStateLocRespRecvd; break; case EStateMeasureDataRecvd: iCurrentState = EStateNetBasedLocSent; break; case EStateNetBasedLocSent: iIsMeasureControlHandled = ETrue; // Was privacy already rejected if (iIsPrivacyRespBeforeMeasureControl && CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp) { ProcedureDone(); } else { iCurrentState = EStateLocReqByNet; } break; case EStateLocReqByNet: iCurrentState = iIsPrivacyRespBeforeMeasureControl ? EStateLocRespRecvd : EStatePrivacyRespRecvdAfterMeasure; break; case EStateLocRespRecvd: iCurrentState = EStateLocSentToNet; break; case EStateLocSentToNet: iCurrentState = EStateClientSessToCloseAfterMeasure; break; case EStateClientSessToCloseWaitMeasure: iCurrentState = EStateMeasureDataRecvd; break; case EStateClientSessToCloseWaitLocResp: // We are waiting for location response from LBS after the // preceding session closes. Check to see if we have timeout // otherwise we must have received the response. if (Cancelling() && (KErrTimedOut == iLocRespReason)) { iCurrentState = EStateCancelling; } else { ProcedureDone(); } break; case EStateClientSessToCloseAfterMeasure: ProcedureDone(); break; case EStateSessionsClosed: // Procedure has completed CompleteProcedure(); break; case EStateCancelling: switch (iCancelSource) { case ECancelNone: case ECancelClosing: case ECancelClientCancel: case ECancelClientCancelSilent: CompleteProcedure(); break; case ECancelNetworkError: iCurrentState = EStateClientSessToCloseAfterMeasure; break; case ECancelNetworkTimeout: // We were waiting for measurement control. // Was privacy rejected? if (CLbsNetworkProtocolBase::EPrivacyResponseAccepted != iPrivacyResp) { ProcedureDone(); } else { iCurrentState = EStateClientSessToCloseAfterMeasure; } break; case ECancelClientTimeout: // We were either waiting for a location response or a privacy response // Privacy response will timeout first, but we may need to still wait for // a location response. if (!iPrivacyResponseRecvd && iIsMeasureControlHandled && (KErrTimedOut != iLocRespReason)) { iCurrentState = EStateClientSessToCloseWaitLocResp; } else { iCurrentState = EStateClientSessToCloseAfterMeasure; } break; case ECancelNetworkCancel: iCurrentState = EStateClientSessToCloseAfterMeasure; break; default: User::Panic(KProtocolModulePanic, EProtocolModuleCancelSource); break; }; break; default: User::Panic(KProtocolModulePanic, EProtocolModuleMtLrState); break; }; } }
bool UGameEngine::HandleCancelCommand( const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld ) { CancelPending(GetWorldContextFromWorldChecked(InWorld)); return true; }
bool UGameEngine::HandleCancelCommand( const TCHAR* Cmd, FOutputDevice& Ar, UWorld* InWorld ) { FWorldContext &Context = WorldContextFromWorld(InWorld); CancelPending(Context); return true; }