0ad/source/simulation2/components/tests/test_Position.h
Yves 7acdde5c86 Changes tests to use global g_ScriptRuntime instead of creating a new JSRuntime for each test.
The tests crashed on my Debian systems but not on my Ubuntu system.
The crash happened in line 142 of SpiderMonkey's ThreadLocal.h.

I know that I had to use a workarounnd for contexts to avoid destroying
the context that was created first. I also had in mind that in newer
versions a JS_Init function got introduced which presumably solves this
kind of issues.
Based on this experience I assumed runtimes could have a similar problem
and this patch indeed fixes the issues.
Unfortunately the correct usage of JSRuntimes in that regard is not
documented.
There's only a rater misterious comment in JSAPI.h which hasn't been
cleared up so far and is most likely completely outdated
(https://bugzilla.mozilla.org/show_bug.cgi?id=992641).

This was SVN commit r14995.
2014-04-25 21:19:51 +00:00

134 lines
5.1 KiB
C++

/* Copyright (C) 2010 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. 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 2 of the License, or
* (at your option) any later version.
*
* 0 A.D. 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 0 A.D. If not, see <http://www.gnu.org/licenses/>.
*/
#include "simulation2/system/ComponentTest.h"
#include "simulation2/components/ICmpPosition.h"
class TestCmpPosition : public CxxTest::TestSuite
{
public:
void setUp()
{
CXeromyces::Startup();
}
void tearDown()
{
CXeromyces::Terminate();
}
static CFixedVector3D fixedvec(int x, int y, int z)
{
return CFixedVector3D(fixed::FromInt(x), fixed::FromInt(y), fixed::FromInt(z));
}
void test_basic()
{
ComponentTestHelper test(g_ScriptRuntime);
MockTerrain terrain;
test.AddMock(SYSTEM_ENTITY, IID_Terrain, terrain);
ICmpPosition* cmp = test.Add<ICmpPosition>(CID_Position, "<Anchor>upright</Anchor><Altitude>23</Altitude><Floating>false</Floating>");
// Defaults
TS_ASSERT(!cmp->IsInWorld());
TS_ASSERT_EQUALS(cmp->GetHeightOffset(), entity_pos_t::FromInt(23));
TS_ASSERT_EQUALS(cmp->GetRotation(), fixedvec(0, 0, 0));
// Change height offset
cmp->SetHeightOffset(entity_pos_t::FromInt(10));
TS_ASSERT_EQUALS(cmp->GetHeightOffset(), entity_pos_t::FromInt(10));
// Move out of world, while currently out of world
cmp->MoveOutOfWorld();
TS_ASSERT(!cmp->IsInWorld());
// Jump into world
cmp->JumpTo(entity_pos_t::FromInt(0), entity_pos_t::FromInt(0));
TS_ASSERT(cmp->IsInWorld());
// Move out of world, while currently in world
cmp->MoveOutOfWorld();
TS_ASSERT(!cmp->IsInWorld());
// Move into world
cmp->MoveTo(entity_pos_t::FromInt(100), entity_pos_t::FromInt(200));
TS_ASSERT(cmp->IsInWorld());
// Position computed from move plus terrain
TS_ASSERT_EQUALS(cmp->GetPosition(), fixedvec(100, 60, 200));
// Interpolated position should be constant
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.0f, false).GetTranslation(), CVector3D(100, 60, 200));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.5f, false).GetTranslation(), CVector3D(100, 60, 200));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(1.0f, false).GetTranslation(), CVector3D(100, 60, 200));
// No TurnStart message, so this move doesn't affect the interpolation
cmp->MoveTo(entity_pos_t::FromInt(0), entity_pos_t::FromInt(0));
// Move smoothly to new position
cmp->MoveTo(entity_pos_t::FromInt(200), entity_pos_t::FromInt(0));
// Position computed from move plus terrain
TS_ASSERT_EQUALS(cmp->GetPosition(), fixedvec(200, 60, 0));
// Interpolated position should vary, from original move into world to new move
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.0f, false).GetTranslation(), CVector3D(100, 60, 200));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.5f, false).GetTranslation(), CVector3D(150, 60, 100));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(1.0f, false).GetTranslation(), CVector3D(200, 60, 0));
// Latch new position for interpolation
CMessageTurnStart msg;
test.HandleMessage(cmp, msg, false);
// Move smoothly to new position
cmp->MoveTo(entity_pos_t::FromInt(400), entity_pos_t::FromInt(300));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.0f, false).GetTranslation(), CVector3D(200, 60, 0));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.5f, false).GetTranslation(), CVector3D(300, 60, 150));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(1.0f, false).GetTranslation(), CVector3D(400, 60, 300));
// Jump to new position
cmp->JumpTo(entity_pos_t::FromInt(300), entity_pos_t::FromInt(100));
// Position computed from jump plus terrain
TS_ASSERT_EQUALS(cmp->GetPosition(), fixedvec(300, 60, 100));
// Interpolated position should be constant after jump
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.0f, false).GetTranslation(), CVector3D(300, 60, 100));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(0.5f, false).GetTranslation(), CVector3D(300, 60, 100));
TS_ASSERT_EQUALS(cmp->GetInterpolatedTransform(1.0f, false).GetTranslation(), CVector3D(300, 60, 100));
// TODO: Test the rotation methods
}
void test_serialize()
{
ComponentTestHelper test(g_ScriptRuntime);
MockTerrain terrain;
test.AddMock(SYSTEM_ENTITY, IID_Terrain, terrain);
ICmpPosition* cmp = test.Add<ICmpPosition>(CID_Position, "<Anchor>upright</Anchor><Altitude>5</Altitude><Floating>false</Floating>");
test.Roundtrip();
cmp->SetHeightOffset(entity_pos_t::FromInt(20));
cmp->SetXZRotation(entity_angle_t::FromInt(1), entity_angle_t::FromInt(2));
cmp->SetYRotation(entity_angle_t::FromInt(3));
test.Roundtrip();
cmp->JumpTo(entity_pos_t::FromInt(10), entity_pos_t::FromInt(20));
cmp->MoveTo(entity_pos_t::FromInt(123), entity_pos_t::FromInt(456));
test.Roundtrip();
}
};