#include "python_host_node.h" #include #include "python_stdlib.h" #ifdef MTGODOT_HAVE_PYTHON // Standard types only — PythonBoot.h keeps and the Win32 shims out of this translation // unit, which has to stay compilable next to godot-cpp. #include "platform/ScriptLib/PythonBoot.h" #include "platform/EterLib/UIRenderCommands.h" #include #endif #include using namespace godot; namespace mtgodot { #ifdef MTGODOT_HAVE_PYTHON String Metin2PythonHost::start(const String &stdlib_path) { String path = stdlib_path; if (path.is_empty()) { path = Metin2Python::stdlib_path(false); if (path.is_empty()) { return String("python27.zip unavailable: ") + Metin2Python::last_error(); } } std::string error; if (!PythonBoot::Start(path.utf8().get_data(), &error)) { return String::utf8(error.c_str()); } return String(); } bool Metin2PythonHost::is_running() { return PythonBoot::IsRunning(); } String Metin2PythonHost::run_main_script(const String &command_line) { std::string error; if (!PythonBoot::RunMainScript(command_line.utf8().get_data(), &error)) { return String::utf8(error.c_str()); } return String(); } String Metin2PythonHost::run_line(const String &source) { std::string error; if (!PythonBoot::RunLine(source.utf8().get_data(), &error)) { return String::utf8(error.c_str()); } return String(); } bool Metin2PythonHost::is_app_looping() { return PythonBoot::IsAppLooping(); } void Metin2PythonHost::set_ui_size(int width, int height) { PythonBoot::SetUISize(width, height); } void Metin2PythonHost::ui_mouse_move(int x, int y) { PythonBoot::UIMouseMove(x, y); } void Metin2PythonHost::ui_mouse_button(int button, bool pressed, int x, int y) { PythonBoot::UIMouseButton(button, pressed, x, y); } void Metin2PythonHost::ui_key(int key, bool pressed) { PythonBoot::UIKey(key, pressed); } void Metin2PythonHost::ui_update() { PythonBoot::UIUpdate(); } Array Metin2PythonHost::ui_render_commands() { PythonBoot::UIRender(); Array out; for (const auto &command : UIRenderCommands()) { Dictionary item; item["kind"] = command.kind == UIRenderCommand::Bar ? "bar" : (command.kind == UIRenderCommand::Line ? "line" : (command.kind == UIRenderCommand::Image ? "image" : "text")); item["x1"] = command.x1; item["y1"] = command.y1; item["x2"] = command.x2; item["y2"] = command.y2; item["argb"] = static_cast(command.argb); item["clip_x1"] = command.clip_x1; item["clip_y1"] = command.clip_y1; item["clip_x2"] = command.clip_x2; item["clip_y2"] = command.clip_y2; if (command.kind == UIRenderCommand::Text || command.kind == UIRenderCommand::Image) item["text"] = String::utf8(command.text.c_str()); if (command.quad) { PackedVector2Array quad; for (int i = 0; i < 4; ++i) quad.push_back(Vector2(command.qx[i], command.qy[i])); item["quad"] = quad; item["uv"] = PackedVector2Array({Vector2(command.su, command.sv), Vector2(command.eu, command.sv), Vector2(command.su, command.ev), Vector2(command.eu, command.ev)}); item["blend"] = command.blend; } out.push_back(item); } return out; } void Metin2PythonHost::stop() { PythonBoot::Stop(); } #else // Built without -DMTGODOT_EMBED_PYTHON=ON: the class is still registered so GDScript can tell "no // interpreter in this build" apart from "the interpreter failed to start". String Metin2PythonHost::start(const String &) { return String("this build has no embedded Python (-DMTGODOT_EMBED_PYTHON=ON)"); } bool Metin2PythonHost::is_running() { return false; } String Metin2PythonHost::run_main_script(const String &) { return String("this build has no embedded Python (-DMTGODOT_EMBED_PYTHON=ON)"); } String Metin2PythonHost::run_line(const String &) { return String("this build has no embedded Python (-DMTGODOT_EMBED_PYTHON=ON)"); } bool Metin2PythonHost::is_app_looping() { return false; } void Metin2PythonHost::set_ui_size(int, int) {} void Metin2PythonHost::ui_mouse_move(int, int) {} void Metin2PythonHost::ui_mouse_button(int, bool, int, int) {} void Metin2PythonHost::ui_key(int, bool) {} void Metin2PythonHost::ui_update() {} Array Metin2PythonHost::ui_render_commands() { return Array(); } void Metin2PythonHost::stop() { } #endif void Metin2PythonHost::_bind_methods() { ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("start", "stdlib_path"), &Metin2PythonHost::start, DEFVAL(String())); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("is_running"), &Metin2PythonHost::is_running); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("run_main_script", "command_line"), &Metin2PythonHost::run_main_script, DEFVAL(String())); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("run_line", "source"), &Metin2PythonHost::run_line); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("is_app_looping"), &Metin2PythonHost::is_app_looping); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("set_ui_size", "width", "height"), &Metin2PythonHost::set_ui_size); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_mouse_move", "x", "y"), &Metin2PythonHost::ui_mouse_move); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_mouse_button", "button", "pressed", "x", "y"), &Metin2PythonHost::ui_mouse_button); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_key", "key", "pressed"), &Metin2PythonHost::ui_key); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_update"), &Metin2PythonHost::ui_update); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("ui_render_commands"), &Metin2PythonHost::ui_render_commands); ClassDB::bind_static_method("Metin2PythonHost", D_METHOD("stop"), &Metin2PythonHost::stop); } } // namespace mtgodot