示例#1
0
void FEngine::Run(FGameThread::FCreateGameSceneFunc CreateGameSceneFunc)
{
	Init(CreateGameSceneFunc);

	F_Assert(IsValid(), "Engine failed to initialize.");

	const Float32 FramesPerSec = 120.f;
	const Float32 MaxDeltaTime = 1.f / FramesPerSec;

	TThreadSafeVector<FEvent>::ContainerT ReceivedEvents;
	Float32 AccumulatedTime = 0.f;

	FHighResolutionTimer Timer;
	Timer.Reset();

	while (IsRunning)
	{
		Timer.Update();
		const Float32 DeltaTimeSec = Timer.GetDeltaSeconds<Float32>();
		AccumulatedTime += DeltaTimeSec;

		if (AccumulatedTime >= MaxDeltaTime)
		{
			AccumulatedTime = FMathf::Modulo(AccumulatedTime, MaxDeltaTime);
			Window->ProcessEvents();
			GamePadUtility.ProcessEvents(EventHandler);

			OutgoingEvents.AddData(EventHandler.GetEvents());
			EventHandler.GetEvents().clear();
			IncomingEvents.GetDataAndClear(ReceivedEvents);

			for (SizeT I = 0; I < ReceivedEvents.size(); ++I)
			{
				const FEvent& Event = ReceivedEvents[I];
				HandleEvent(Event);
			}

			ReceivedEvents.clear();
		}

		NThread::SleepThread(1);
	}

	DeInit();
	NThread::SleepThread(2000);
}
示例#2
0
void FGameThread::ThreadRun()
{
	ThreadInit();
	F_LogTrace(F_GetProfiler());
	F_ResetProfiler();

	const Float32 FramesPerSec = 60.f;
	const Float32 MaxDeltaTime = 1.f / FramesPerSec;
	const UInt32 MaxUpdateCountPerFrame = 4;

	TThreadSafeVector<FEvent>::ContainerT ReceivedEvents;
	FUpdateEvent UpdateEvent(0.f);

	Float32 NextFrameProgress = 0.f;
	Float32 AccumulatedTime = 0.f;
	UInt32 UpdateCount = 0;

	FHighResolutionTimer Timer;
	Timer.Reset();

	while (IsRunning)
	{
		{
			F_Profile();

			Timer.Update();
			const Float32 DeltaTimeSec = Timer.GetDeltaSeconds<Float32>();

			AccumulatedTime += DeltaTimeSec;
			UpdateCount = 0;

			NextFrameProgress = AccumulatedTime / MaxDeltaTime;
			while (AccumulatedTime >= MaxDeltaTime)
			{
				F_ProfileWithMsg("Update");
				UpdateEvent.CurrentTimeS = Timer.GetTimeInSeconds();
				AccumulatedTime -= MaxDeltaTime;

				const bool bIsFirstUpdateThisFrame = UpdateCount == 0;
				if (bIsFirstUpdateThisFrame)
				{
					const Float32 AccumTModDeltaT = FMathf::Modulo(AccumulatedTime, MaxDeltaTime);

					UpdateEvent.PreviousFrameTimeS = UpdateEvent.CurrentFrameTimeS;
					UpdateEvent.CurrentFrameTimeS = UpdateEvent.CurrentTimeS - AccumTModDeltaT;
					UpdateEvent.DeltaTimeS = MaxDeltaTime;

					NextFrameProgress = AccumTModDeltaT / MaxDeltaTime;
				}

				InitData.IncomingEvents->GetDataAndClear<false>(ReceivedEvents);
				ThreadHandleEvents(UpdateEvent, ReceivedEvents);

				GameScene->Update(UpdateEvent, ComponentManagerImpl->ComponentManager);

				ComponentManagerImpl->ComponentManager.UpdateSystems(UpdateEvent);
				ComponentManagerImpl->ComponentManager.Refresh();

				++UpdateCount;
				const UInt32 MinFramesBeforeWarning = 2;
				const bool TwoUpdatesForFrame = UpdateCount == MinFramesBeforeWarning;
				F_LogWarningIf(TwoUpdatesForFrame, "Two or more updates occurred.  AccT: " << AccumulatedTime);

				if (UpdateCount >= MaxUpdateCountPerFrame)
				{
					AccumulatedTime = FMathf::Modulo(AccumulatedTime, MaxDeltaTime);
					NextFrameProgress = AccumulatedTime / MaxDeltaTime;
					F_LogError("Hit the maximum update count of " << MaxUpdateCountPerFrame 
						<< " for this frame.  Reducing AccumulatedTime to " << AccumulatedTime);
				}
			}

			if (UpdateCount)
			{
				GFXEngine.SetUpNextRender();
			}

			// Eliminate spin wait until we actually need the CPU usage.
			if (UpdateCount == 0)
			{
				NThread::SleepThread(1);
			}
		}

		F_ResetProfiler();
	}

	ThreadDeInit();
}