mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-01-30 03:32:36 +00:00
84944a7530
Direct leak of 16197408 byte(s) in 56241 object(s) allocated from: #0 0x5572356d4d42 in operator new(unsigned long) (/home/elsid/dev/openmw/build/clang/asan/openmw+0xae0d42) #1 0x557236938196 in (anonymous namespace)::addObject(MWWorld::Ptr const&, MWWorld::World const&, std::__1::vector<ESM::RefNum, std::__1::allocator<ESM::RefNum> > const&, MWPhysics::PhysicsSystem&, MWRender::RenderingManager&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:119:42 #2 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7::operator()(MWWorld::Ptr const&) const /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:62 #3 0x55723692e51b in void (anonymous namespace)::InsertVisitor::insert<MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7>(MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7&&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:230:21 #4 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:23 #5 0x55723692d451 in MWWorld::Scene::loadCell(MWWorld::CellStore*, Loading::Listener*, bool, osg::Vec3f const&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:449:9 #6 0x5572369299f5 in MWWorld::Scene::changeCellGrid(osg::Vec3f const&, int, int, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:612:17 #7 0x557236928521 in MWWorld::Scene::update(float) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:315:13 #8 0x5572368d4c98 in MWWorld::World::update(float, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1833:22 #9 0x557236ebbb72 in OMW::Engine::frame(float) /home/elsid/dev/openmw/apps/openmw/engine.cpp:418:25 #10 0x557236ed250a in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1102:14 #11 0x557236eb621a in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228:17 #12 0x55723774d622 in wrapApplication(int (*)(int, char**), int, char**, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) /home/elsid/dev/openmw/components/debug/debugging.cpp:328:19 #13 0x557236eb651f in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240:12 #14 0x7fbf58a3f2cf (/usr/lib/libc.so.6+0x232cf) (BuildId: e637217a46491314667a7a37b2155cb07afc1a40) Direct leak of 396288 byte(s) in 1376 object(s) allocated from: #0 0x5572356d4d42 in operator new(unsigned long) (/home/elsid/dev/openmw/build/clang/asan/openmw+0xae0d42) #1 0x557236938196 in (anonymous namespace)::addObject(MWWorld::Ptr const&, MWWorld::World const&, std::__1::vector<ESM::RefNum, std::__1::allocator<ESM::RefNum> > const&, MWPhysics::PhysicsSystem&, MWRender::RenderingManager&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:119:42 #2 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7::operator()(MWWorld::Ptr const&) const /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:62 #3 0x55723692e51b in void (anonymous namespace)::InsertVisitor::insert<MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7>(MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*)::$_7&&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:230:21 #4 0x55723692e51b in MWWorld::Scene::insertCell(MWWorld::CellStore&, Loading::Listener*) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:913:23 #5 0x55723692d451 in MWWorld::Scene::loadCell(MWWorld::CellStore*, Loading::Listener*, bool, osg::Vec3f const&) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:449:9 #6 0x5572369299f5 in MWWorld::Scene::changeCellGrid(osg::Vec3f const&, int, int, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:612:17 #7 0x557236936eb2 in MWWorld::Scene::changeToExteriorCell(ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/scene.cpp:888:9 #8 0x55723689a5ac in MWWorld::World::changeToExteriorCell(ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1003:22 #9 0x5572368c249d in MWWorld::World::changeToCell(ESM::CellId const&, ESM::Position const&, bool, bool) /home/elsid/dev/openmw/apps/openmw/mwworld/worldimp.cpp:1014:13 #10 0x557236e9bbce in MWState::StateManager::loadGame(MWState::Character const*, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:545:52 #11 0x557236e998db in MWState::StateManager::loadGame(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) /home/elsid/dev/openmw/apps/openmw/mwstate/statemanagerimp.cpp:377:17 #12 0x557236ed18fb in OMW::Engine::go() /home/elsid/dev/openmw/apps/openmw/engine.cpp:1066:24 #13 0x557236eb621a in runApplication(int, char**) /home/elsid/dev/openmw/apps/openmw/main.cpp:228:17 #14 0x55723774d622 in wrapApplication(int (*)(int, char**), int, char**, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool) /home/elsid/dev/openmw/components/debug/debugging.cpp:328:19 #15 0x557236eb651f in main /home/elsid/dev/openmw/apps/openmw/main.cpp:240:12 #16 0x7fbf58a3f2cf (/usr/lib/libc.so.6+0x232cf) (BuildId: e637217a46491314667a7a37b2155cb07afc1a40)
299 lines
7.2 KiB
C++
299 lines
7.2 KiB
C++
#include "refdata.hpp"
|
|
|
|
#include <components/esm3/objectstate.hpp>
|
|
#include <components/sceneutil/positionattitudetransform.hpp>
|
|
|
|
#include "customdata.hpp"
|
|
#include "cellstore.hpp"
|
|
|
|
#include "../mwbase/environment.hpp"
|
|
#include "../mwbase/world.hpp"
|
|
|
|
#include "../mwlua/localscripts.hpp"
|
|
|
|
namespace
|
|
{
|
|
enum RefDataFlags
|
|
{
|
|
Flag_SuppressActivate = 1, // If set, activation will be suppressed and redirected to the OnActivate flag, which can then be handled by a script.
|
|
Flag_OnActivate = 2,
|
|
Flag_ActivationBuffered = 4
|
|
};
|
|
}
|
|
|
|
namespace MWWorld
|
|
{
|
|
|
|
void RefData::setLuaScripts(std::shared_ptr<MWLua::LocalScripts>&& scripts)
|
|
{
|
|
mChanged = true;
|
|
mLuaScripts = std::move(scripts);
|
|
}
|
|
|
|
void RefData::copy (const RefData& refData)
|
|
{
|
|
mBaseNode = refData.mBaseNode;
|
|
mLocals = refData.mLocals;
|
|
mEnabled = refData.mEnabled;
|
|
mCount = refData.mCount;
|
|
mPosition = refData.mPosition;
|
|
mChanged = refData.mChanged;
|
|
mDeletedByContentFile = refData.mDeletedByContentFile;
|
|
mFlags = refData.mFlags;
|
|
mPhysicsPostponed = refData.mPhysicsPostponed;
|
|
|
|
mAnimationState = refData.mAnimationState;
|
|
|
|
mCustomData = refData.mCustomData ? refData.mCustomData->clone() : nullptr;
|
|
mLuaScripts = refData.mLuaScripts;
|
|
}
|
|
|
|
void RefData::cleanup()
|
|
{
|
|
mBaseNode = nullptr;
|
|
mCustomData = nullptr;
|
|
mLuaScripts = nullptr;
|
|
}
|
|
|
|
RefData::RefData()
|
|
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mPhysicsPostponed(false), mCount (1), mCustomData (nullptr), mChanged(false), mFlags(0)
|
|
{
|
|
for (int i=0; i<3; ++i)
|
|
{
|
|
mPosition.pos[i] = 0;
|
|
mPosition.rot[i] = 0;
|
|
}
|
|
}
|
|
|
|
RefData::RefData (const ESM::CellRef& cellRef)
|
|
: mBaseNode(nullptr), mDeletedByContentFile(false), mEnabled (true), mPhysicsPostponed(false),
|
|
mCount (1), mPosition (cellRef.mPos),
|
|
mCustomData (nullptr),
|
|
mChanged(false), mFlags(0) // Loading from ESM/ESP files -> assume unchanged
|
|
{
|
|
}
|
|
|
|
RefData::RefData (const ESM::ObjectState& objectState, bool deletedByContentFile)
|
|
: mBaseNode(nullptr), mDeletedByContentFile(deletedByContentFile),
|
|
mEnabled (objectState.mEnabled != 0), mPhysicsPostponed(false),
|
|
mCount (objectState.mCount),
|
|
mPosition (objectState.mPosition),
|
|
mAnimationState(objectState.mAnimationState),
|
|
mCustomData (nullptr),
|
|
mChanged(true), mFlags(objectState.mFlags) // Loading from a savegame -> assume changed
|
|
{
|
|
// "Note that the ActivationFlag_UseEnabled is saved to the reference,
|
|
// which will result in permanently suppressed activation if the reference script is removed.
|
|
// This occurred when removing the animated containers mod, and the fix in MCP is to reset UseEnabled to true on loading a game."
|
|
mFlags &= (~Flag_SuppressActivate);
|
|
}
|
|
|
|
RefData::RefData (const RefData& refData)
|
|
: mBaseNode(nullptr), mCustomData (nullptr)
|
|
{
|
|
try
|
|
{
|
|
copy (refData);
|
|
mFlags &= ~(Flag_SuppressActivate|Flag_OnActivate|Flag_ActivationBuffered);
|
|
}
|
|
catch (...)
|
|
{
|
|
cleanup();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void RefData::write(ESM::ObjectState& objectState, std::string_view scriptId) const
|
|
{
|
|
objectState.mHasLocals = mLocals.write (objectState.mLocals, scriptId);
|
|
|
|
objectState.mEnabled = mEnabled;
|
|
objectState.mCount = mCount;
|
|
objectState.mPosition = mPosition;
|
|
objectState.mFlags = mFlags;
|
|
|
|
objectState.mAnimationState = mAnimationState;
|
|
}
|
|
|
|
RefData& RefData::operator= (const RefData& refData)
|
|
{
|
|
try
|
|
{
|
|
cleanup();
|
|
copy (refData);
|
|
}
|
|
catch (...)
|
|
{
|
|
cleanup();
|
|
throw;
|
|
}
|
|
|
|
return *this;
|
|
}
|
|
|
|
RefData::~RefData()
|
|
{
|
|
try
|
|
{
|
|
cleanup();
|
|
}
|
|
catch (...)
|
|
{}
|
|
}
|
|
|
|
RefData::RefData(RefData&& other) = default;
|
|
RefData& RefData::operator=(RefData&& other) = default;
|
|
|
|
void RefData::setBaseNode(osg::ref_ptr<SceneUtil::PositionAttitudeTransform> base)
|
|
{
|
|
mBaseNode = std::move(base);
|
|
}
|
|
|
|
SceneUtil::PositionAttitudeTransform* RefData::getBaseNode()
|
|
{
|
|
return mBaseNode;
|
|
}
|
|
|
|
const SceneUtil::PositionAttitudeTransform* RefData::getBaseNode() const
|
|
{
|
|
return mBaseNode;
|
|
}
|
|
|
|
int RefData::getCount(bool absolute) const
|
|
{
|
|
if(absolute)
|
|
return std::abs(mCount);
|
|
return mCount;
|
|
}
|
|
|
|
void RefData::setLocals (const ESM::Script& script)
|
|
{
|
|
if (mLocals.configure (script) && !mLocals.isEmpty())
|
|
mChanged = true;
|
|
}
|
|
|
|
void RefData::setCount (int count)
|
|
{
|
|
if(count == 0)
|
|
MWBase::Environment::get().getWorld()->removeRefScript(this);
|
|
|
|
mChanged = true;
|
|
|
|
mCount = count;
|
|
}
|
|
|
|
void RefData::setDeletedByContentFile(bool deleted)
|
|
{
|
|
mDeletedByContentFile = deleted;
|
|
}
|
|
|
|
bool RefData::isDeleted() const
|
|
{
|
|
return mDeletedByContentFile || mCount == 0;
|
|
}
|
|
|
|
bool RefData::isDeletedByContentFile() const
|
|
{
|
|
return mDeletedByContentFile;
|
|
}
|
|
|
|
MWScript::Locals& RefData::getLocals()
|
|
{
|
|
return mLocals;
|
|
}
|
|
|
|
bool RefData::isEnabled() const
|
|
{
|
|
return mEnabled;
|
|
}
|
|
|
|
void RefData::enable()
|
|
{
|
|
if (!mEnabled)
|
|
{
|
|
mChanged = true;
|
|
mEnabled = true;
|
|
}
|
|
}
|
|
|
|
void RefData::disable()
|
|
{
|
|
if (mEnabled)
|
|
{
|
|
mChanged = true;
|
|
mEnabled = false;
|
|
}
|
|
}
|
|
|
|
void RefData::setPosition(const ESM::Position& pos)
|
|
{
|
|
mChanged = true;
|
|
mPosition = pos;
|
|
}
|
|
|
|
const ESM::Position& RefData::getPosition() const
|
|
{
|
|
return mPosition;
|
|
}
|
|
|
|
void RefData::setCustomData(std::unique_ptr<CustomData>&& value) noexcept
|
|
{
|
|
mChanged = true; // We do not currently track CustomData, so assume anything with a CustomData is changed
|
|
mCustomData = std::move(value);
|
|
}
|
|
|
|
CustomData *RefData::getCustomData()
|
|
{
|
|
return mCustomData.get();
|
|
}
|
|
|
|
const CustomData *RefData::getCustomData() const
|
|
{
|
|
return mCustomData.get();
|
|
}
|
|
|
|
bool RefData::hasChanged() const
|
|
{
|
|
return mChanged || !mAnimationState.empty();
|
|
}
|
|
|
|
bool RefData::activateByScript()
|
|
{
|
|
bool ret = (mFlags & Flag_ActivationBuffered);
|
|
mFlags &= ~(Flag_SuppressActivate|Flag_OnActivate);
|
|
return ret;
|
|
}
|
|
|
|
bool RefData::activate()
|
|
{
|
|
if (mFlags & Flag_SuppressActivate)
|
|
{
|
|
mFlags |= Flag_OnActivate|Flag_ActivationBuffered;
|
|
return false;
|
|
}
|
|
else
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
bool RefData::onActivate()
|
|
{
|
|
bool ret = mFlags & Flag_OnActivate;
|
|
mFlags |= Flag_SuppressActivate;
|
|
mFlags &= (~Flag_OnActivate);
|
|
return ret;
|
|
}
|
|
|
|
const ESM::AnimationState& RefData::getAnimationState() const
|
|
{
|
|
return mAnimationState;
|
|
}
|
|
|
|
ESM::AnimationState& RefData::getAnimationState()
|
|
{
|
|
return mAnimationState;
|
|
}
|
|
|
|
}
|