#include "PythonEngine.h" #include #include #include #include "../Engine.h" #include namespace py = pybind11; PythonEngine& PythonEngine::Get() { static PythonEngine instance; return instance; } void PythonEngine::Init() { if (initialized_) { SDL_Log("[Python] Already initialized"); return; } py::initialize_interpreter(); try { py::module_::import("sys").attr("path").attr("append")("assets/scripts"); SDL_Log("[Python] scripts/ path added"); } catch (const py::error_already_set& e) { SDL_Log("[Python] Error setting sys.path: %s", e.what()); } // Release GIL immidiately so game loop can run freely PyEval_SaveThread(); initialized_ = true; SDL_Log("[Python] Embedded interpreter ready (managed by scoped_interpreter)"); } void PythonEngine::Shutdown() { if (initialized_) { return; } PyEval_RestoreThread(PyGILState_GetThisThreadState()); py::finalize_interpreter(); initialized_ = false; } void PythonEngine::Exec(const std::string& code) { py::gil_scoped_acquire gil; try { py::exec(code); } catch (const py::error_already_set& e) { SDL_Log("[Python] Error: %s", e.what()); } catch (const std::exception& e) { SDL_Log("[Python] Error: %s", e.what()); } }