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.
......@@ -54,65 +51,45 @@ namespace Geometry
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;
class DLLExport ParameterFactory
{
public:
template<class C>
static void subscribe(const std::string& className);
static Parameter* create(const std::string& className, const std::string& name);
private:
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
/** 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)
{
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())
{
......@@ -122,7 +99,7 @@ namespace Geometry
{
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);
boost::shared_ptr<Parameter> param = ParameterFactory::create(type,name);
param->fromString(value);
m_map.insert(std::make_pair(comp,boost::shared_ptr<Parameter>(param)));
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)
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");
}
param->setValue(value);
m_map.insert(std::make_pair(comp,boost::shared_ptr<Parameter>(param)));
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;
......
......@@ -24,12 +24,12 @@ namespace Geometry
* @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)
boost::shared_ptr<Parameter> ParameterFactory::create(const std::string& className, const std::string& name)
{
Parameter* p = NULL;
boost::shared_ptr<Parameter> p;
FactoryMap::const_iterator it = s_map.find(className);
if (it != s_map.end())
p = it->second->createUnwrappedInstance();
p = it->second->createInstance();
else
throw std::runtime_error("ParameterFactory:"+ className + " is not registered.\n");
p->m_name = name;
......@@ -38,7 +38,6 @@ namespace Geometry
}
} // 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,21 +184,23 @@ 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)
{
delete B;
B=nR;
if (B)
B->setParent(this);
}
else
{
delete A;
A=nR;
if (A)
A->setParent(this);
......@@ -478,21 +480,23 @@ 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)
{
delete B;
B=nR;
if (B)
B->setParent(this);
}
else
{
delete A;
A=nR;
if (A)
A->setParent(this);
......@@ -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
......@@ -733,7 +737,8 @@ SurfPoint::operator=(const SurfPoint& A)
{
if (&A!=this)
{
key=A.key;
delete key;
key=A.key->clone();
keyN=A.keyN;
sign=A.sign;
}
......@@ -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,43 +411,42 @@ Rule::removeItem(Rule* &TRule,const int SurfN)
*/
{
int cnt(0);
Rule* Ptr=TRule->findKey(SurfN);
while(Ptr)
Rule* Ptr = TRule->findKey(SurfN);
while (Ptr)
{
Rule* LevelOne=Ptr->getParent(); // Must work
Rule* LevelTwo=(LevelOne) ? LevelOne->getParent() : 0;
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);
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);
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);
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
TRule = PObj;
LevelOne->setLeaves(0, 0); // Delete from Ptr, and copy
// Note we now need to delete this
delete LevelOne;
}
else // Basic surf object
{
SurfPoint* SX=dynamic_cast<SurfPoint*>(Ptr);
SurfPoint* SX = dynamic_cast<SurfPoint*> (Ptr);
SX->setKeyN(0);
SX->setKey(0);
return cnt+1;
return cnt + 1;
}
delete Ptr;
delete LevelOne;
Ptr=TRule->findKey(SurfN);
//delete LevelOne; // Shouldn't delete now we're deleting in setLeaf.
Ptr = TRule->findKey(SurfN);
cnt++;
}
return cnt;
......@@ -629,11 +628,12 @@ Rule::substituteSurf(const int SurfN,const int newSurfN,Surface* SPtr)
while(Ptr)
{
Ptr->setKeyN(Ptr->getSign()*newSurfN);
Ptr->setKey(SPtr);
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);
TS_ASSERT_EQUALS(child.getPos(), pos2+parentPos);
TS_ASSERT_EQUALS(child.getRelativePos(), pos2);
child.translate(translate2.X(), translate2.Y(), translate2.Z());
TS_ASSERT_EQUALS(child.getPos(), pos3+parentPos);
TS_ASSERT_EQUALS(child.getRelativePos(), pos3);
CompAssembly* child = new CompAssembly("testTranslate", parent);
child->setPos(pos1);
TS_ASSERT_EQUALS(child->getPos(), pos1+parentPos);
TS_ASSERT_EQUALS(child->getRelativePos(), pos1);
child->translate(translate1);
TS_ASSERT_EQUALS(child->getPos(), pos2+parentPos);
TS_ASSERT_EQUALS(child->getRelativePos(), pos2);
child->translate(translate2.X(), translate2.Y(), translate2.Z());
TS_ASSERT_EQUALS(child->getPos(), pos3+parentPos);
TS_ASSERT_EQUALS(child->getRelativePos(), pos3);
delete parent;
}
void testRotate()
......
......@@ -107,6 +107,7 @@ public:
TS_ASSERT_EQUALS(q.getRelativePos(),copy->getRelativePos());
TS_ASSERT_EQUALS(q.getPos(),copy->getPos());
TS_ASSERT_EQUALS(q.getRelativeRot(),copy->getRelativeRot());
delete copy;
}
void testGetParent()
......
......@@ -51,6 +51,7 @@ public:
TS_ASSERT_EQUALS(B->getNormal(),V3D(1.0,0.0,0.0));
TS_ASSERT_EQUALS(B->getCentre(),V3D(1.0,1.0,1.0));
TS_ASSERT_EQUALS(extractString(*B),"-1 k/x 1 1 1 1\n");
delete B;
}
void testAssignment()
......
......@@ -24,7 +24,8 @@ public:
d2->setPos(3.0,4.0,5.0);
d2->markAsMonitor();
group->addDetector(d2);
dg = new DetectorGroup( *(new std::vector<boost::shared_ptr<IDetector> >(1,boost::shared_ptr<IDetector>(group))) );
std::vector<IDetector_sptr> vec(1,boost::shared_ptr<IDetector>(group));
dg = new DetectorGroup( vec );
d3 = boost::shared_ptr<Detector>(new Detector("d3",0));
d3->setID(10);
d3->setPos(5.0,5.0,5.0);
......@@ -33,8 +34,7 @@ public:
~DetectorGroupTest()
{
//delete d1, d2, d3;
//delete dg, group;
delete dg, group;
}
void testConstructors()
......
......@@ -43,6 +43,7 @@ public:
General *B;
B=A.clone();
TS_ASSERT_EQUALS(extractString(*B),"-1 gq 1 1 1 0 0 0 0 0 0 -1 \n");
delete B;
}
void testEqualOperator(){
......
......@@ -75,7 +75,8 @@ public:
TS_ASSERT_EQUALS(B->getName(),"Rb");
TS_ASSERT_EQUALS(B->getScat(),22.0);
TS_ASSERT_EQUALS(B->getCoh(),20.0);
TS_ASSERT_EQUALS(B->getInc(),2.0)
TS_ASSERT_EQUALS(B->getInc(),2.0);
delete B;
}
void testAssignment(){
......
......@@ -303,11 +303,12 @@ public:
std::string ObjA="60001 -60002 60003 -60004 60005 -60006";
std::string ObjB="80001 -80002 60003 -60004 60005 -60006";
createSurfaces();
createSurfaces(ObjA);
Object object1=Object();
object1.setObject(3,ObjA);
object1.populate(SMap);
createSurfaces(ObjB);
Object object2=Object();
object2.setObject(4,ObjB);
object2.populate(SMap);
......@@ -334,11 +335,12 @@ public:
std::string ObjA="60001 -60002 60003 -60004 60005 -60006";
std::string ObjB="60002 -80002 60003 -60004 60005 -60006";
createSurfaces();
createSurfaces(ObjA);
Object object1=Object();
object1.setObject(3,ObjA);
object1.populate(SMap);
createSurfaces(ObjB);
Object object2=Object();
object2.setObject(4,ObjB);
object2.populate(SMap);
......@@ -366,11 +368,12 @@ public:
std::string ObjA="60001 -60002 60003 -60004 60005 -60006 71";
std::string ObjB="-71";
createSurfaces();
createSurfaces(ObjA);
Object object1=Object();
object1.setObject(3,ObjA);
object1.populate(SMap);
createSurfaces(ObjB);
Object object2=Object();
object2.setObject(4,ObjB);
object2.populate(SMap);
......@@ -397,11 +400,12 @@ public:
std::string ObjA="60001 -60002 60003 -60004 60005 -60006 72 73";
std::string ObjB="(-72 : -73)";
createSurfaces();
createSurfaces(ObjA);
Object object1=Object();
object1.setObject(3,ObjA);
object1.populate(SMap);