Handle case where extension manager comes from existing Python module

This commit is contained in:
Ray Speth 2023-01-27 15:54:38 -05:00 committed by Ingmar Schoegl
parent 8114f2f828
commit ae9687ad36
5 changed files with 27 additions and 18 deletions

View File

@ -35,9 +35,7 @@ public:
void registerRateBuilder(const string& moduleName,
const string& className, const string& rateName) override;
static ExtensionManager* create() {
return new PythonExtensionManager();
}
static void registerSelf();
void registerRateDataBuilder(const string& moduleName,
const string& className, const string& rateName) override;
@ -46,7 +44,7 @@ private:
static bool s_imported;
};
BOOST_DLL_ALIAS(Cantera::PythonExtensionManager::create, create_manager);
BOOST_DLL_ALIAS(Cantera::PythonExtensionManager::registerSelf, registerPythonExtensionManager);
}

View File

@ -69,6 +69,12 @@ cdef extern from "cantera/base/ExtensionManager.h" namespace "Cantera":
shared_ptr[CxxExtensionManager] build(string&)
cdef extern from "cantera/extensions/PythonExtensionManager.h" namespace "Cantera":
cdef cppclass CxxPythonExtensionManager "Cantera::PythonExtensionManager" (CxxExtensionManager):
@staticmethod
void registerSelf()
cdef extern from "cantera/base/ExtensionManagerFactory.h" namespace "Cantera":
cdef cppclass CxxExtensionManagerFactory "Cantera::ExtensionManagerFactory":
@staticmethod

View File

@ -345,6 +345,8 @@ cdef int assign_delegates(obj, CxxDelegator* delegator) except -1:
_rate_delegators = []
_rate_data_delegators = []
CxxPythonExtensionManager.registerSelf()
def extension(*, name, data=None):
"""
A decorator for declaring Cantera extensions that should be registered with

View File

@ -406,21 +406,17 @@ void Application::loadExtension(const string& extType, const string& name)
return;
}
writelog("Loading cantera_python library\n");
typedef ExtensionManager* (creator_t)();
auto loader = boost::dll::import_alias<creator_t>( // type of imported symbol must be explicitly specified
"cantera_python", // path to library
"create_manager", // symbol to import
boost::dll::load_mode::search_system_folders | boost::dll::load_mode::append_decorations | boost::dll::load_mode::rtld_global // append extensions and prefixes, and search normal library path
);
auto manager = loader();
ExtensionManagerFactory::factory().reg("python", [&]() { return loader(); });
Cantera::writelog("Registered extensions with factory {}\n",
(void*) &ExtensionManagerFactory::factory());
manager->registerRateBuilders(name);
if (extType == "python" && !ExtensionManagerFactory::factory().exists("python")) {
typedef void (creator_t)();
static auto loader = boost::dll::import_alias<creator_t>( // type of imported symbol must be explicitly specified
"cantera_python", // path to library
"registerPythonExtensionManager", // symbol to import
boost::dll::load_mode::search_system_folders | boost::dll::load_mode::append_decorations | boost::dll::load_mode::rtld_global // append extensions and prefixes, and search normal library path
);
loader();
}
ExtensionManagerFactory::build(extType)->registerRateBuilders(name);
m_loaded_extensions.insert({extType, name});
writelog("Done loading extension\n");
}
Application* Application::s_app = 0;

View File

@ -5,6 +5,7 @@
#include "cantera/extensions/PythonExtensionManager.h"
#include "cantera/extensions/PythonHandle.h"
#include "cantera/base/ExtensionManagerFactory.h"
#include "cantera/kinetics/ReactionRateFactory.h"
#include "cantera/kinetics/ReactionRateDelegator.h"
@ -154,6 +155,12 @@ PythonExtensionManager::PythonExtensionManager()
s_imported = true;
}
void PythonExtensionManager::registerSelf()
{
ExtensionManagerFactory::factory().reg("python",
[]() { return new PythonExtensionManager(); });
}
void PythonExtensionManager::registerRateBuilders(const string& extensionName)
{
// Each rate builder class is decorated with @extension, which calls the