/
PythonModule.cpp
110 lines (90 loc) · 2.13 KB
/
PythonModule.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
#include "PythonModule.h"
// Stringify and concatenate the PYBIND11_VERSION_xxx preprocessor symbols
#define Str(x) #x
#define QUOTE(x) Str(x)
#define PYBIND11_VERSION_STR (QUOTE(PYBIND11_VERSION_MAJOR) "." QUOTE(PYBIND11_VERSION_MINOR) "." QUOTE(PYBIND11_VERSION_PATCH))
#include "itextstream.h"
namespace script
{
const char* PythonModule::NAME()
{
return "darkradiant";
}
py::module& PythonModule::GetModule()
{
if (!_module)
{
_module.reset(new py::module(NAME()));
}
return *_module;
}
void PythonModule::RegisterToPython(const ModuleRegistrationCallback& callback)
{
_registrationCallback = callback;
rMessage() << "Registering darkradiant module to Python using pybind11 version " <<
PYBIND11_VERSION_STR << std::endl;
// Register the darkradiant module to Python
int result = PyImport_AppendInittab(NAME(), InitModule);
if (result == -1)
{
rError() << "Could not initialise Python module" << std::endl;
return;
}
}
py::dict& PythonModule::GetGlobals()
{
if (!_globals)
{
_globals.reset(new py::dict);
}
return *_globals;
}
void PythonModule::Clear()
{
_module.reset();
_globals.reset();
}
#if PY_MAJOR_VERSION >= 3
PyObject* PythonModule::InitModule()
{
return InitModuleImpl();
}
#else
void PythonModule::InitModule()
{
InitModuleImpl();
}
#endif
PyObject* PythonModule::InitModuleImpl()
{
try
{
// Acquire modules here (through callback?)
if (_registrationCallback)
{
_registrationCallback(GetModule(), GetGlobals());
}
py::object main = py::module::import("__main__");
py::dict globals = main.attr("__dict__").cast<py::dict>();
for (auto i = globals.begin(); i != globals.end(); ++i)
{
GetGlobals()[(*i).first] = (*i).second;
}
return _module->ptr();
}
catch (py::error_already_set& e)
{
//e.clear();
PyErr_SetString(PyExc_ImportError, e.what());
return nullptr;
}
catch (const std::exception& e)
{
PyErr_SetString(PyExc_ImportError, e.what());
return nullptr;
}
}
std::unique_ptr<py::module> PythonModule::_module;
std::unique_ptr<py::dict> PythonModule::_globals;
PythonModule::ModuleRegistrationCallback PythonModule::_registrationCallback;
}