Exteor/include/xtr/core/PyCore.h
2024-06-07 20:30:06 +03:00

116 lines
3.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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 programs 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