Merge branch 'refactor/6677-2' into 'master'

Introduce IndexedVector

See merge request OpenMW/openmw!1733
This commit is contained in:
psi29a 2022-04-04 13:56:20 +00:00
commit ca77ae336f
8 changed files with 305 additions and 9 deletions

View file

@ -1057,9 +1057,11 @@ namespace MWMechanics
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if (!anim)
return;
mActors.emplace(ptr, new Actor(ptr, anim));
CharacterController* ctrl = mActors[ptr]->getCharacterController();
auto* newActor = new Actor(ptr, anim);
mActors.emplace(ptr, newActor);
CharacterController* ctrl = newActor->getCharacterController();
if (updateImmediately)
ctrl->update(0);
@ -1160,7 +1162,7 @@ namespace MWMechanics
mActors.erase(iter);
actor->updatePtr(ptr);
mActors.insert(std::make_pair(ptr, actor));
mActors.emplace(ptr, actor);
}
}
@ -1173,7 +1175,7 @@ namespace MWMechanics
{
removeTemporaryEffects(iter->first);
delete iter->second;
mActors.erase(iter++);
iter = mActors.erase(iter);
}
else
++iter;

View file

@ -6,6 +6,7 @@
#include <string>
#include <list>
#include <map>
#include <components/misc/indexedvector.hpp>
#include "../mwmechanics/actorutil.hpp"
@ -62,7 +63,7 @@ namespace MWMechanics
Actors();
~Actors();
typedef std::map<MWWorld::Ptr,Actor*> PtrActorMap;
using PtrActorMap = Misc::IndexedVector<MWWorld::Ptr, Actor*, MWWorld::PtrHash>;
PtrActorMap::const_iterator begin() { return mActors.begin(); }
PtrActorMap::const_iterator end() { return mActors.end(); }

View file

@ -11,6 +11,8 @@
#include <optional>
#include <functional>
#include <components/misc/indexedvector.hpp>
#include <osg/Quat>
#include <osg/BoundingBox>
#include <osg/ref_ptr>
@ -55,7 +57,7 @@ namespace MWPhysics
class PhysicsTaskScheduler;
class Projectile;
using ActorMap = std::unordered_map<const MWWorld::LiveCellRefBase*, std::shared_ptr<Actor>>;
using ActorMap = Misc::IndexedVector<const MWWorld::LiveCellRefBase*, std::shared_ptr<Actor>>;
struct ContactPoint
{
@ -299,8 +301,9 @@ namespace MWPhysics
using ObjectMap = std::unordered_map<const MWWorld::LiveCellRefBase*, std::shared_ptr<Object>>;
ObjectMap mObjects;
std::map<Object*, bool> mAnimatedObjects; // stores pointers to elements in mObjects
using AnimatedObjectMap = Misc::IndexedVector<Object*, bool>;
AnimatedObjectMap mAnimatedObjects; // stores pointers to elements in mObjects
ActorMap mActors;

View file

@ -6,6 +6,7 @@
#include <string>
#include <string_view>
#include <sstream>
#include <functional>
#include "livecellref.hpp"
@ -161,6 +162,20 @@ namespace MWWorld
ConstPtr(const LiveCellRefBase *liveCellRef=nullptr, const CellStoreType *cell=nullptr) : PtrBase(liveCellRef, cell, nullptr) {}
};
struct PtrHash
{
size_t operator()(const Ptr& ptr) const noexcept
{
const void* p = ptr;
return std::hash<const void*>{}(p);
}
size_t operator()(const ConstPtr& ptr) const noexcept
{
const void* p = ptr;
return std::hash<const void*>{}(p);
}
};
}
#endif

View file

@ -30,6 +30,7 @@ if (GTEST_FOUND AND GMOCK_FOUND)
misc/test_stringops.cpp
misc/test_endianness.cpp
misc/test_resourcehelpers.cpp
misc/test_indexedvector.cpp
misc/progressreporter.cpp
misc/compression.cpp

View file

@ -0,0 +1,88 @@
#include <components/misc/indexedvector.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <cstdint>
#include <vector>
namespace
{
TEST(IndexedVectorTests, basicInsert)
{
std::vector<std::pair<int, int>> vec;
Misc::IndexedVector<int, int> map;
for (int i = 0; i < 10000; i++)
{
vec.emplace_back(i, i << 13);
map.emplace(i, i << 13);
}
ASSERT_EQ(vec.size(), map.size());
auto itVec = vec.begin();
auto itMap = map.begin();
while (itMap != map.end() && itVec != vec.end())
{
ASSERT_EQ(itVec->first, itMap->first);
ASSERT_EQ(itVec->second, itMap->second);
itMap++;
itVec++;
}
}
TEST(IndexedVectorTests, duplicateInsert)
{
Misc::IndexedVector<int, int> map;
auto pairVal = map.emplace(1, 5);
ASSERT_EQ(map.size(), 1);
ASSERT_EQ(pairVal.first, map.begin());
ASSERT_EQ(pairVal.first->second, 5);
ASSERT_EQ(pairVal.second, true);
pairVal = map.emplace(1, 10);
ASSERT_EQ(map.size(), 1);
ASSERT_EQ(pairVal.first, map.begin());
ASSERT_EQ(pairVal.first->second, 5);
ASSERT_EQ(pairVal.second, false);
}
TEST(IndexedVectorTests, testErase)
{
Misc::IndexedVector<int, int> map;
for (int i = 0; i < 10000; i++)
{
map.emplace(i, i);
}
auto itA = map.find(100);
ASSERT_NE(itA, map.end());
ASSERT_EQ(itA->second, 100);
itA = map.erase(itA);
ASSERT_EQ(map.size(), 10000 - 1);
ASSERT_NE(itA, map.end());
ASSERT_EQ(itA->second, 101);
}
TEST(IndexedVectorTests, testLookup)
{
Misc::IndexedVector<int, int> map;
for (int i = 0; i < 10000; i++)
{
map.emplace(i, i);
}
auto itA = map.find(100);
ASSERT_NE(itA, map.end());
ASSERT_EQ(itA->second, 100);
map.erase(itA);
ASSERT_EQ(map.size(), 10000 - 1);
itA = map.find(101);
ASSERT_NE(itA, map.end());
ASSERT_EQ(itA->second, 101);
}
}