Commit 4df86bfa authored by Russell Taylor's avatar Russell Taylor
Browse files

Remove some Geometry memory leaks (including ones just in tests). Re #722.

parent 64cf1e3e
......@@ -53,7 +53,7 @@ namespace Geometry
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>.
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport Component:public virtual IComponent
class DLLExport Component:public virtual IComponent
{
public:
/// Returns a string representation of the component type
......
......@@ -25,17 +25,14 @@ namespace Geometry
//----------------------------------------------------------------------
// Forward declaration
//----------------------------------------------------------------------
class Parameter;
class Parameter;
/** The AlgorithmFactory class creates parameters for the instrument ParameterMap.
It inherits most of its implementation from the Dynamic Factory base class.
It is implemented as a singleton class.
/** The ParameterFactory class creates parameters for the instrument ParameterMap.
@author Roman Tolchenov, Tessella plc
@date 19/05/2009
Copyright &copy; 2007 STFC Rutherford Appleton Laboratories
Copyright &copy; 2009 STFC Rutherford Appleton Laboratories
This file is part of Mantid.
......@@ -53,76 +50,56 @@ namespace Geometry
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://svn.mantidproject.org/mantid/trunk/Code/Mantid>
*/
//class DLLExport ParameterFactoryImpl : public Kernel::DynamicFactory<Parameter>
// {
// public:
// /// Creates a new instance of parameter of type className
// Parameter* create(const std::string& className, const std::string& name) const;
// template<class C>
// void subscribe(const std::string& className);
// private:
// friend struct Mantid::Kernel::CreateUsingNew<ParameterFactoryImpl>;
//
// /// Private Constructor for singleton class
// ParameterFactoryImpl(): Kernel::DynamicFactory<Parameter>(), g_log(Kernel::Logger::get("ParameterFactory")){}
// /// Private copy constructor - NO COPY ALLOWED
// ParameterFactoryImpl(const ParameterFactoryImpl&);
// /// Private assignment operator - NO ASSIGNMENT ALLOWED
// ParameterFactoryImpl& operator = (const ParameterFactoryImpl&);
// ///Private Destructor
// virtual ~ParameterFactoryImpl(){}
// ///static reference to the logger class
// Kernel::Logger& g_log;
//
// };
//
// ///Forward declaration of a specialisation of SingletonHolder for AlgorithmFactoryImpl (needed for dllexport/dllimport) and a typedef for it.
//#ifdef _WIN32
//// this breaks new namespace declaraion rules; need to find a better fix
// template class DLLExport Mantid::Kernel::SingletonHolder<ParameterFactoryImpl>;
//#endif /* _WIN32 */
// typedef DLLExport Mantid::Kernel::SingletonHolder<ParameterFactoryImpl> ParameterFactory;
//
class DLLExport ParameterFactory
{
public:
/// A typedef for the instantiator
typedef Kernel::AbstractInstantiator<Parameter> AbstractFactory;
/// A typedef for the map of registered classes
typedef std::map<std::string, AbstractFactory*> FactoryMap;
template<class C>
static void subscribe(const std::string& className);
static Parameter* create(const std::string& className, const std::string& name);
private:
/// Private default constructor
ParameterFactory();
/// Private copy constructor
ParameterFactory(const ParameterFactory&);
/// Private assignment operator
ParameterFactory& operator=(const ParameterFactory&);
/// The map holding the registered class names and their instantiators
static FactoryMap s_map;
};
*/
class DLLExport ParameterFactory
{
public:
template<class C>
static void subscribe(const std::string& className);
static boost::shared_ptr<Parameter> create(const std::string& className, const std::string& name);
private:
/// Private default constructor
ParameterFactory();
/// Private copy constructor
ParameterFactory(const ParameterFactory&);
/// Private assignment operator
ParameterFactory& operator=(const ParameterFactory&);
/// A typedef for the instantiator
typedef Kernel::AbstractInstantiator<Parameter> AbstractFactory;
/// An inner class to specialise map such that it does a deep delete when s_map is destroyed
class FactoryMap : public std::map<std::string, AbstractFactory*>
{
public:
/// Destructor. Deletes the AbstractInstantiator objects stored in the map.
virtual ~FactoryMap()
{
for (iterator it = this->begin(); it!=this->end(); ++it) delete it->second;
}
};
/// The map holding the registered class names and their instantiators
static FactoryMap s_map;
};
/** Templated method for parameter subscription
* @param className The parameter type name
* @tparam C The parameter type
*/
template<class C>
void ParameterFactory::subscribe(const std::string& className)
{
typename FactoryMap::iterator it = s_map.find(className);
if (!className.empty() && it == s_map.end())
{
s_map[className] = new Kernel::Instantiator<C, Parameter>;
}
else
{
throw std::runtime_error("Parameter type" + className + " is already registered.\n");
}
}
/** Templated method for parameter subscription
* @param className The parameter type name
* @tparam C The parameter type
*/
template<class C>
void ParameterFactory::subscribe(const std::string& className)
{
typename FactoryMap::iterator it = s_map.find(className);
if (!className.empty() && it == s_map.end())
{
s_map[className] = new Kernel::Instantiator<C, Parameter>;
}
else
{
throw std::runtime_error("Parameter type" + className + " is already registered.\n");
}
}
} // namespace Geometry
} // namespace Mantid
......
......@@ -81,23 +81,24 @@ public:
/// Method for adding a parameter providing its value as a string
void add(const std::string& type,const IComponent* comp,const std::string& name, const std::string& value)
{
Parameter* param = ParameterFactory::create(type,name);
param->fromString(value);
m_map.insert(std::make_pair(comp,boost::shared_ptr<Parameter>(param)));
boost::shared_ptr<Parameter> param = ParameterFactory::create(type,name);
param->fromString(value);
m_map.insert(std::make_pair(comp,param));
}
/// Method for adding a parameter providing its value of a particular type
template<class T>
void add(const std::string& type,const IComponent* comp,const std::string& name, const T& value)
{
ParameterType<T> *param = dynamic_cast<ParameterType<T> *>(ParameterFactory::create(type,name));
if (!param)
{
reportError("Error in adding parameter: incompatible types");
throw std::runtime_error("Error in adding parameter: incompatible types");
}
param->setValue(value);
m_map.insert(std::make_pair(comp,boost::shared_ptr<Parameter>(param)));
boost::shared_ptr<Parameter> param = ParameterFactory::create(type,name);
ParameterType<T> *paramT = dynamic_cast<ParameterType<T> *>(param.get());
if (!paramT)
{
reportError("Error in adding parameter: incompatible types");
throw std::runtime_error("Error in adding parameter: incompatible types");
}
paramT->setValue(value);
m_map.insert(std::make_pair(comp,param));
}
/// Method is provided to add a parameter of any custom type which must be created with 'new' operator.
......
......@@ -46,8 +46,8 @@ namespace Mantid
*/
CacheGeometryGenerator::~CacheGeometryGenerator()
{
if(mFaces!=NULL) delete mFaces;
if(mPoints!=NULL) delete mPoints;
if(mFaces!=NULL) delete[] mFaces;
if(mPoints!=NULL) delete[] mPoints;
}
......@@ -80,8 +80,8 @@ namespace Mantid
*/
void CacheGeometryGenerator::setGeometryCache(int noPts,int noFaces,double* pts,int* faces)
{
if(mPoints!=NULL) delete mPoints;
if(mFaces!=NULL) delete mFaces;
if(mPoints!=NULL) delete[] mPoints;
if(mFaces!=NULL) delete[] mFaces;
mNoOfVertices=noPts;
mNoOfTriangles=noFaces;
mPoints=pts;
......
......@@ -308,9 +308,8 @@ namespace Mantid
}
}
}
#if debugObject
std::cerr<<"Populated surfaces =="<<Rcount<<" in "<<ObjName<<std::endl;
#endif
PLog.debug() <<"Populated surfaces =="<<Rcount<<" in "<<ObjName<<std::endl;
createSurfaceList();
return 0;
......
......@@ -7,7 +7,7 @@ namespace Mantid
namespace Geometry
{
/// @cond
/// @cond
template<>
void ParameterV3D::fromString(const std::string &value)
{
......@@ -16,29 +16,28 @@ namespace Geometry
}
/// @endcond
ParameterFactory::FactoryMap ParameterFactory::s_map;
ParameterFactory::FactoryMap ParameterFactory::s_map;
/** Creates an instance of a parameter
* @param className The parameter registered type name
* @param name The parameter name
* @return A pointer to the created parameter
* @throw runtime_error if the type has not been registered
*/
Parameter* ParameterFactory::create(const std::string& className, const std::string& name)
{
Parameter* p = NULL;
FactoryMap::const_iterator it = s_map.find(className);
if (it != s_map.end())
p = it->second->createUnwrappedInstance();
else
throw std::runtime_error("ParameterFactory:"+ className + " is not registered.\n");
p->m_name = name;
p->m_type = className;
return p;
}
/** Creates an instance of a parameter
* @param className The parameter registered type name
* @param name The parameter name
* @return A pointer to the created parameter
* @throw runtime_error if the type has not been registered
*/
boost::shared_ptr<Parameter> ParameterFactory::create(const std::string& className, const std::string& name)
{
boost::shared_ptr<Parameter> p;
FactoryMap::const_iterator it = s_map.find(className);
if (it != s_map.end())
p = it->second->createInstance();
else
throw std::runtime_error("ParameterFactory:"+ className + " is not registered.\n");
p->m_name = name;
p->m_type = className;
return p;
}
} // Namespace Geometry
} // Namespace Mantid
DECLARE_PARAMETER(int,int)
......@@ -47,4 +46,3 @@ DECLARE_PARAMETER(bool,bool)
DECLARE_PARAMETER(str,std::string)
DECLARE_PARAMETER(V3D,Mantid::Geometry::V3D)
DECLARE_PARAMETER(Quat,Mantid::Geometry::Quat)
......@@ -184,25 +184,27 @@ void
Intersection::setLeaf(Rule* nR,const int side)
/*!
Replaces a leaf with a rule.
No deletion is carried out
Calls delete on previous leaf.
\param nR :: new rule
\param side :: side to use
- 0 == LHS
- true == RHS
- 1 == RHS
*/
{
if (side)
{
B=nR;
if (B)
B->setParent(this);
}
{
delete B;
B=nR;
if (B)
B->setParent(this);
}
else
{
A=nR;
if (A)
A->setParent(this);
}
{
delete A;
A=nR;
if (A)
A->setParent(this);
}
return;
}
......@@ -478,25 +480,27 @@ void
Union::setLeaf(Rule* nR,const int side)
/*!
Replaces a leaf with a rule.
No deletion is carried out
Calls delete on previous leaf.
\param nR :: new rule
\param side :: side to use
- 0 == LHS
- true == RHS
- 1 == RHS
*/
{
if (side)
{
B=nR;
if (B)
B->setParent(this);
}
{
delete B;
B=nR;
if (B)
B->setParent(this);
}
else
{
A=nR;
if (A)
A->setParent(this);
}
{
delete A;
A=nR;
if (A)
A->setParent(this);
}
return;
}
......@@ -705,7 +709,7 @@ SurfPoint::SurfPoint() : Rule(),
{}
SurfPoint::SurfPoint(const SurfPoint& A) : Rule(),
key(A.key),keyN(A.keyN),sign(A.sign)
key(A.key->clone()),keyN(A.keyN),sign(A.sign)
/*!
Copy constructor
\param A ::SurfPoint to copy
......@@ -732,11 +736,12 @@ SurfPoint::operator=(const SurfPoint& A)
*/
{
if (&A!=this)
{
key=A.key;
keyN=A.keyN;
sign=A.sign;
}
{
delete key;
key=A.key->clone();
keyN=A.keyN;
sign=A.sign;
}
return *this;
}
......@@ -744,7 +749,9 @@ SurfPoint::~SurfPoint()
/*!
Destructor
*/
{}
{
delete key;
}
void
SurfPoint::setLeaf(Rule* nR,const int)
......@@ -817,10 +824,11 @@ SurfPoint::setKeyN(const int Ky)
void
SurfPoint::setKey(Surface* Spoint)
/*!
Sets the key pointter
Sets the key pointer. The class takes ownership.
\param Spoint :: new key values
*/
{
if (key!=Spoint) delete key;
key=Spoint;
return;
}
......
......@@ -411,45 +411,44 @@ Rule::removeItem(Rule* &TRule,const int SurfN)
*/
{
int cnt(0);
Rule* Ptr=TRule->findKey(SurfN);
while(Ptr)
{
Rule* LevelOne=Ptr->getParent(); // Must work
Rule* LevelTwo=(LevelOne) ? LevelOne->getParent() : 0;
Rule* Ptr = TRule->findKey(SurfN);
while (Ptr)
{
Rule* LevelOne = Ptr->getParent(); // Must work
Rule* LevelTwo = (LevelOne) ? LevelOne->getParent() : 0;
if (LevelTwo) /// Not the top level
{
// Decide which of the pairs is to be copied
Rule* PObj= (LevelOne->leaf(0)!=Ptr) ?
LevelOne->leaf(0) : LevelOne->leaf(1);
//
LevelOne->setLeaves(0,0); // Delete from Ptr, and copy
const int side=(LevelTwo->leaf(0)!=LevelOne) ? 1 : 0;
LevelTwo->setLeaf(PObj,side);
}
else if (LevelOne) // LevelOne is the top rule
{
// Decide which of the pairs is to be copied
Rule* PObj= (LevelOne->leaf(0)!=Ptr) ?
LevelOne->leaf(0) : LevelOne->leaf(1);
PObj->setParent(0); /// New Top rule
TRule=PObj;
LevelOne->setLeaves(0,0); // Delete from Ptr, and copy
// Note we now need to delete this
}
else // Basic surf object
{
SurfPoint* SX=dynamic_cast<SurfPoint*>(Ptr);
SX->setKeyN(0);
SX->setKey(0);
return cnt+1;
}
delete Ptr;
if (LevelTwo) /// Not the top level
{
// Decide which of the pairs is to be copied
Rule* PObj = (LevelOne->leaf(0) != Ptr) ? LevelOne->leaf(0) : LevelOne->leaf(1);
//
LevelOne->setLeaves(0, 0); // Delete from Ptr, and copy
const int side = (LevelTwo->leaf(0) != LevelOne) ? 1 : 0;
LevelTwo->setLeaf(PObj, side);
}
else if (LevelOne) // LevelOne is the top rule
{
// Decide which of the pairs is to be copied
Rule* PObj = (LevelOne->leaf(0) != Ptr) ? LevelOne->leaf(0) : LevelOne->leaf(1);
PObj->setParent(0); /// New Top rule
TRule = PObj;
LevelOne->setLeaves(0, 0); // Delete from Ptr, and copy
// Note we now need to delete this
delete LevelOne;
Ptr=TRule->findKey(SurfN);
cnt++;
}
else // Basic surf object
{
SurfPoint* SX = dynamic_cast<SurfPoint*> (Ptr);
SX->setKeyN(0);
SX->setKey(0);
return cnt + 1;
}
delete Ptr;
//delete LevelOne; // Shouldn't delete now we're deleting in setLeaf.
Ptr = TRule->findKey(SurfN);
cnt++;
}
return cnt;
}
......@@ -627,13 +626,14 @@ Rule::substituteSurf(const int SurfN,const int newSurfN,Surface* SPtr)
int cnt(0);
SurfPoint* Ptr=dynamic_cast<SurfPoint*>(findKey(SurfN));
while(Ptr)
{
Ptr->setKeyN(Ptr->getSign()*newSurfN);
Ptr->setKey(SPtr);
cnt++;
// get next key
Ptr=dynamic_cast<SurfPoint*>(findKey(SurfN));
}
{
Ptr->setKeyN(Ptr->getSign()*newSurfN);
Ptr->setKey(SPtr->clone()); // Clone to ensure uniqueness
cnt++;
// get next key
Ptr=dynamic_cast<SurfPoint*>(findKey(SurfN));
}
delete SPtr; // Delete incoming pointer
return cnt;
}
......
......@@ -222,6 +222,8 @@ boost::shared_ptr<Object> ShapeFactory::createShape(Poco::XML::Element* pElem)
}
}
pNL->release();
if ( defaultAlgebra == false )
{
// Translate algebra string defined by the user into something Mantid can
......
......@@ -46,6 +46,7 @@ namespace Mantid
*/
vtkGeometryCacheReader::~vtkGeometryCacheReader()
{
mDoc->release();
delete pParser;
}
......
......@@ -44,20 +44,21 @@ public:
void testNameParentValueConstructor()
{
CompAssembly* parent = new CompAssembly("Parent");
CompAssembly *parent = new CompAssembly("Parent");
//name and parent
CompAssembly q("Child", parent);
TS_ASSERT_EQUALS(q.getName(), "Child");
TS_ASSERT_EQUALS(q.nelements(), 0);
TS_ASSERT_THROWS(q[0], std::runtime_error);
CompAssembly *q = new CompAssembly("Child", parent);
TS_ASSERT_EQUALS(q->getName(), "Child");
TS_ASSERT_EQUALS(q->nelements(), 0);
TS_ASSERT_THROWS((*q)[0], std::runtime_error);
//check the parent
TS_ASSERT(q.getParent());
TS_ASSERT_EQUALS(q.getParent()->getName(), parent->getName());
TS_ASSERT(q->getParent());
TS_ASSERT_EQUALS(q->getParent()->getName(), parent->getName());
TS_ASSERT_EQUALS(q.getPos(), V3D(0, 0, 0));
TS_ASSERT_EQUALS(q.getRelativeRot(), Quat(1, 0, 0, 0));
TS_ASSERT_EQUALS(q->getPos(), V3D(0, 0, 0));
TS_ASSERT_EQUALS(q->getRelativeRot(), Quat(1, 0, 0, 0));
//as the parent is at 0,0,0 GetPos should equal getRelativePos
TS_ASSERT_EQUALS(q.getRelativePos(), q.getPos());
TS_ASSERT_EQUALS(q->getRelativePos(), q->getPos());
delete parent;
}
void testAdd()
......@@ -127,6 +128,7 @@ public:
TS_ASSERT_EQUALS(q.getRelativePos(), copy.getRelativePos());
TS_ASSERT_EQUALS(q.getPos(), copy.getPos());
TS_ASSERT_EQUALS(q.getRelativeRot(), copy.getRelativeRot());
delete parent;
}
void testClone()
......@@ -153,6 +155,8 @@ public:
TS_ASSERT_EQUALS(q.getRelativePos(), copy->getRelativePos());
TS_ASSERT_EQUALS(q.getPos(), copy->getPos());
TS_ASSERT_EQUALS(q.getRelativeRot(), copy->getRelativeRot());
delete copyAsComponent;
delete parent;
}
void testGetParent()
......@@ -272,16 +276,17 @@ public:
CompAssembly* parent = new CompAssembly("testTranslate");
parent->setPos(parentPos);
CompAssembly child("testTranslate", parent);
child.setPos(pos1);
TS_ASSERT_EQUALS(child.getPos(), pos1+parentPos);
TS_ASSERT_EQUALS(child.getRelativePos(), pos1);
child.translate(translate1);