(Re)set the inventory listener outside of the Animation class

pull/164/head
scrawl 8 years ago
parent 8f79fa3d72
commit a5247394dc

@ -26,10 +26,8 @@
namespace MWRender namespace MWRender
{ {
ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem)
bool disableListener) : Animation(ptr, parentNode, resourceSystem)
: Animation(ptr, parentNode, resourceSystem),
mListenerDisabled(disableListener)
{ {
MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr); MWWorld::ContainerStore& store = mPtr.getClass().getContainerStore(mPtr);
@ -41,16 +39,10 @@ ActorAnimation::ActorAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group>
addHiddenItemLight(*iter, light); addHiddenItemLight(*iter, light);
} }
} }
if (!mListenerDisabled)
store.setContListener(this);
} }
ActorAnimation::~ActorAnimation() ActorAnimation::~ActorAnimation()
{ {
if (!mListenerDisabled && mPtr.getRefData().getCustomData() && mPtr.getClass().getContainerStore(mPtr).getContListener() == this)
mPtr.getClass().getContainerStore(mPtr).setContListener(NULL);
for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter) for (ItemLightMap::iterator iter = mItemLights.begin(); iter != mItemLights.end(); ++iter)
{ {
mInsert->removeChild(iter->second); mInsert->removeChild(iter->second);

@ -31,8 +31,7 @@ namespace MWRender
class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener
{ {
public: public:
ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, ActorAnimation(const MWWorld::Ptr &ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem);
bool disableListener=false);
virtual ~ActorAnimation(); virtual ~ActorAnimation();
virtual void itemAdded(const MWWorld::ConstPtr& item, int count); virtual void itemAdded(const MWWorld::ConstPtr& item, int count);
@ -44,8 +43,6 @@ class ActorAnimation : public Animation, public MWWorld::ContainerStoreListener
typedef std::map<MWWorld::ConstPtr, osg::ref_ptr<SceneUtil::LightSource> > ItemLightMap; typedef std::map<MWWorld::ConstPtr, osg::ref_ptr<SceneUtil::LightSource> > ItemLightMap;
ItemLightMap mItemLights; ItemLightMap mItemLights;
bool mListenerDisabled;
}; };
} }

@ -464,6 +464,11 @@ namespace MWRender
return mPtr; return mPtr;
} }
MWWorld::Ptr Animation::getPtr()
{
return mPtr;
}
void Animation::setActive(bool active) void Animation::setActive(bool active)
{ {
if (mSkeleton) if (mSkeleton)

@ -343,6 +343,8 @@ public:
MWWorld::ConstPtr getPtr() const; MWWorld::ConstPtr getPtr() const;
MWWorld::Ptr getPtr();
/// Set active flag on the object skeleton, if one exists. /// Set active flag on the object skeleton, if one exists.
/// @see SceneUtil::Skeleton::setActive /// @see SceneUtil::Skeleton::setActive
void setActive(bool active); void setActive(bool active);

@ -220,7 +220,7 @@ namespace MWRender
{ {
mAnimation.reset(NULL); mAnimation.reset(NULL);
mAnimation.reset(new NpcAnimation(mCharacter, mNode, mResourceSystem, true, true, mAnimation.reset(new NpcAnimation(mCharacter, mNode, mResourceSystem, true,
(renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal))); (renderHeadOnly() ? NpcAnimation::VM_HeadOnly : NpcAnimation::VM_Normal)));
onSetup(); onSetup();

@ -269,13 +269,6 @@ const NpcAnimation::PartBoneMap NpcAnimation::sPartList = createPartListMap();
NpcAnimation::~NpcAnimation() NpcAnimation::~NpcAnimation()
{ {
if (!mListenerDisabled
// No need to getInventoryStore() to reset, if none exists
// This is to avoid triggering the listener via ensureCustomData()->autoEquip()->fireEquipmentChanged()
// all from within this destructor. ouch!
&& mPtr.getRefData().getCustomData() && mPtr.getClass().getInventoryStore(mPtr).getInvListener() == this)
mPtr.getClass().getInventoryStore(mPtr).setInvListener(NULL, mPtr);
// do not detach (delete) parts yet, this is done so the background thread can handle the deletion // do not detach (delete) parts yet, this is done so the background thread can handle the deletion
for(size_t i = 0;i < ESM::PRT_Count;i++) for(size_t i = 0;i < ESM::PRT_Count;i++)
{ {
@ -285,9 +278,8 @@ NpcAnimation::~NpcAnimation()
} }
NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
bool disableListener, bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView) bool disableSounds, ViewMode viewMode, float firstPersonFieldOfView)
: ActorAnimation(ptr, parentNode, resourceSystem, disableListener), : ActorAnimation(ptr, parentNode, resourceSystem),
mListenerDisabled(disableListener),
mViewMode(viewMode), mViewMode(viewMode),
mShowWeapons(false), mShowWeapons(false),
mShowCarriedLeft(true), mShowCarriedLeft(true),
@ -309,9 +301,6 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> par
} }
updateNpcBase(); updateNpcBase();
if (!disableListener)
mPtr.getClass().getInventoryStore(mPtr).setInvListener(this, mPtr);
} }
void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode) void NpcAnimation::setViewMode(NpcAnimation::ViewMode viewMode)

