DeletionManager
Class for safely deleting objects that may be active in different threads. This is now used in the implementation of spin animations.
This commit is contained in:
parent
e202d4e4a5
commit
78a78a17cc
@ -44,6 +44,7 @@
|
||||
#include <simgear/structure/SGBinding.hxx>
|
||||
#include <simgear/scene/material/EffectGeode.hxx>
|
||||
#include <simgear/scene/material/EffectCullVisitor.hxx>
|
||||
#include <simgear/scene/util/DeletionManager.hxx>
|
||||
#include <simgear/scene/util/OsgMath.hxx>
|
||||
#include <simgear/scene/util/SGNodeMasks.hxx>
|
||||
#include <simgear/scene/util/SGSceneUserData.hxx>
|
||||
@ -778,7 +779,8 @@ protected:
|
||||
// more than one camera. It is probably safe to overwrite the
|
||||
// reference values in multiple threads, but we'll provide a
|
||||
// threadsafe way to manage those values just to be safe.
|
||||
struct ReferenceValues {
|
||||
struct ReferenceValues : public osg::Referenced
|
||||
{
|
||||
ReferenceValues(double t, double rot, double vel)
|
||||
: _time(t), _rotation(rot), _rotVelocity(vel)
|
||||
{
|
||||
@ -800,19 +802,31 @@ void SpinAnimCallback::operator()(osg::Node* node, osg::NodeVisitor* nv)
|
||||
if (!_condition || _condition->test()) {
|
||||
double t = nv->getFrameStamp()->getReferenceTime();
|
||||
double rps = _animationValue->getValue() / 60.0;
|
||||
ReferenceValues* refval = static_cast<ReferenceValues*>(_referenceValues.get());
|
||||
if (!refval || refval->_rotVelocity != rps) {
|
||||
ReferenceValues* newref = 0;
|
||||
if (!refval) {
|
||||
ref_ptr<ReferenceValues>
|
||||
refval(static_cast<ReferenceValues*>(_referenceValues.get()));
|
||||
if (!refval || refval->_rotVelocity != rps) {
|
||||
ref_ptr<ReferenceValues> newref;
|
||||
if (!refval.valid()) {
|
||||
// initialization
|
||||
newref = new ReferenceValues(t, 0.0, rps);
|
||||
} else {
|
||||
double newRot = refval->_rotation + (t - refval->_time) * refval->_rotVelocity;
|
||||
newref = new ReferenceValues(t, newRot, rps);
|
||||
}
|
||||
// increment reference pointer, because it will be stored
|
||||
// naked in _referenceValues.
|
||||
newref->ref();
|
||||
if (_referenceValues.assign(newref, refval)) {
|
||||
delete refval;
|
||||
if (refval.valid()) {
|
||||
DeletionManager::instance()->addStaleObject(refval.get());
|
||||
refval->unref();
|
||||
}
|
||||
} else {
|
||||
// Another thread installed new values before us
|
||||
newref->unref();
|
||||
}
|
||||
// Whatever happened, we can use the reference values just
|
||||
// calculated.
|
||||
refval = newref;
|
||||
}
|
||||
double rotation = refval->_rotation + (t - refval->_time) * rps;
|
||||
|
@ -2,6 +2,7 @@ include (SimGearComponent)
|
||||
|
||||
set(HEADERS
|
||||
CopyOp.hxx
|
||||
DeletionManager.hxx
|
||||
NodeAndDrawableVisitor.hxx
|
||||
Noise.hxx
|
||||
OsgMath.hxx
|
||||
@ -28,6 +29,7 @@ set(HEADERS
|
||||
|
||||
set(SOURCES
|
||||
CopyOp.cxx
|
||||
DeletionManager.cxx
|
||||
NodeAndDrawableVisitor.cxx
|
||||
Noise.cxx
|
||||
PrimitiveUtils.cxx
|
||||
|
58
simgear/scene/util/DeletionManager.cxx
Normal file
58
simgear/scene/util/DeletionManager.cxx
Normal file
@ -0,0 +1,58 @@
|
||||
// DeletionManager.hxx -- defer deletions to a safe time
|
||||
//
|
||||
// Copyright (C) 2012 Tim Moore timoore33@gmail.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301, USA.
|
||||
|
||||
#include "DeletionManager.hxx"
|
||||
|
||||
#include <OpenThreads/ScopedLock>
|
||||
#include <osg/Node>
|
||||
#include "OsgSingleton.hxx"
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
using namespace osg;
|
||||
|
||||
bool DeletionManager::handle(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter&,
|
||||
osg::Object*, osg::NodeVisitor*)
|
||||
{
|
||||
if (ea.getEventType() == osgGA::GUIEventAdapter::FRAME)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
_staleObjects.resize(0);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void DeletionManager::addStaleObject(Referenced* obj)
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_mutex);
|
||||
_staleObjects.push_back(obj);
|
||||
}
|
||||
|
||||
void DeletionManager::install(Node* node)
|
||||
{
|
||||
node->addEventCallback(instance());
|
||||
}
|
||||
|
||||
DeletionManager* DeletionManager::instance()
|
||||
{
|
||||
return SingletonRefPtr<DeletionManager>::instance();
|
||||
}
|
||||
}
|
||||
|
48
simgear/scene/util/DeletionManager.hxx
Normal file
48
simgear/scene/util/DeletionManager.hxx
Normal file
@ -0,0 +1,48 @@
|
||||
// DeletionManager.hxx -- defer deletions to a safe time
|
||||
//
|
||||
// Copyright (C) 2012 Tim Moore timoore33@gmail.com
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Library General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Library General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Library General Public
|
||||
// License along with this library; if not, write to the
|
||||
// Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
|
||||
// Boston, MA 02110-1301, USA.
|
||||
|
||||
#ifndef SIMGEAR_DELETIONMANAGER_HXX
|
||||
#define SIMGEAR_DELETIONMANAGER_HXX 1
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <OpenThreads/Mutex>
|
||||
#include <osg/ref_ptr>
|
||||
#include <osg/NodeCallback>
|
||||
#include <osg/Referenced>
|
||||
#include <osgGA/GUIEventHandler>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
class DeletionManager : public osgGA::GUIEventHandler
|
||||
{
|
||||
public:
|
||||
virtual bool handle(const osgGA::GUIEventAdapter& ea,
|
||||
osgGA::GUIActionAdapter& aa,
|
||||
osg::Object* object, osg::NodeVisitor* nv);
|
||||
void addStaleObject(osg::Referenced* obj);
|
||||
static void install(osg::Node* node);
|
||||
static DeletionManager* instance();
|
||||
protected:
|
||||
OpenThreads::Mutex _mutex;
|
||||
std::vector<osg::ref_ptr<osg::Referenced> > _staleObjects;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user