Sdk/System: Fix time loss when using max update rate

This commit is contained in:
Jérôme Leclercq 2018-02-08 11:43:15 +01:00
parent 15fb338e36
commit 7366d92818
3 changed files with 78 additions and 19 deletions

View File

@ -164,8 +164,10 @@ namespace Ndk
} }
else else
{ {
OnUpdate(m_maxUpdateRate); float updateRate = std::max(elapsedTime, m_maxUpdateRate);
m_updateCounter -= m_maxUpdateRate;
OnUpdate(updateRate);
m_updateCounter -= updateRate;
} }
} }
} }

View File

@ -1,30 +1,40 @@
#include <NDK/System.hpp> #include <NDK/System.hpp>
#include <Catch/catch.hpp> #include <Catch/catch.hpp>
/*
namespace namespace
{ {
class TestSystem : public Ndk::System<TestSystem> class TestSystem : public Ndk::System<TestSystem>
{ {
public: public:
TestSystem(int value) : TestSystem() :
m_value(value) m_updateCounter(0),
m_elapsedTime(0.f)
{ {
} }
int GetValue() const
{
return m_value;
}
~TestSystem() = default; ~TestSystem() = default;
float GetElapsedTime() const
{
return m_elapsedTime;
}
std::size_t GetLoopCount() const
{
return m_updateCounter;
}
static Ndk::SystemIndex systemIndex; static Ndk::SystemIndex systemIndex;
private: private:
int m_value; std::size_t m_updateCounter;
float m_elapsedTime;
void OnUpdate(float elapsedTime) override void OnUpdate(float elapsedTime) override
{ {
++m_updateCounter;
m_elapsedTime += elapsedTime;
} }
}; };
@ -35,16 +45,63 @@ SCENARIO("System", "[NDK][SYSTEM]")
{ {
GIVEN("Our TestSystem") GIVEN("Our TestSystem")
{ {
TestSystem testSystem(666); TestSystem testSystem;
testSystem.SetMaximumUpdateRate(30.f);
WHEN("We clone it") float maxTimePerFrame = 1 / 30.f;
WHEN("We update it with a higher framerate")
{ {
std::unique_ptr<Ndk::BaseSystem> clone = testSystem.Clone(); float timePerFrame = maxTimePerFrame / 2.f;
float elapsedTime = 2.f;
THEN("We should get a copy") std::size_t loopCount = static_cast<std::size_t>(std::round(elapsedTime / timePerFrame));
for (std::size_t i = 0; i < loopCount; ++i)
testSystem.Update(timePerFrame);
CHECK(testSystem.GetLoopCount() == loopCount / 2);
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime).epsilon(timePerFrame));
}
WHEN("We update it with a lower framerate")
{
float timePerFrame = maxTimePerFrame * 2.f;
float elapsedTime = 10.f;
std::size_t loopCount = static_cast<std::size_t>(std::round(elapsedTime / timePerFrame));
for (std::size_t i = 0; i < loopCount; ++i)
testSystem.Update(timePerFrame);
CHECK(testSystem.GetLoopCount() == loopCount);
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime).epsilon(timePerFrame));
AND_WHEN("We suddenly increase framerate")
{ {
REQUIRE(static_cast<TestSystem*>(clone.get())->GetValue() == 666); float newTimePerFrame = 1 / 300.f;
float newElapsedTime = 100.f;
std::size_t newLoopCount = static_cast<std::size_t>(std::round(newElapsedTime / newTimePerFrame));
for (std::size_t i = 0; i < newLoopCount; ++i)
testSystem.Update(newTimePerFrame);
CHECK(testSystem.GetLoopCount() == loopCount + newLoopCount / 10);
CHECK(testSystem.GetElapsedTime() == Approx(elapsedTime + newElapsedTime).epsilon(newTimePerFrame));
} }
} }
WHEN("We update it with a very low framerate")
{
float timePerFrame = 0.5f;
for (std::size_t i = 0; i < 10; ++i)
testSystem.Update(timePerFrame);
CHECK(testSystem.GetLoopCount() == 10);
CHECK(testSystem.GetElapsedTime() == Approx(5.f));
}
} }
}*/ }

View File

@ -19,7 +19,7 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent<Ndk::NodeComponent>(); Ndk::NodeComponent& nodeComponent = movingEntity->GetComponent<Ndk::NodeComponent>();
Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent<Ndk::PhysicsComponent2D>(); Ndk::PhysicsComponent2D& physicsComponent2D = movingEntity->AddComponent<Ndk::PhysicsComponent2D>();
world.GetSystem<Ndk::PhysicsSystem2D>().SetFixedUpdateRate(30.f); world.GetSystem<Ndk::PhysicsSystem2D>().SetMaximumUpdateRate(0.f);
WHEN("We update the world") WHEN("We update the world")
{ {
@ -43,7 +43,7 @@ SCENARIO("PhysicsSystem2D", "[NDK][PHYSICSSYSTEM2D]")
world.Update(1.f); world.Update(1.f);
THEN("It should moved freely") THEN("It should move freely")
{ {
REQUIRE(nodeComponent.GetPosition() == position); REQUIRE(nodeComponent.GetPosition() == position);
movingAABB.Translate(position); movingAABB.Translate(position);