@ -38,8 +38,6 @@ public:
private: private:
static const PartBoneMap sPartList; static const PartBoneMap sPartList;
bool mListenerDisabled;
// Bounded Parts // Bounded Parts
PartHolderPtr mObjectParts[ESM::PRT_Count]; PartHolderPtr mObjectParts[ESM::PRT_Count];
std::string mSoundIds[ESM::PRT_Count]; std::string mSoundIds[ESM::PRT_Count];
@ -105,7 +103,7 @@ public:
* @param disableSounds Same as \a disableListener but for playing items sounds * @param disableSounds Same as \a disableListener but for playing items sounds
* @param viewMode * @param viewMode
*/ */
NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem, bool disableListener = false, NpcAnimation(const MWWorld::Ptr& ptr, osg::ref_ptr<osg::Group> parentNode, Resource::ResourceSystem* resourceSystem,
bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f); bool disableSounds = false, ViewMode viewMode=VM_Normal, float firstPersonFieldOfView=55.f);
virtual ~NpcAnimation(); virtual ~NpcAnimation();

@ -92,6 +92,8 @@ void Objects::insertCreature(const MWWorld::Ptr &ptr, const std::string &mesh, b
else else
anim.reset(new CreatureAnimation(ptr, mesh, mResourceSystem)); anim.reset(new CreatureAnimation(ptr, mesh, mResourceSystem));
ptr.getClass().getContainerStore(ptr).setContListener(static_cast<ActorAnimation*>(anim.get()));
mObjects.insert(std::make_pair(ptr, anim.release())); mObjects.insert(std::make_pair(ptr, anim.release()));
} }
@ -102,6 +104,9 @@ void Objects::insertNPC(const MWWorld::Ptr &ptr)
std::auto_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem)); std::auto_ptr<NpcAnimation> anim (new NpcAnimation(ptr, osg::ref_ptr<osg::Group>(ptr.getRefData().getBaseNode()), mResourceSystem));
ptr.getClass().getInventoryStore(ptr).setInvListener(anim.get(), ptr);
ptr.getClass().getInventoryStore(ptr).setContListener(anim.get());
mObjects.insert(std::make_pair(ptr, anim.release())); mObjects.insert(std::make_pair(ptr, anim.release()));
} }
@ -119,6 +124,13 @@ bool Objects::removeObject (const MWWorld::Ptr& ptr)
delete iter->second; delete iter->second;
mObjects.erase(iter); mObjects.erase(iter);
if (ptr.getClass().isNpc())
{
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
store.setInvListener(NULL, ptr);
store.setContListener(NULL);
}
ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode()); ptr.getRefData().getBaseNode()->getParent(0)->removeChild(ptr.getRefData().getBaseNode());
ptr.getRefData().setBaseNode(NULL); ptr.getRefData().setBaseNode(NULL);
@ -132,10 +144,19 @@ void Objects::removeCell(const MWWorld::CellStore* store)
{ {
for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();) for(PtrAnimationMap::iterator iter = mObjects.begin();iter != mObjects.end();)
{ {
if(iter->first.getCell() == store) MWWorld::Ptr ptr = iter->second->getPtr();
if(ptr.getCell() == store)
{ {
if (mUnrefQueue.get()) if (mUnrefQueue.get())
mUnrefQueue->push(iter->second->getObjectRoot()); mUnrefQueue->push(iter->second->getObjectRoot());
if (ptr.getClass().isNpc() && ptr.getRefData().getCustomData())
{
MWWorld::InventoryStore& store = ptr.getClass().getInventoryStore(ptr);
store.setInvListener(NULL, ptr);
store.setContListener(NULL);
}
delete iter->second; delete iter->second;
mObjects.erase(iter++); mObjects.erase(iter++);
} }

@ -821,7 +821,7 @@ namespace MWRender
void RenderingManager::renderPlayer(const MWWorld::Ptr &player) void RenderingManager::renderPlayer(const MWWorld::Ptr &player)
{ {
mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, false, NpcAnimation::VM_Normal, mPlayerAnimation.reset(new NpcAnimation(player, player.getRefData().getBaseNode(), mResourceSystem, 0, NpcAnimation::VM_Normal,
mFirstPersonFieldOfView)); mFirstPersonFieldOfView));
mCamera->setAnimation(mPlayerAnimation.get()); mCamera->setAnimation(mPlayerAnimation.get());

@ -31,6 +31,7 @@
#include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors #include "../mwmechanics/aiavoiddoor.hpp" //Used to tell actors to avoid doors
#include "../mwrender/animation.hpp" #include "../mwrender/animation.hpp"
#include "../mwrender/npcanimation.hpp"
#include "../mwrender/renderingmanager.hpp" #include "../mwrender/renderingmanager.hpp"
#include "../mwrender/camera.hpp" #include "../mwrender/camera.hpp"
#include "../mwrender/vismask.hpp" #include "../mwrender/vismask.hpp"
@ -2212,7 +2213,12 @@ namespace MWWorld
{ {
MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr()); MWBase::Environment::get().getMechanicsManager()->remove(getPlayerPtr());
mRendering->renderPlayer(getPlayerPtr()); MWWorld::Ptr player = getPlayerPtr();
mRendering->renderPlayer(player);
MWRender::NpcAnimation* anim = static_cast<MWRender::NpcAnimation*>(mRendering->getAnimation(player));
player.getClass().getInventoryStore(player).setInvListener(anim, player);
player.getClass().getInventoryStore(player).setContListener(anim);
scaleObject(getPlayerPtr(), 1.f); // apply race height scaleObject(getPlayerPtr(), 1.f); // apply race height

Loading…
Cancel
Save