diff --git a/include/cantera/base/Delegator.h b/include/cantera/base/Delegator.h index 9aee98729e..2d1ac9e997 100644 --- a/include/cantera/base/Delegator.h +++ b/include/cantera/base/Delegator.h @@ -7,6 +7,7 @@ #define CT_DELEGATOR_H #include "cantera/base/global.h" +#include "cantera/base/Units.h" #include "cantera/base/ctexceptions.h" #include "cantera/base/ExtensionManager.h" #include @@ -254,8 +255,21 @@ class Delegator *m_funcs_sz_csr[name] = makeDelegate(name, func, when, m_base_sz_csr[name]); } - void holdExternalHandle(const shared_ptr& handle) { - m_handles.push_back(handle); + //! Store a handle to a wrapper for the delegate from an external language interface + void holdExternalHandle(const string& name, + const shared_ptr& handle) { + m_handles[name] = handle; + } + + //! Get the handle for a wrapper for the delegate from the external language + //! interface specified by *name*. + //! Returns a null pointer if the requested handle does not exist. + shared_ptr getExternalHandle(const string& name) const { + if (m_handles.count(name)) { + return m_handles.at(name); + } else { + return shared_ptr(); + } } protected: @@ -496,8 +510,10 @@ class Delegator std::function*> m_funcs_sz_csr; //! @} - //! Cleanup functions to be called from the destructor - std::list> m_handles; + //! Handles to wrappers for the delegated object in external language interfaces. + //! Used to provide access to these wrappers as well as managing cleanup functions + //! called from the destructor of the derived ExternalHandle class. + map> m_handles; //! Name of the class in the extension language std::string m_delegatorName; diff --git a/include/cantera/base/Solution.h b/include/cantera/base/Solution.h index 376c6ba954..6c88891afc 100644 --- a/include/cantera/base/Solution.h +++ b/include/cantera/base/Solution.h @@ -137,7 +137,7 @@ class Solution : public std::enable_shared_from_this AnyMap m_header; //!< Additional input fields; usually from a YAML input file - //! Wrappers for this Kinetics object in extension languages, for evaluation + //! Wrappers for this Solution object in extension languages, for evaluation //! of user-defined reaction rates std::map> m_externalHandles; diff --git a/interfaces/cython/cantera/delegator.pxd b/interfaces/cython/cantera/delegator.pxd index 39011a392d..9a1034999f 100644 --- a/interfaces/cython/cantera/delegator.pxd +++ b/interfaces/cython/cantera/delegator.pxd @@ -22,11 +22,22 @@ cdef extern from "" namespace "std" nogil: size_t& operator[](size_t) +cdef extern from "cantera/extensions/PythonHandle.h" namespace "Cantera": + cdef cppclass CxxExternalHandle "Cantera::ExternalHandle": + pass + + cdef cppclass CxxPythonHandle "Cantera::PythonHandle" (CxxExternalHandle): + CxxPythonHandle(PyObject*, cbool) + PyObject* get() + + cdef extern from "cantera/base/Delegator.h" namespace "Cantera": cdef cppclass CxxDelegator "Cantera::Delegator": Delegator() void setDelegatorName(string&) + void holdExternalHandle(string&, shared_ptr[CxxExternalHandle]&) + shared_ptr[CxxExternalHandle] getExternalHandle(string&) void setDelegate(string&, function[void()], string&) except +translate_exception void setDelegate(string&, function[void(cbool)], string&) except +translate_exception diff --git a/interfaces/cython/cantera/solutionbase.pxd b/interfaces/cython/cantera/solutionbase.pxd index 0e209feb4b..c8aee47b6d 100644 --- a/interfaces/cython/cantera/solutionbase.pxd +++ b/interfaces/cython/cantera/solutionbase.pxd @@ -8,6 +8,8 @@ import numpy as np cimport numpy as np from .ctcxx cimport * +from .delegator cimport CxxExternalHandle + cdef extern from "cantera/thermo/ThermoFactory.h" namespace "Cantera": cdef cppclass CxxThermoPhase "Cantera::ThermoPhase" @@ -29,14 +31,6 @@ cdef extern from "cantera/base/Interface.h" namespace "Cantera": string, string, vector[string]) except +translate_exception -cdef extern from "cantera/extensions/PythonHandle.h" namespace "Cantera": - cdef cppclass CxxExternalHandle "Cantera::ExternalHandle": - pass - - cdef cppclass CxxPythonHandle "Cantera::PythonHandle" (CxxExternalHandle): - CxxPythonHandle(PyObject*, cbool) - - cdef extern from "cantera/base/Solution.h" namespace "Cantera": cdef cppclass CxxKinetics "Cantera::Kinetics" cdef cppclass CxxTransport "Cantera::Transport" diff --git a/interfaces/cython/cantera/solutionbase.pyx b/interfaces/cython/cantera/solutionbase.pyx index 1eb140f1df..65eb3fca86 100644 --- a/interfaces/cython/cantera/solutionbase.pyx +++ b/interfaces/cython/cantera/solutionbase.pyx @@ -12,7 +12,7 @@ from .kinetics cimport * from .transport cimport * from .reaction cimport * from ._utils cimport * -from .delegator cimport pyOverride, callback_v +from .delegator cimport pyOverride, callback_v, CxxPythonHandle from .yamlwriter cimport YamlWriter ctypedef CxxSurfPhase* CxxSurfPhasePtr diff --git a/src/extensions/PythonExtensionManager.cpp b/src/extensions/PythonExtensionManager.cpp index b6b1a52446..6dc9c36cba 100644 --- a/src/extensions/PythonExtensionManager.cpp +++ b/src/extensions/PythonExtensionManager.cpp @@ -99,7 +99,8 @@ void PythonExtensionManager::registerRateBuilder( delegator->setParameters(params, units); // The delegator is responsible for eventually deleting the Python object - delegator->holdExternalHandle(make_shared(extRate, false)); + delegator->holdExternalHandle("python", + make_shared(extRate, false)); return delegator.release(); }; ReactionRateFactory::factory()->reg(rateName, builder);