فهرست منبع

More on Python

Vitaliy Polonski 1 روز پیش
والد
کامیت
a2b38ac544
5فایلهای تغییر یافته به همراه72 افزوده شده و 28 حذف شده
  1. 6 5
      src/Engine.cpp
  2. 0 1
      src/Engine.h
  3. 31 7
      src/scripting/PythonEngine.cpp
  4. 1 10
      src/scripting/PythonEngine.h
  5. 34 5
      src/scripting/bindings/kariokaModule.cpp

+ 6 - 5
src/Engine.cpp

@@ -143,16 +143,17 @@ void Engine::InitPython()
     {
         throw std::runtime_error("Engine instance already created! Only one Engine allowed");
     }
+    
     s_instance = this;
     
     PythonEngine::Get().Init();
     
     PythonEngine::Get().Exec(R"(
-        import karioka
-        e = karioka.engine()
-        e.DebugInfo()
-        karioka.log(\"Python module for kariokaEngine initialized\")
-    )", *this);
+import karioka
+karioka.log('Python module for kariokaEngine initialized')
+e = karioka.engine()
+e.DebugInfo()
+)");
 }
 
 void Engine::ShutdownPython()

+ 0 - 1
src/Engine.h

@@ -59,7 +59,6 @@ private:
     void InitPython();
     void ShutdownPython();
     void RunPythonScript(const std::string& filename);
-    std::unique_ptr<py::scoped_interpreter> pythonInterpreter;
     static Engine* s_instance;
 
     // StateManager

+ 31 - 7
src/scripting/PythonEngine.cpp

@@ -3,6 +3,7 @@
 #include <filesystem>
 #include <iostream>
 #include "../Engine.h"
+#include <SDL2/SDL_log.h>
 
 namespace py = pybind11;
 
@@ -14,18 +15,29 @@ PythonEngine& PythonEngine::Get()
 
 void PythonEngine::Init()
 {
-    if (initialized_) { return; }
-    
-    // Tell python where do scripts live
-    py::module_::import("sys").attr("path").attr("append")("scripts");
+    if (initialized_)
+    {
+        SDL_Log("[Python] Already initialized");
+        return;
+    }
     
-    // Initialize interpreter
     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()
@@ -37,8 +49,20 @@ void PythonEngine::Shutdown()
     initialized_ = false;
 }
 
-void PythonEngine::Exec(const std::string& code, Engine& engine)
+void PythonEngine::Exec(const std::string& code)
 {
     py::gil_scoped_acquire gil;
-    py::exec(code);
+    
+    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());
+    }
 }

+ 1 - 10
src/scripting/PythonEngine.h

@@ -4,7 +4,6 @@
 #include <pybind11/embed.h>
 #include <string>
 #include <functional>
-#include "../Engine.h"
 
 namespace py = pybind11;
 
@@ -16,18 +15,10 @@ public:
     void Init();
     void Shutdown();
     
-    void Exec(const std::string& code, Engine& engine);
+    void Exec(const std::string& code);
     
-    py::object Call(const std::string& module, const std::string& func, py::args args = {});
-    
-    // Hot reload scripts for later
-    void ReloadAllScripts();
-
 private:
     PythonEngine() = default;
-    ~PythonEngine() = default;
-    
-    py::scoped_interpreter guard_;
     bool initialized_ = false;
 
 };

+ 34 - 5
src/scripting/bindings/kariokaModule.cpp

@@ -8,19 +8,48 @@ namespace py = pybind11;
 
 class Engine;
 
-PYBIND11_MODULE(karioka, m)
+PYBIND11_EMBEDDED_MODULE(karioka, m)
 {
     m.doc() = "kariokaEngine Python API";
     
-    // Bind the Engine class itself
+    // Bind the Engine class
     py::class_<Engine, std::unique_ptr<Engine, py::nodelete>> engine_cls(m, "Engine");
     
-    // Simple log function
-    m.def("log",  [](const std::string& msg) {
+    // Bind useful methods from Engine
+    engine_cls.def("DebugInfo", &Engine::DebugInfo);
+    engine_cls.def("StopRunning", &Engine::StopRunning);
+    engine_cls.def("IsRunning", &Engine::IsRunning);
+    
+    // State management
+    engine_cls.def("RequestStateChange", &Engine::RequestStateChange);
+    engine_cls.def("RequestPopState", &Engine::RequestPopState);
+    
+    // SDL resources
+    engine_cls.def("GetRenderer", &Engine::GetRenderer, py::return_value_policy::reference);
+    engine_cls.def("GetWindow", &Engine::GetWindow, py::return_value_policy::reference);
+    
+    // Logging
+    engine_cls.def("log",  [](Engine& self, const std::string& msg) {
         SDL_Log("[PY] %s", msg.c_str());
     });
     
-    // Get engine reference
+    // Static accessor
     engine_cls.def_static("get", &Engine::Get, py::return_value_policy::reference);
+
+    // === Convenient top-level functions ==
     m.def("engine", &Engine::Get, py::return_value_policy::reference);
+    
+    m.def("log", [](const std::string& msg) {
+        SDL_Log("[PY] %s", msg.c_str());
+    });
+    
+    m.def("quit", []() {
+        Engine::Get().StopRunning();
+        SDL_Log("[PY] Quit requested from Python");
+    });
+    
+    m.def("run_script", [](const std::string& filename) {
+        Engine::Get().RunPythonScript(filename);
+    });
+    
 }