| 77 | } |
| 78 | |
| 79 | void PythonExtensionManager::registerRateBuilder( |
| 80 | const std::string& moduleName, const std::string& className, |
| 81 | const std::string& rateName) |
| 82 | { |
| 83 | // Make sure the helper module has been loaded |
| 84 | PythonExtensionManager mgr; |
| 85 | |
| 86 | // Create a function that constructs and links a C++ ReactionRateDelegator |
| 87 | // object and a Python ExtensibleRate object of a particular type, and register |
| 88 | // this as the builder for reactions of this type |
| 89 | auto builder = [moduleName, className](const AnyMap& params, const UnitStack& units) { |
| 90 | auto delegator = make_unique<ReactionRateDelegator>(); |
| 91 | PyObject* extRate = ct_newPythonExtensibleRate(delegator.get(), |
| 92 | moduleName, className); |
| 93 | if (extRate == nullptr) { |
| 94 | throw CanteraError("PythonExtensionManager::registerRateBuilders", |
| 95 | "Problem in ct_newPythonExtensibleRate:\n{}", |
| 96 | getPythonExceptionInfo()); |
| 97 | } |
| 98 | //! Call setParameters after the delegated functions have been connected |
| 99 | delegator->setParameters(params, units); |
| 100 | |
| 101 | // The delegator needs to hold a reference to the Python object to prevent |
| 102 | // garbage collection for as long as the delegator exists. Breaking the |
| 103 | // reference cycle is handled on the Python side. |
| 104 | delegator->holdExternalHandle("python", |
| 105 | make_shared<PythonHandle>(extRate, false)); |
| 106 | Py_XDECREF(extRate); |
| 107 | return delegator.release(); |
| 108 | }; |
| 109 | ReactionRateFactory::factory()->reg(rateName, builder); |
| 110 | } |
| 111 | |
| 112 | void PythonExtensionManager::registerRateDataBuilder( |
| 113 | const string& moduleName, const string& className, const string& rateName) |
nothing calls this directly
no test coverage detected