ComIn 0.5.1
ICON Community Interface
Loading...
Searching...
No Matches
callbacks.cpp
Go to the documentation of this file.
1/* @authors 11/2023 :: ICON Community Interface <comin@icon-model.org>
2
3 SPDX-License-Identifier: BSD-3-Clause
4
5 Please see the file LICENSE in the root of the source tree for this code.
6 Where software is supplied by third parties, it is indicated in the
7 headers of the routines. */
8
9#define PY_SSIZE_T_CLEAN
10#include <Python.h>
11
12#include <map>
13#include <stdexcept>
14#include <string>
15#include <vector>
16
17#include "comin.h"
18#include "util.h"
19
20#include "callbacks.h"
21#include "exception.h"
22
23namespace comin::python {
24
25// stores a vector of callable python objects for each plugin id and entry
26// point. In contrast to the fortran and c interface we explicitly allow to
27// register multiple callbacks for every entrypoint. This makes it
28// easy to combine multiple python 3rd party modules. However, we do not make
29// any guarantees about the order in which the callbacks are called.
30static std::map<int, std::map<int, std::vector<PyObject*>>> callbacks;
31
33 int ep = 0;
35 int plugin_id = comin_current_get_plugin_id();
36 for (PyObject* fun : callbacks[plugin_id][ep]) {
37 // call it (no arguments supplied)
38 PyObject* rv = PyObject_CallObject(fun, 0);
39 Py_CLEAR(rv);
40 if (PyErr_Occurred()) {
41 PyErr_Print();
42 comin_plugin_finish("python_adapter", "Uncaught exception in callback");
43 }
44 }
45}
46
47static PyObject* callback_register(PyObject* /*self*/, PyObject* args) {
48 int ientry_point;
49 PyObject* callback;
50 if (!PyArg_ParseTuple(args, "iO", &ientry_point, &callback)) {
51 return NULL;
52 }
53 int entry_point = ientry_point;
54 if (!PyCallable_Check(callback)) {
55 return PyErr_Format(PyExc_TypeError, "A callable is required");
56 }
57
58 int plugin_id = comin_current_get_plugin_id();
59 if (callbacks[plugin_id].find(entry_point) == callbacks[plugin_id].end() &&
60 entry_point != EP_DESTRUCTOR) {
61 comin_callback_register((t_comin_entry_point)ientry_point,
64 }
65 Py_INCREF(callback);
66 callbacks[plugin_id][entry_point].push_back(callback);
67 Py_RETURN_NONE;
68}
69
70static PyObject* EP_DESCTRUCTOR(PyObject* /*self*/, PyObject* /*args*/) {
71 return PyLong_FromLong((long)EP_DESTRUCTOR);
72}
73
81static PyObject* callback_get_ep_name(PyObject* /*self*/, PyObject* args,
82 PyObject* kwargs) {
83 int iep;
84 static char const* kwlist[] = {(char*)"iep", NULL};
85 if (!PyArg_ParseTupleAndKeywords(args, kwargs, "i", (char**)&kwlist, &iep)) {
86 return NULL;
87 }
88 const char* out_ep_name =
89 comin_callback_get_ep_name((t_comin_entry_point)iep);
90 using namespace std::string_literals;
91 check_error("ep = "s + std::to_string(iep));
92 return Py_BuildValue("s", out_ep_name);
93};
94
95std::vector<PyMethodDef> callbacks_methods() {
96 return {
97 {"_callback_register", func_wrapper<callback_register>, METH_VARARGS,
98 "Registers callback to ICON"},
99 {"_EP_DESTRUCTOR", func_wrapper<EP_DESCTRUCTOR>, METH_NOARGS, ""},
100 {"callback_get_ep_name", (PyCFunction)func_wrapper<callback_get_ep_name>,
101 METH_VARARGS | METH_KEYWORDS,
102 "C function signature: const char* "
103 "comin_callback_get_ep_name(t_comin_entry_point iep)"},
104 };
105}
106} // namespace comin::python
C interface for the ICON Community Interface.
const char * comin_callback_get_ep_name(t_comin_entry_point iep)
void comin_plugin_finish(const char *routine, const char *text)
int comin_current_get_plugin_id()
t_comin_entry_point comin_current_get_ep()
Represents an Entry Point.
Definition comin.py:109
static PyObject * callback_get_ep_name(PyObject *, PyObject *args, PyObject *kwargs)
Get the name of an entry point.
Definition callbacks.cpp:81
void comin_callback_register(t_comin_entry_point entry_point, t_comin_callback_function fct_ptr)
void check_error(std::string add_info)
Definition exception.cpp:7
static PyObject * callback_register(PyObject *, PyObject *args)
Definition callbacks.cpp:47
static std::map< int, std::map< int, std::vector< PyObject * > > > callbacks
Definition callbacks.cpp:30
static PyObject * EP_DESCTRUCTOR(PyObject *, PyObject *)
Definition callbacks.cpp:70
void generic_callback()
Definition callbacks.cpp:32
std::vector< PyMethodDef > callbacks_methods()
Definition callbacks.cpp:95
PyObject * func_wrapper(PyObject *self, PyObject *args)
Definition exception.h:33