2014-10-14 13:11:37 +00:00
|
|
|
/*
|
|
|
|
* This file is part of the Colobot: Gold Edition source code
|
2020-07-07 08:19:36 +00:00
|
|
|
* Copyright (C) 2001-2020, Daniel Roux, EPSITEC SA & TerranovaTeam
|
2015-08-22 14:40:02 +00:00
|
|
|
* http://epsitec.ch; http://colobot.info; http://github.com/colobot
|
2014-10-14 13:11:37 +00:00
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see http://gnu.org/licenses
|
|
|
|
*/
|
2015-05-12 22:52:18 +00:00
|
|
|
|
2013-03-23 23:03:37 +00:00
|
|
|
#include "app/app.h"
|
|
|
|
|
2015-08-05 08:27:39 +00:00
|
|
|
#include "common/make_unique.h"
|
|
|
|
|
2016-07-24 12:38:49 +00:00
|
|
|
#include "common/system/system_other.h"
|
|
|
|
|
2015-05-12 22:52:18 +00:00
|
|
|
#include <functional>
|
|
|
|
#include <memory>
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
2015-05-12 22:52:18 +00:00
|
|
|
#include <hippomocks.h>
|
2013-03-23 23:03:37 +00:00
|
|
|
|
2015-05-12 22:52:18 +00:00
|
|
|
using namespace HippoMocks;
|
|
|
|
namespace ph = std::placeholders;
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
struct FakeSystemTimeStamp : public SystemTimeStamp
|
|
|
|
{
|
|
|
|
FakeSystemTimeStamp(int uid) : uid(uid), time(0) {}
|
|
|
|
|
|
|
|
int uid;
|
|
|
|
long long time;
|
|
|
|
};
|
|
|
|
|
|
|
|
class CApplicationWrapper : public CApplication
|
|
|
|
{
|
|
|
|
public:
|
2015-08-07 06:31:34 +00:00
|
|
|
CApplicationWrapper(CSystemUtils* systemUtils)
|
|
|
|
: CApplication(systemUtils)
|
2015-08-05 08:27:39 +00:00
|
|
|
{
|
|
|
|
SDL_Init(0);
|
|
|
|
m_eventQueue = MakeUnique<CEventQueue>();
|
|
|
|
}
|
|
|
|
|
|
|
|
~CApplicationWrapper()
|
|
|
|
{
|
|
|
|
SDL_Quit();
|
|
|
|
}
|
|
|
|
|
2017-08-06 10:03:28 +00:00
|
|
|
Event CreateUpdateEvent(SystemTimeStamp *timestamp) override
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2017-08-06 10:03:28 +00:00
|
|
|
return CApplication::CreateUpdateEvent(timestamp);
|
2013-03-23 23:03:37 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
class CApplicationUT : public testing::Test
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
protected:
|
2015-10-03 20:05:14 +00:00
|
|
|
CApplicationUT() :
|
2015-05-12 22:52:18 +00:00
|
|
|
m_systemUtils(nullptr),
|
|
|
|
m_stampUid(0),
|
|
|
|
m_currentTime(0)
|
|
|
|
{}
|
2013-03-23 23:03:37 +00:00
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
~CApplicationUT() NOEXCEPT
|
2015-05-12 22:52:18 +00:00
|
|
|
{}
|
|
|
|
|
2015-06-25 22:24:32 +00:00
|
|
|
void SetUp() override;
|
|
|
|
void TearDown() override;
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
void NextInstant(long long diff);
|
|
|
|
|
|
|
|
SystemTimeStamp* CreateTimeStamp();
|
|
|
|
void DestroyTimeStamp(SystemTimeStamp *stamp);
|
|
|
|
void CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src);
|
|
|
|
void GetCurrentTimeStamp(SystemTimeStamp *stamp);
|
|
|
|
long long TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after);
|
|
|
|
|
|
|
|
void TestCreateUpdateEvent(long long relTimeExact, long long absTimeExact,
|
|
|
|
float relTime, float absTime,
|
|
|
|
long long relTimeReal, long long absTimeReal);
|
|
|
|
|
|
|
|
protected:
|
2015-05-12 22:52:18 +00:00
|
|
|
std::unique_ptr<CApplicationWrapper> m_app;
|
|
|
|
MockRepository m_mocks;
|
|
|
|
CSystemUtils* m_systemUtils;
|
2015-08-07 06:31:34 +00:00
|
|
|
std::vector<std::unique_ptr<FakeSystemTimeStamp>> m_timeStamps;
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
int m_stampUid;
|
|
|
|
long long m_currentTime;
|
|
|
|
};
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::SetUp()
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2015-05-12 22:52:18 +00:00
|
|
|
m_systemUtils = m_mocks.Mock<CSystemUtils>();
|
2013-03-23 23:03:37 +00:00
|
|
|
|
2015-05-12 22:52:18 +00:00
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::GetDataPath).Return("");
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::GetLangPath).Return("");
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::GetSaveDir).Return("");
|
2013-03-23 23:03:37 +00:00
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::CreateTimeStamp).Do(std::bind(&CApplicationUT::CreateTimeStamp, this));
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::DestroyTimeStamp).Do(std::bind(&CApplicationUT::DestroyTimeStamp, this, ph::_1));
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::CopyTimeStamp).Do(std::bind(&CApplicationUT::CopyTimeStamp, this, ph::_1, ph::_2));
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::GetCurrentTimeStamp).Do(std::bind(&CApplicationUT::GetCurrentTimeStamp, this, ph::_1));
|
|
|
|
m_mocks.OnCall(m_systemUtils, CSystemUtils::TimeStampExactDiff).Do(std::bind(&CApplicationUT::TimeStampExactDiff, this, ph::_1, ph::_2));
|
2015-05-12 22:52:18 +00:00
|
|
|
|
2015-08-07 06:31:34 +00:00
|
|
|
m_app = MakeUnique<CApplicationWrapper>(m_systemUtils);
|
2013-03-23 23:03:37 +00:00
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::TearDown()
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app.reset();
|
2013-03-23 23:03:37 +00:00
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
SystemTimeStamp* CApplicationUT::CreateTimeStamp()
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2015-08-07 06:31:34 +00:00
|
|
|
auto stamp = MakeUnique<FakeSystemTimeStamp>(++m_stampUid);
|
|
|
|
auto stampPtr = stamp.get();
|
|
|
|
m_timeStamps.push_back(std::move(stamp));
|
|
|
|
return stampPtr;
|
2013-03-23 23:03:37 +00:00
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::DestroyTimeStamp(SystemTimeStamp *stamp)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::CopyTimeStamp(SystemTimeStamp *dst, SystemTimeStamp *src)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
*static_cast<FakeSystemTimeStamp*>(dst) = *static_cast<FakeSystemTimeStamp*>(src);
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::GetCurrentTimeStamp(SystemTimeStamp *stamp)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
static_cast<FakeSystemTimeStamp*>(stamp)->time = m_currentTime;
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
long long CApplicationUT::TimeStampExactDiff(SystemTimeStamp *before, SystemTimeStamp *after)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
return static_cast<FakeSystemTimeStamp*>(after)->time - static_cast<FakeSystemTimeStamp*>(before)->time;
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::NextInstant(long long diff)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
m_currentTime += diff;
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
void CApplicationUT::TestCreateUpdateEvent(long long relTimeExact, long long absTimeExact,
|
|
|
|
float relTime, float absTime,
|
|
|
|
long long relTimeReal, long long absTimeReal)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2017-08-06 10:03:28 +00:00
|
|
|
SystemTimeStamp *now = CreateTimeStamp();
|
|
|
|
GetCurrentTimeStamp(now);
|
|
|
|
Event event = m_app->CreateUpdateEvent(now);
|
2013-03-23 23:03:37 +00:00
|
|
|
EXPECT_EQ(EVENT_FRAME, event.type);
|
|
|
|
EXPECT_FLOAT_EQ(relTime, event.rTime);
|
2015-05-12 22:52:18 +00:00
|
|
|
EXPECT_FLOAT_EQ(relTime, m_app->GetRelTime());
|
|
|
|
EXPECT_FLOAT_EQ(absTime, m_app->GetAbsTime());
|
|
|
|
EXPECT_EQ(relTimeExact, m_app->GetExactRelTime());
|
|
|
|
EXPECT_EQ(absTimeExact, m_app->GetExactAbsTime());
|
|
|
|
EXPECT_EQ(relTimeReal, m_app->GetRealRelTime());
|
|
|
|
EXPECT_EQ(absTimeReal, m_app->GetRealAbsTime());
|
2013-03-23 23:03:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
TEST_F(CApplicationUT, UpdateEventTimeCalculation_SimulationSuspended)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->SuspendSimulation();
|
2017-08-06 10:03:28 +00:00
|
|
|
|
|
|
|
SystemTimeStamp *now = CreateTimeStamp();
|
|
|
|
GetCurrentTimeStamp(now);
|
|
|
|
Event event = m_app->CreateUpdateEvent(now);
|
|
|
|
|
2013-03-23 23:03:37 +00:00
|
|
|
EXPECT_EQ(EVENT_NULL, event.type);
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
TEST_F(CApplicationUT, UpdateEventTimeCalculation_NormalOperation)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
// 1st update
|
|
|
|
|
|
|
|
long long relTimeExact = 1111;
|
|
|
|
long long absTimeExact = relTimeExact;
|
|
|
|
float relTime = relTimeExact / 1e9f;
|
|
|
|
float absTime = absTimeExact / 1e9f;
|
|
|
|
long long relTimeReal = relTimeExact;
|
|
|
|
long long absTimeReal = absTimeExact;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 2nd update
|
|
|
|
|
|
|
|
relTimeExact = 2222;
|
|
|
|
absTimeExact += relTimeExact;
|
|
|
|
relTime = relTimeExact / 1e9f;
|
|
|
|
absTime = absTimeExact / 1e9f;
|
|
|
|
relTimeReal = relTimeExact;
|
|
|
|
absTimeReal = absTimeExact;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
TEST_F(CApplicationUT, UpdateEventTimeCalculation_NegativeTimeOperation)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
// 1st update
|
|
|
|
|
|
|
|
long long relTimeExact = 2222;
|
|
|
|
long long absTimeExact = relTimeExact;
|
|
|
|
float relTime = relTimeExact / 1e9f;
|
|
|
|
float absTime = absTimeExact / 1e9f;
|
|
|
|
long long relTimeReal = relTimeExact;
|
|
|
|
long long absTimeReal = absTimeExact;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 2nd update
|
|
|
|
|
|
|
|
NextInstant(-1111);
|
|
|
|
|
2017-08-06 10:03:28 +00:00
|
|
|
SystemTimeStamp *now = CreateTimeStamp();
|
|
|
|
GetCurrentTimeStamp(now);
|
|
|
|
Event event = m_app->CreateUpdateEvent(now);
|
2013-03-23 23:03:37 +00:00
|
|
|
EXPECT_EQ(EVENT_NULL, event.type);
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
TEST_F(CApplicationUT, UpdateEventTimeCalculation_ChangingSimulationSpeed)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->SetSimulationSpeed(2.0f);
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
// 1st update -- speed 2x
|
|
|
|
|
|
|
|
long long relTimeReal = 100;
|
|
|
|
long long absTimeReal = relTimeReal;
|
|
|
|
long long relTimeExact = relTimeReal*2;
|
|
|
|
long long absTimeExact = absTimeReal*2;
|
|
|
|
float relTime = relTimeExact / 1e9f;
|
|
|
|
float absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 2nd update -- speed 2x
|
|
|
|
|
|
|
|
relTimeReal = 200;
|
|
|
|
absTimeReal += relTimeReal;
|
|
|
|
relTimeExact = relTimeReal*2;
|
|
|
|
absTimeExact += relTimeReal*2;
|
|
|
|
relTime = relTimeExact / 1e9f;
|
|
|
|
absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 3rd update -- speed 4x
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->SetSimulationSpeed(4.0f);
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
relTimeReal = 300;
|
|
|
|
absTimeReal += relTimeReal;
|
|
|
|
relTimeExact = relTimeReal*4;
|
|
|
|
absTimeExact += relTimeReal*4;
|
|
|
|
relTime = relTimeExact / 1e9f;
|
|
|
|
absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 4th update -- speed 1x
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->SetSimulationSpeed(1.0f);
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
relTimeReal = 400;
|
|
|
|
absTimeReal += relTimeReal;
|
|
|
|
relTimeExact = relTimeReal;
|
|
|
|
absTimeExact += relTimeReal;
|
|
|
|
relTime = relTimeExact / 1e9f;
|
|
|
|
absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
}
|
|
|
|
|
2015-10-03 20:05:14 +00:00
|
|
|
TEST_F(CApplicationUT, UpdateEventTimeCalculation_SuspendingAndResumingSimulation)
|
2013-03-23 23:03:37 +00:00
|
|
|
{
|
|
|
|
// 1st update -- simulation enabled
|
|
|
|
|
|
|
|
long long relTimeReal = 1000;
|
|
|
|
long long absTimeReal = relTimeReal;
|
|
|
|
long long relTimeExact = relTimeReal;
|
|
|
|
long long absTimeExact = absTimeReal;
|
|
|
|
float relTime = relTimeExact / 1e9f;
|
|
|
|
float absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
|
|
|
|
// 2nd update -- simulation suspended
|
|
|
|
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->SuspendSimulation();
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
long long suspensionTime = 5000;
|
|
|
|
|
|
|
|
NextInstant(suspensionTime);
|
|
|
|
|
|
|
|
// 3rd update -- simulation resumed
|
|
|
|
|
2015-05-12 22:52:18 +00:00
|
|
|
m_app->ResumeSimulation();
|
2013-03-23 23:03:37 +00:00
|
|
|
|
|
|
|
relTimeReal = 200;
|
|
|
|
absTimeReal += relTimeReal;
|
|
|
|
relTimeExact = relTimeReal;
|
|
|
|
absTimeExact += relTimeReal;
|
|
|
|
relTime = relTimeExact / 1e9f;
|
|
|
|
absTime = absTimeExact / 1e9f;
|
|
|
|
|
|
|
|
NextInstant(relTimeReal);
|
|
|
|
|
|
|
|
TestCreateUpdateEvent(relTimeExact, absTimeExact, relTime, absTime, relTimeReal, absTimeReal);
|
|
|
|
}
|