1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-12-12 22:43:07 +00:00

Merge branch 'mechanics_objects_list' into 'master'

Use std::list to store mechanics objects

See merge request OpenMW/openmw!1881
This commit is contained in:
psi29a 2022-05-20 14:08:02 +00:00
commit 6b7c302102
3 changed files with 45 additions and 59 deletions

View file

@ -241,6 +241,8 @@ public:
CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim); CharacterController(const MWWorld::Ptr &ptr, MWRender::Animation *anim);
virtual ~CharacterController(); virtual ~CharacterController();
const MWWorld::Ptr& getPtr() const { return mPtr; };
void handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override; void handleTextKey(const std::string &groupname, SceneUtil::TextKeyMap::ConstIterator key, const SceneUtil::TextKeyMap& map) override;
// Be careful when to call this, see comment in Actors // Be careful when to call this, see comment in Actors

View file

@ -13,55 +13,43 @@
namespace MWMechanics namespace MWMechanics
{ {
Objects::~Objects()
{
for(auto& object : mObjects)
{
delete object.second;
object.second = nullptr;
}
}
void Objects::addObject(const MWWorld::Ptr& ptr) void Objects::addObject(const MWWorld::Ptr& ptr)
{ {
removeObject(ptr); removeObject(ptr);
MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr); MWRender::Animation *anim = MWBase::Environment::get().getWorld()->getAnimation(ptr);
if(anim) mObjects.insert(std::make_pair(ptr, new CharacterController(ptr, anim))); if (anim == nullptr)
return;
const auto it = mObjects.emplace(mObjects.end(), ptr, anim);
mIndex.emplace(ptr.getBase(), it);
} }
void Objects::removeObject(const MWWorld::Ptr& ptr) void Objects::removeObject(const MWWorld::Ptr& ptr)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); const auto iter = mIndex.find(ptr.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
{ {
delete iter->second; mObjects.erase(iter->second);
mObjects.erase(iter); mIndex.erase(iter);
} }
} }
void Objects::updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr) void Objects::updateObject(const MWWorld::Ptr &old, const MWWorld::Ptr &ptr)
{ {
PtrControllerMap::iterator iter = mObjects.find(old); const auto iter = mIndex.find(old.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
{ iter->second->updatePtr(ptr);
CharacterController *ctrl = iter->second;
mObjects.erase(iter);
ctrl->updatePtr(ptr);
mObjects.insert(std::make_pair(ptr, ctrl));
}
} }
void Objects::dropObjects (const MWWorld::CellStore *cellStore) void Objects::dropObjects (const MWWorld::CellStore *cellStore)
{ {
PtrControllerMap::iterator iter = mObjects.begin(); for (auto iter = mObjects.begin(); iter != mObjects.end();)
while(iter != mObjects.end())
{ {
if(iter->first.getCell()==cellStore) if (iter->getPtr().getCell() == cellStore)
{ {
delete iter->second; mIndex.erase(iter->getPtr().getBase());
mObjects.erase(iter++); iter = mObjects.erase(iter);
} }
else else
++iter; ++iter;
@ -72,8 +60,8 @@ void Objects::update(float duration, bool paused)
{ {
if(!paused) if(!paused)
{ {
for(auto& object : mObjects) for (CharacterController& object : mObjects)
object.second->update(duration); object.update(duration);
} }
else else
{ {
@ -82,15 +70,15 @@ void Objects::update(float duration, bool paused)
if(mode != MWGui::GM_Container) if(mode != MWGui::GM_Container)
return; return;
for(auto& object : mObjects) for (CharacterController& object : mObjects)
{ {
if (object.first.getType() != ESM::Container::sRecordId) if (object.getPtr().getType() != ESM::Container::sRecordId)
continue; continue;
if (object.second->isAnimPlaying("containeropen")) if (object.isAnimPlaying("containeropen"))
{ {
object.second->update(duration); object.update(duration);
MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.first); MWBase::Environment::get().getWorld()->updateAnimatedCollisionShape(object.getPtr());
} }
} }
} }
@ -98,23 +86,23 @@ void Objects::update(float duration, bool paused)
bool Objects::onOpen(const MWWorld::Ptr& ptr) bool Objects::onOpen(const MWWorld::Ptr& ptr)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); const auto iter = mIndex.find(ptr.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
return iter->second->onOpen(); return iter->second->onOpen();
return true; return true;
} }
void Objects::onClose(const MWWorld::Ptr& ptr) void Objects::onClose(const MWWorld::Ptr& ptr)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); const auto iter = mIndex.find(ptr.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
iter->second->onClose(); iter->second->onClose();
} }
bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist) bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number, bool persist)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); const auto iter = mIndex.find(ptr.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
{ {
return iter->second->playGroup(groupName, mode, number, persist); return iter->second->playGroup(groupName, mode, number, persist);
} }
@ -126,24 +114,22 @@ bool Objects::playAnimationGroup(const MWWorld::Ptr& ptr, const std::string& gro
} }
void Objects::skipAnimation(const MWWorld::Ptr& ptr) void Objects::skipAnimation(const MWWorld::Ptr& ptr)
{ {
PtrControllerMap::iterator iter = mObjects.find(ptr); const auto iter = mIndex.find(ptr.getBase());
if(iter != mObjects.end()) if (iter != mIndex.end())
iter->second->skipAnim(); iter->second->skipAnim();
} }
void Objects::persistAnimationStates() void Objects::persistAnimationStates()
{ {
for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) for (CharacterController& object : mObjects)
iter->second->persistAnimationState(); object.persistAnimationState();
} }
void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out) void Objects::getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out) const
{ {
for (PtrControllerMap::iterator iter = mObjects.begin(); iter != mObjects.end(); ++iter) for (const CharacterController& object : mObjects)
{ if ((position - object.getPtr().getRefData().getPosition().asVec3()).length2() <= radius * radius)
if ((position - iter->first.getRefData().getPosition().asVec3()).length2() <= radius*radius) out.push_back(object.getPtr());
out.push_back(iter->first);
}
} }
} }

View file

@ -1,9 +1,12 @@
#ifndef GAME_MWMECHANICS_ACTIVATORS_H #ifndef GAME_MWMECHANICS_ACTIVATORS_H
#define GAME_MWMECHANICS_ACTIVATORS_H #define GAME_MWMECHANICS_ACTIVATORS_H
#include "character.hpp"
#include <string> #include <string>
#include <map> #include <map>
#include <vector> #include <vector>
#include <list>
namespace osg namespace osg
{ {
@ -18,17 +21,12 @@ namespace MWWorld
namespace MWMechanics namespace MWMechanics
{ {
class CharacterController;
class Objects class Objects
{ {
typedef std::map<MWWorld::Ptr,CharacterController*> PtrControllerMap; std::list<CharacterController> mObjects;
PtrControllerMap mObjects; std::map<const MWWorld::LiveCellRefBase*, std::list<CharacterController>::iterator> mIndex;
public: public:
Objects() = default;
~Objects();
void addObject (const MWWorld::Ptr& ptr); void addObject (const MWWorld::Ptr& ptr);
///< Register an animated object ///< Register an animated object
@ -51,7 +49,7 @@ namespace MWMechanics
void skipAnimation(const MWWorld::Ptr& ptr); void skipAnimation(const MWWorld::Ptr& ptr);
void persistAnimationStates(); void persistAnimationStates();
void getObjectsInRange (const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out); void getObjectsInRange(const osg::Vec3f& position, float radius, std::vector<MWWorld::Ptr>& out) const;
std::size_t size() const std::size_t size() const
{ {