116 lines
3.2 KiB
C
116 lines
3.2 KiB
C
![]() |
#pragma once
|
|||
|
|
|||
|
#include <string>
|
|||
|
#include <map>
|
|||
|
|
|||
|
// Note: forward declare basic object class for Python
|
|||
|
struct _object; // NOLINT(bugprone-reserved-identifier, cert-dcl37-c, cert-dcl51-cpp)
|
|||
|
|
|||
|
namespace cxxpython {
|
|||
|
|
|||
|
//! PyObject wrapper
|
|||
|
/*!
|
|||
|
Uses Python ref counting
|
|||
|
*/
|
|||
|
class Object {
|
|||
|
_object* object;
|
|||
|
|
|||
|
public:
|
|||
|
~Object() noexcept;
|
|||
|
Object(const Object& obj2) noexcept;
|
|||
|
Object& operator=(const Object& obj2) noexcept;
|
|||
|
Object(Object&& obj2) noexcept;
|
|||
|
Object& operator=(Object&& obj2) noexcept;
|
|||
|
|
|||
|
private:
|
|||
|
explicit Object(_object* objectIn) noexcept
|
|||
|
: object{ objectIn } {}
|
|||
|
|
|||
|
public:
|
|||
|
explicit(false) Object(nullptr_t) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
|
|||
|
: object{ nullptr } {}
|
|||
|
[[nodiscard]] static Object FromNew(_object* objectIn) noexcept;
|
|||
|
[[nodiscard]] static Object FromBorrowed(_object* objectIn) noexcept;
|
|||
|
|
|||
|
public:
|
|||
|
[[nodiscard]] Object at(int index) const noexcept;
|
|||
|
[[nodiscard]] constexpr bool operator!=(nullptr_t) const noexcept { return object != nullptr; }
|
|||
|
[[nodiscard]] constexpr bool operator==(nullptr_t) const noexcept { return object == nullptr; }
|
|||
|
|
|||
|
// Note: use with Python/C API only!
|
|||
|
[[nodiscard]] constexpr _object* get() noexcept { return object; }
|
|||
|
[[nodiscard]] constexpr _object* get() const noexcept { return object; }
|
|||
|
|
|||
|
private:
|
|||
|
void DecreaseRefCount() noexcept;
|
|||
|
};
|
|||
|
|
|||
|
//! Convert object to string
|
|||
|
std::string ToString(const Object& object);
|
|||
|
|
|||
|
//! Convert object to long
|
|||
|
long ToLong(const Object& object) noexcept;
|
|||
|
|
|||
|
//! Convert object to bool
|
|||
|
bool ToBool(const Object& object) noexcept;
|
|||
|
|
|||
|
//! Python callable wrapper
|
|||
|
class Callable {
|
|||
|
Object func;
|
|||
|
|
|||
|
public:
|
|||
|
explicit(false) Callable(nullptr_t) noexcept // NOLINT(google-explicit-constructor, hicpp-explicit-conversions)
|
|||
|
: func{ nullptr } {}
|
|||
|
explicit Callable(_object* object) noexcept;
|
|||
|
|
|||
|
public:
|
|||
|
constexpr bool operator!=(nullptr_t) const noexcept { return func != nullptr; }
|
|||
|
constexpr bool operator==(nullptr_t) const noexcept { return func == nullptr; }
|
|||
|
|
|||
|
Object operator()() const noexcept;
|
|||
|
Object operator()(const char* format, ...) const noexcept;
|
|||
|
};
|
|||
|
|
|||
|
//! Python interpreter wrapper
|
|||
|
class PyCore {
|
|||
|
struct Module {
|
|||
|
Object pyModule{ nullptr };
|
|||
|
Object pyDictionary{ nullptr };
|
|||
|
};
|
|||
|
|
|||
|
bool isRunning{ false };
|
|||
|
std::map<std::string, Module> modules{};
|
|||
|
|
|||
|
public:
|
|||
|
PyCore(const PyCore&) = delete;
|
|||
|
PyCore& operator=(const PyCore&) = delete;
|
|||
|
|
|||
|
private:
|
|||
|
~PyCore();
|
|||
|
PyCore() = default;
|
|||
|
|
|||
|
public:
|
|||
|
static PyCore& Instance();
|
|||
|
|
|||
|
public:
|
|||
|
//! Start Python interpreter from local path.
|
|||
|
/*!
|
|||
|
Requires: The argument should point to a zero-terminated character string
|
|||
|
in static storage whose contents will not change
|
|||
|
for the duration of the program’s execution
|
|||
|
see https://docs.python.org/3/c-api/init.html#c.Py_SetPythonHome
|
|||
|
*/
|
|||
|
bool Start(const wchar_t* pyPath = nullptr) noexcept;
|
|||
|
|
|||
|
//! Stop Python interpreter.
|
|||
|
/*!
|
|||
|
Requires: Every Object should be destroyed before calling PyCore.Stop()
|
|||
|
*/
|
|||
|
void Stop() noexcept;
|
|||
|
[[nodiscard]] bool IsRunning() const noexcept;
|
|||
|
|
|||
|
bool LoadModule(const std::string& moduleName, const std::string& pyFileName);
|
|||
|
[[nodiscard]] Callable PyFunction(const std::string& moduleName, const std::string& funcName) const;
|
|||
|
};
|
|||
|
|
|||
|
} // namespace cxxpython
|