From 3743bd34e97e02f92fd9bcb8547ef7cb7a9ce9f0 Mon Sep 17 00:00:00 2001 From: Martyn Gigg <martyn.gigg@stfc.ac.uk> Date: Tue, 22 Oct 2013 14:45:56 +0100 Subject: [PATCH] Unsubscribe any loader that has been replaced by a Python algorithm. If we don't then we get a crash in the FileLoaderRegistry that tries to cast to an incorrect type. Refs #8177 --- .../API/inc/MantidAPI/FileLoaderRegistry.h | 7 ++++ .../Framework/API/src/FileLoaderRegistry.cpp | 42 +++++++++++++++++++ .../api/src/Exports/AlgorithmFactory.cpp | 6 ++- 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h b/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h index efee45e2c52..9707f11d361 100644 --- a/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h +++ b/Code/Mantid/Framework/API/inc/MantidAPI/FileLoaderRegistry.h @@ -80,6 +80,9 @@ namespace Mantid m_log.debug() << "Registered '" << nameVersion.first << "' version '" << nameVersion.second << "' as file loader\n"; } + /// Unsubscribe a named algorithm and version from the loader registration + void unsubscribe(const std::string &name, const int version = -1); + /// Returns the name of an Algorithm that can load the given filename const boost::shared_ptr<IAlgorithm> chooseLoader(const std::string &filename) const; /// Checks whether the given algorithm can load the file @@ -121,6 +124,10 @@ namespace Mantid } }; + /// Remove a named algorithm & version from the given map + void removeAlgorithm(const std::string & name, const int version, + std::multimap<std::string,int> & typedLoaders); + /// The list of names. The index pointed to by LoaderFormat defines a set for that format std::vector<std::multimap<std::string,int> > m_names; /// Total number of names registered diff --git a/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp b/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp index 11836e3632b..084ce2c20f3 100644 --- a/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp +++ b/Code/Mantid/Framework/API/src/FileLoaderRegistry.cpp @@ -49,6 +49,7 @@ namespace Mantid const int version = it->second; logger.debug() << "Checking " << name << " version " << version << std::endl; + // Use static cast for speed. Checks have been done at registration to check the types auto alg = boost::static_pointer_cast<FileLoaderType>(factory.create(name, version)); // highest version try { @@ -75,6 +76,20 @@ namespace Mantid // Public members //---------------------------------------------------------------------------------------------- + /** + * If the name does not exist then it does nothing + * @param name Name of the algorithm to remove from the search list + * @aparam version An optional version to remove. -1 indicates remove all (Default=-1) + */ + void FileLoaderRegistryImpl::unsubscribe(const std::string &name, const int version) + { + auto iend = m_names.end(); + for(auto it = m_names.begin(); it != iend; ++it) + { + removeAlgorithm(name, version, *it); + } + } + /** * Queries each registered algorithm and asks it how confident it is that it can * load the given file. The name of the one with the highest confidence is returned. @@ -161,5 +176,32 @@ namespace Mantid { } + /** + * @param name A string containing the algorithm name + * @param version The version to remove. -1 indicates all instances + * @param typedLoaders A map of names to version numbers + **/ + void FileLoaderRegistryImpl::removeAlgorithm(const std::string & name, const int version, + std::multimap<std::string,int> & typedLoaders) + { + if(version == -1) // remove all + { + typedLoaders.erase(name); + } + else // find the right version + { + auto range = typedLoaders.equal_range(name); + for(auto ritr = range.first; ritr != range.second; ++ritr) + { + if(ritr->second == version) + { + typedLoaders.erase(ritr); + break; + } + } + } + } + + } // namespace API } // namespace Mantid diff --git a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp index 6dd925e9d04..d241f44b8a6 100644 --- a/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp +++ b/Code/Mantid/Framework/PythonInterface/mantid/api/src/Exports/AlgorithmFactory.cpp @@ -1,5 +1,6 @@ #include "MantidAPI/AlgorithmFactory.h" #include "MantidAPI/Algorithm.h" +#include "MantidAPI/FileLoaderRegistry.h" #include "MantidKernel/WarningSuppressions.h" #include "MantidPythonInterface/kernel/PythonObjectInstantiator.h" #include "MantidPythonInterface/api/PythonAlgorithm/PythonAlgorithm.h" @@ -90,7 +91,10 @@ GCC_DIAG_OFF(cast-qual) } boost::python::object classType(handle<>(borrowed(classObject))); // Takes ownership of instantiator and replaces any existing algorithm - self.subscribe(new PythonObjectInstantiator<Algorithm>(classType), AlgorithmFactoryImpl::OverwriteCurrent); + auto descr = self.subscribe(new PythonObjectInstantiator<Algorithm>(classType), AlgorithmFactoryImpl::OverwriteCurrent); + + // Python algorithms cannot yet act as loaders so remove any registered ones from the FileLoaderRegistry + FileLoaderRegistry::Instance().unsubscribe(descr.first, descr.second); } ///@endcond -- GitLab