File: PythonModule.h

package info (click to toggle)
darkradiant 3.9.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 41,080 kB
  • sloc: cpp: 264,743; ansic: 10,659; python: 1,852; xml: 1,650; sh: 92; makefile: 21
file content (82 lines) | stat: -rw-r--r-- 2,149 bytes parent folder | download | duplicates (2)
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
#pragma once

#include "iscript.h"
#include "iscriptinterface.h"
#include <functional>
#include <memory>
#include <pybind11/pybind11.h>

#include "PythonConsoleWriter.h"
#include "ScriptCommand.h"

namespace py = pybind11;

namespace script
{

class PythonModule final
{
private:
    std::unique_ptr<py::module::module_def> _moduleDef;

	// Python module and global dictionary
	py::module _module;
	std::unique_ptr<py::dict> _globals;

    // List of registered interfaces
	NamedInterfaces _namedInterfaces;

    PythonModule(const PythonModule& other) = delete;
    PythonModule& operator=(const PythonModule& other) = delete;

    // We need a static reference to the current object, since 
    // PyImport_AppendInittab doesn't allow us to pass user data
    static PythonModule* _instance;

    // Console and Error output handling
    std::string _outputBuffer;
    std::string _errorBuffer;

    PythonConsoleWriter _outputWriter;
    PythonConsoleWriter _errorWriter;

    bool _interpreterInitialised;

public:
    PythonModule();
    ~PythonModule();

    // Starts up the interpreter, imports the darkradiant module
    void initialise();

    ExecutionResultPtr executeString(const std::string& scriptString);

    // Execute the given script file
    void executeScriptFile(const std::string& scriptBasePath, const std::string& relativeScriptPath, bool setExecuteCommandAttr);

	// Get the global object dictionary of this module
	py::dict& getGlobals();

    void addInterface(const NamedInterface& iface);

    // Attempts to create a script command from the given .py file
    // Will return an empty object if the file path is not a valid file
    ScriptCommand::Ptr createScriptCommand(const std::string& scriptBasePath, const std::string& relativeScriptPath);

private:
    // Register the darkradiant module with the inittab pointing to InitModule
    void registerModule();

    bool interfaceExists(const std::string& name);

	// Endpoint called by the Python interface to acquire the module
#if PY_MAJOR_VERSION >= 3
	static PyObject* InitModule();
#else
	static void InitModule();
#endif

	PyObject* initialiseModule();
};

}