diff --git a/Code/Mantid/Framework/Kernel/inc/MantidKernel/SingletonHolder.h b/Code/Mantid/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
index e189b49c31cd..faca5f0c1c22 100644
--- a/Code/Mantid/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
+++ b/Code/Mantid/Framework/Kernel/inc/MantidKernel/SingletonHolder.h
@@ -44,6 +44,9 @@ namespace Mantid
class SingletonHolder
{
public:
+ /// Allow users to access to the type returned by Instance()
+ typedef T HeldType;
+
static T& Instance();
private:
diff --git a/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TrackingInstanceMethod.h b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TrackingInstanceMethod.h
new file mode 100644
index 000000000000..1ed9b12a5487
--- /dev/null
+++ b/Code/Mantid/Framework/PythonInterface/inc/MantidPythonInterface/kernel/TrackingInstanceMethod.h
@@ -0,0 +1,93 @@
+#ifndef MANTID_PYTHONINTERFACE_TRACKINGINSTANCEMETHOD_H_
+#define MANTID_PYTHONINTERFACE_TRACKINGINSTANCEMETHOD_H_
+
+/*
+ Copyright © 2014 ISIS Rutherford Appleton Laboratory & NScD Oak Ridge National Laboratory
+
+ This file is part of Mantid.
+
+ Mantid is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ Mantid 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+
+ File change history is stored at:
+ Code Documentation is available at:
+ */
+#include
+
+namespace Mantid
+{
+ namespace PythonInterface
+ {
+ /**
+ * Add an Instance() & __del__ method to the already exported python type.
+ * The methods track how many times instance() & __del__ are called and clear the
+ * SingletonType object when the count reaches zero.
+ * @tparam SingletonType The main SingletonHolder type. It is expected to have a nested type
+ * HeldType that defines the implementation
+ * @tparam PythonType The boost.python C++ exported type
+ */
+ template
+ class TrackingInstanceMethod
+ {
+ /// Type returned by instance()
+ typedef typename SingletonType::HeldType InstanceType;
+
+ public:
+ /**
+ * Add the instance tracking methods
+ * @param classType The python type already exported using class_
+ */
+ static void define(PythonType & classType)
+ {
+ classType.def("__del__", &TrackingInstanceMethod::decref);
+ classType.def("Instance", &TrackingInstanceMethod::instance,
+ return_value_policy(),
+ "Return a reference to the singleton instance");
+ classType.staticmethod("Instance");
+ }
+
+ /**
+ * Increment reference count & return the singleton instance
+ * @return A reference to the InstanceType
+ */
+ static InstanceType &instance()
+ {
+ ++g_py_instance_count;
+ return SingletonType::Instance();
+ }
+
+ /**
+ * @param self The calling object
+ */
+ static void decref(InstanceType & self)
+ {
+ --g_py_instance_count;
+ if (g_py_instance_count == 0)
+ {
+ self.clear();
+ }
+ }
+
+ private:
+ /// Track the number of calls to instance/decref
+ static size_t g_py_instance_count;
+ };
+
+ /// Initialize static counter
+ template
+ size_t TrackingInstanceMethod::g_py_instance_count = 0;
+
+ }
+}
+
+#endif /* MANTID_PYTHONINTERFACE_TRACKINGINSTANCEMETHOD */
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp
index c501b5edb2e4..c71750cf2350 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmManager.cpp
@@ -1,5 +1,6 @@
#include "MantidAPI/AlgorithmManager.h"
#include "MantidPythonInterface/api/AlgorithmIDProxy.h"
+#include "MantidPythonInterface/kernel/TrackingInstanceMethod.h"
#include
#include
@@ -10,6 +11,7 @@
using namespace Mantid::API;
using Mantid::PythonInterface::AlgorithmIDProxy;
+using Mantid::PythonInterface::TrackingInstanceMethod;
using namespace boost::python;
namespace
@@ -66,7 +68,9 @@ namespace
void export_AlgorithmManager()
{
- class_("AlgorithmManagerImpl", no_init)
+ typedef class_ PythonType;
+
+ auto pythonClass = class_("AlgorithmManagerImpl", no_init)
.def("create", &AlgorithmManagerImpl::create, create_overloads((arg("name"), arg("version")), "Creates a managed algorithm."))
.def("createUnmanaged", &AlgorithmManagerImpl::createUnmanaged,
createUnmanaged_overloads((arg("name"), arg("version")), "Creates an unmanaged algorithm."))
@@ -83,9 +87,9 @@ void export_AlgorithmManager()
.def("clear", &AlgorithmManagerImpl::clear, "Clears the current list of managed algorithms")
.def("cancelAll", &AlgorithmManagerImpl::cancelAll,
"Requests that all currently running algorithms be cancelled")
-
- .def("Instance", &AlgorithmManager::Instance, return_value_policy(),
- "Returns a reference to the AlgorithmManager singleton")
- .staticmethod("Instance")
;
+
+ // Instance method
+ TrackingInstanceMethod::define(pythonClass);
+
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
index bdfebc28d73a..ffe453646bad 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AnalysisDataService.cpp
@@ -1,5 +1,6 @@
#include "MantidPythonInterface/kernel/DataServiceExporter.h"
#include "MantidPythonInterface/kernel/Registry/DowncastRegistry.h"
+#include "MantidPythonInterface/kernel/TrackingInstanceMethod.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/Workspace.h"
@@ -11,6 +12,7 @@
using namespace Mantid::API;
using Mantid::PythonInterface::DataServiceExporter;
+using Mantid::PythonInterface::TrackingInstanceMethod;
using namespace Mantid::PythonInterface::Registry;
using namespace boost::python;
@@ -68,22 +70,18 @@ namespace
void export_AnalysisDataService()
{
-
- auto adsType = DataServiceExporter::define("AnalysisDataServiceImpl");
+ typedef DataServiceExporter ADSExporter;
+ auto pythonClass = ADSExporter::define("AnalysisDataServiceImpl");
// -- special ADS behaviour --
// replace the add/addOrReplace,__setitem__ methods as we need to exact the exact stored type
- adsType.def("add", &addItem,
+ pythonClass.def("add", &addItem,
"Adds the given object to the service with the given name. If the name/object exists it will raise an error.");
- adsType.def("addOrReplace", &addOrReplaceItem,
+ pythonClass.def("addOrReplace", &addOrReplaceItem,
"Adds the given object to the service with the given name. The the name exists the object is replaced.");
- adsType.def("__setitem__", &addOrReplaceItem);
+ pythonClass.def("__setitem__", &addOrReplaceItem);
- // Add instance method for the ADS singleton
- adsType.def("Instance", &AnalysisDataService::Instance,
- return_value_policy(),
- "Return a reference to the ADS singleton");
- adsType.staticmethod("Instance");
+ // Instance method
+ TrackingInstanceMethod::define(pythonClass);
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/PropertyManagerDataService.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/PropertyManagerDataService.cpp
index d2955e3d301c..65cab60bf180 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/PropertyManagerDataService.cpp
+++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/PropertyManagerDataService.cpp
@@ -1,4 +1,5 @@
#include "MantidPythonInterface/kernel/DataServiceExporter.h"
+#include "MantidPythonInterface/kernel/TrackingInstanceMethod.h"
#include "MantidAPI/PropertyManagerDataService.h"
#include "MantidKernel/PropertyManager.h"
@@ -7,6 +8,8 @@
using namespace Mantid::API;
using namespace Mantid::Kernel;
+using Mantid::PythonInterface::DataServiceExporter;
+using Mantid::PythonInterface::TrackingInstanceMethod;
using namespace boost::python;
/// Weak pointer to DataItem typedef
@@ -14,15 +17,14 @@ typedef boost::weak_ptr PropertyManager_wptr;
void export_PropertyManagerDataService()
{
- using Mantid::PythonInterface::DataServiceExporter;
register_ptr_to_python();
- auto pmdType = DataServiceExporter::define("PropertyManagerDataServiceImpl");
- pmdType.def("Instance", &PropertyManagerDataService::Instance,
- return_value_policy(),
- "Return a reference to the ADS singleton");
- pmdType.staticmethod("Instance");
+ typedef DataServiceExporter PMDExporter;
+ auto pmdType = PMDExporter::define("PropertyManagerDataServiceImpl");
+
+ // Instance method
+ TrackingInstanceMethod::define(pmdType);
+
}
diff --git a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
index 9de90f326cc1..fa48f236c134 100644
--- a/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
+++ b/Code/Mantid/Framework/PythonInterface/mantid/kernel/CMakeLists.txt
@@ -95,6 +95,7 @@ set ( INC_FILES
${HEADER_DIR}/kernel/PropertyWithValueExporter.h
${HEADER_DIR}/kernel/PythonObjectInstantiator.h
${HEADER_DIR}/kernel/StlExportDefinitions.h
+ ${HEADER_DIR}/kernel/TrackingInstanceMethod.h
${HEADER_DIR}/kernel/TypedValidatorExporter.h
)
diff --git a/Code/Mantid/MantidQt/CustomInterfaces/test/CMakeLists.txt b/Code/Mantid/MantidQt/CustomInterfaces/test/CMakeLists.txt
index 68f05f3c316c..4b639417edcf 100644
--- a/Code/Mantid/MantidQt/CustomInterfaces/test/CMakeLists.txt
+++ b/Code/Mantid/MantidQt/CustomInterfaces/test/CMakeLists.txt
@@ -6,11 +6,10 @@ if ( CXXTEST_FOUND )
set ( TESTHELPER_SRCS ../../../Framework/TestHelpers/src/ComponentCreationHelper.cpp
../../../Framework/TestHelpers/src/WorkspaceCreationHelper.cpp
../../../Framework/TestHelpers/src/ScopedFileHelper.cpp
- )
+ ../../../Framework/TestHelpers/src/TearDownWorld.cpp
+ )
if ( GMOCK_FOUND AND GTEST_FOUND )
- set ( TESTHELPER_SRCS ../../../Framework/TestHelpers/src/TearDownWorld.cpp )
-
cxxtest_add_test ( CustomInterfacesTest ${TEST_FILES} ${GMOCK_TEST_FILES} )
target_link_libraries( CustomInterfacesTest CustomInterfaces DataObjects ${GMOCK_LIBRARIES} ${GTEST_LIBRARIES} )
add_dependencies( CustomInterfacesTest MDAlgorithms )