Skip to content

Commit

Permalink
Do more iterative steps per game loop up to 8msec
Browse files Browse the repository at this point in the history
  • Loading branch information
MrSapps committed Jul 22, 2017
1 parent ec85224 commit b80d468
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 25 deletions.
80 changes: 80 additions & 0 deletions include/iterativeforloop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,43 @@

#include "types.hpp"
#include <functional>
#include <chrono>

constexpr u32 kMaxExecutionTimeMs = 8;

class Timer
{
public:
Timer() : mStartTime(TClock::now())
{

}

void Reset()
{
mStartTime = TClock::now();
}

u32 Elapsed() const
{
const u32 ret = static_cast<u32>(std::chrono::duration_cast<std::chrono::milliseconds>(TClock::now() - mStartTime).count());
return ret;
}

private:
using TClock = std::chrono::high_resolution_clock;
std::chrono::time_point<TClock> mStartTime;
};

template<class Func>
inline void RunForAtLeast(u32 millisecondsTimeBox, Func func)
{
Timer time;
do
{
func();
} while (time.Elapsed() < millisecondsTimeBox);
}

template<class LoopIndexType>
class IterativeForLoop
Expand All @@ -15,6 +52,27 @@ class IterativeForLoop
return mCurrentIndex;
}

template<class Func>
bool IterateTimeBoxed(u32 millisecondsTimeBox, LoopIndexType bound, Func loopIterationFunc)
{
Timer time;
bool iterationCompleted = false;
do
{
iterationCompleted = IterateCommon(bound, [&]()
{
// For the most nested iterate we run the loop body and always increment
loopIterationFunc();
return true;
});
if (iterationCompleted)
{
break;
}
} while (time.Elapsed() < millisecondsTimeBox);
return iterationCompleted;
}

template<class Func>
bool Iterate(LoopIndexType bound, Func loopIterationFunc)
{
Expand All @@ -38,6 +96,28 @@ class IterativeForLoop
});
}

template<class Func>
bool IterateTimeBoxedIf(u32 millisecondsTimeBox, LoopIndexType bound, Func loopIterationFunc)
{
Timer time;
bool iterationCompleted = false;
do
{
iterationCompleted = IterateCommon(bound, [&]()
{
// The caller supplied loop function determines if we increment, typically
// this is the result of another Iterate, i.e the outer loop only increments
// if the inner loop iteration is done.
return loopIterationFunc();
});
if (iterationCompleted)
{
break;
}
} while (time.Elapsed() < millisecondsTimeBox);
return iterationCompleted;
}

private:
template<class Func>
bool IterateCommon(LoopIndexType bound, Func executeLoopIterationAndCheckIfShouldIncrement)
Expand Down
2 changes: 1 addition & 1 deletion src/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ void Engine::RunInitScript()
}

// TODO: Using averaging value or anything that is more accurate than this
typedef std::chrono::high_resolution_clock THighResClock;
using THighResClock = std::chrono::high_resolution_clock;
class BasicFramesPerSecondCounter
{
public:
Expand Down
6 changes: 3 additions & 3 deletions src/gridmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ GridMap::GridMap()
mEditorMode = std::make_unique<EditorMode>(mMapState);
mGameMode = std::make_unique<GameMode>(mMapState);

// Size of the screen you see during normal game play, this is always less the the "block" the camera image fits into
// Size of the screen you see during normal game play, this is always less than the "block" the camera image fits into
mMapState.kVirtualScreenSize = glm::vec2(368.0f, 240.0f);
}

Expand Down Expand Up @@ -201,7 +201,7 @@ void GridMap::Loader::HandleAllocateCameraMemory(const Oddlib::Path& path)

void GridMap::Loader::HandleLoadCameras(const Oddlib::Path& path, ResourceLocator& locator)
{
if (mXForLoop.IterateIf(path.XSize(), [&]()
if (mXForLoop.IterateTimeBoxedIf(kMaxExecutionTimeMs, path.XSize(), [&]()
{
return mYForLoop.Iterate(path.YSize(), [&]()
{
Expand Down Expand Up @@ -350,7 +350,7 @@ bool GridMap::Loader::Load(const Oddlib::Path& path, ResourceLocator& locator)
break;

case LoaderStates::eLoadObjects:
HandleLoadObjects(path, locator);
RunForAtLeast(kMaxExecutionTimeMs, [&]() { HandleLoadObjects(path, locator); });
break;

case LoaderStates::eHackToPlaceAbeInValidCamera:
Expand Down
23 changes: 2 additions & 21 deletions src/mapobject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,6 @@
}
}


template<class T, class U>
static void IterateArray(Sqrat::Object& sqObj, const char* arrayName, U callBack)
{
Sqrat::Array sqArray = sqObj[arrayName];
if (!sqArray.IsNull())
{
const SQInteger arraySize = sqArray.GetSize();
for (SQInteger i = 0; i < arraySize; i++)
{
Sqrat::SharedPtr<T> item = sqArray.GetValue<T>(static_cast<int>(i));
if (item)
{
callBack(*item);
}
}
}
}

static bool GetArray(Sqrat::Object& sqObj, const char* arrayName, Sqrat::Array& sqArray)
{
sqArray = sqObj[arrayName];
Expand Down Expand Up @@ -116,7 +97,7 @@ void MapObject::Loader::LoadAnimations()
Sqrat::Array animsArray;
if (GetArray(mMapObj.mScriptObject, "kAnimationResources", animsArray))
{
if (mForLoop.Iterate(animsArray.GetSize(), [&]()
if (mForLoop.IterateTimeBoxed(kMaxExecutionTimeMs, animsArray.GetSize(), [&]()
{
Sqrat::SharedPtr<std::string> item = animsArray.GetValue<std::string>(static_cast<int>(mForLoop.Value()));
if (item)
Expand All @@ -139,7 +120,7 @@ void MapObject::Loader::LoadSounds()
Sqrat::Array soundsArray;
if (GetArray(mMapObj.mScriptObject, "kSoundResources", soundsArray))
{
if (mForLoop.Iterate(soundsArray.GetSize(), [&]()
if (mForLoop.IterateTimeBoxed(kMaxExecutionTimeMs, soundsArray.GetSize(), [&]()
{
Sqrat::SharedPtr<std::string> item = soundsArray.GetValue<std::string>(static_cast<int>(mForLoop.Value()));
if (item)
Expand Down

0 comments on commit b80d468

Please sign in to comment.