From c92c6d44328b3564b8c892b26f142e7ed23e2a4b Mon Sep 17 00:00:00 2001 From: MartinOpat Date: Tue, 11 Nov 2025 00:22:57 +0100 Subject: [PATCH] godot-cpp init. --- .gitmodules | 4 ++ game-of-life-test/thirdparty/.gitignore | 10 +++ game-of-life-test/thirdparty/SConstruct | 31 ++++++++ game-of-life-test/thirdparty/godot-cpp | 1 + game-of-life-test/thirdparty/gol.gdextension | 9 +++ game-of-life-test/thirdparty/src/gol.cpp | 75 ++++++++++++++++++++ 6 files changed, 130 insertions(+) create mode 100644 .gitmodules create mode 100644 game-of-life-test/thirdparty/.gitignore create mode 100644 game-of-life-test/thirdparty/SConstruct create mode 160000 game-of-life-test/thirdparty/godot-cpp create mode 100644 game-of-life-test/thirdparty/gol.gdextension create mode 100644 game-of-life-test/thirdparty/src/gol.cpp diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..9febd5b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "game-of-life-test/thirdparty/godot-cpp"] + path = game-of-life-test/thirdparty/godot-cpp + url = https://github.com/godotengine/godot-cpp.git + branch = 4.5 diff --git a/game-of-life-test/thirdparty/.gitignore b/game-of-life-test/thirdparty/.gitignore new file mode 100644 index 0000000..3f52458 --- /dev/null +++ b/game-of-life-test/thirdparty/.gitignore @@ -0,0 +1,10 @@ +bin +*.uid +*sconsign.dblite +**.os + +game-of-life-test/thirdparty/godot-cpp/bin/ +game-of-life-test/thirdparty/bin/ +*.o +*.so + diff --git a/game-of-life-test/thirdparty/SConstruct b/game-of-life-test/thirdparty/SConstruct new file mode 100644 index 0000000..fdfada3 --- /dev/null +++ b/game-of-life-test/thirdparty/SConstruct @@ -0,0 +1,31 @@ +import os +from SCons.Script import DefaultEnvironment, ARGUMENTS, Glob, Dir + +env = DefaultEnvironment() +platform = ARGUMENTS.get("platform", "linux") +target = ARGUMENTS.get("target", "template_debug") # or template_release +arch = ARGUMENTS.get("arch", "x86_64") + +HERE = Dir(".").abspath +GODOTCPP = os.path.join(HERE, "godot-cpp") + +inc_paths = [ + os.path.join(GODOTCPP, "include"), + os.path.join(GODOTCPP, "gen", "include"), +] +for extra in ("godot-headers", "gdextension"): + p = os.path.join(GODOTCPP, extra) + if os.path.isdir(p): + inc_paths.append(p) + +env.Append(CPPPATH=inc_paths) +env.Append(LIBPATH=[os.path.join(GODOTCPP, "bin")]) +env.Append(CXXFLAGS=["-std=c++17", "-fPIC"]) + +env.Append(LIBS=[f"godot-cpp.{platform}.{target}.{arch}"]) + +outdir = os.path.join(HERE, "bin") +os.makedirs(outdir, exist_ok=True) +soname = f"gol.{platform}.{'debug' if target == 'template_debug' else 'release'}.{arch}" + +env.SharedLibrary(target=os.path.join(outdir, soname), source=Glob("src/*.cpp")) diff --git a/game-of-life-test/thirdparty/godot-cpp b/game-of-life-test/thirdparty/godot-cpp new file mode 160000 index 0000000..abe9457 --- /dev/null +++ b/game-of-life-test/thirdparty/godot-cpp @@ -0,0 +1 @@ +Subproject commit abe94570a16e38eec442d1c9acc0c518c479e725 diff --git a/game-of-life-test/thirdparty/gol.gdextension b/game-of-life-test/thirdparty/gol.gdextension new file mode 100644 index 0000000..b81b90b --- /dev/null +++ b/game-of-life-test/thirdparty/gol.gdextension @@ -0,0 +1,9 @@ + +[configuration] +entry_symbol = "gol_library_init" +compatibility_minimum = "4.5" ; required in 4.5+ +reloadable = true + +[libraries] +linux.debug.x86_64 = "res://thirdparty/bin/libgol.linux.debug.x86_64" + diff --git a/game-of-life-test/thirdparty/src/gol.cpp b/game-of-life-test/thirdparty/src/gol.cpp new file mode 100644 index 0000000..f4b1ac1 --- /dev/null +++ b/game-of-life-test/thirdparty/src/gol.cpp @@ -0,0 +1,75 @@ + +// src/gol.cpp + +#include +#include +#include +#include +#include +#include + +using namespace godot; + +class GoL : public RefCounted { + GDCLASS(GoL, RefCounted); + + static void _bind_methods() { + ClassDB::bind_method(D_METHOD("step_once", "arr", "n"), &GoL::step_once); + } + + static int neighs(const Array &a, int n, int x, int y) { + int s = 0; + for (int dy = -1; dy <= 1; ++dy) { + for (int dx = -1; dx <= 1; ++dx) { + if (dx == 0 && dy == 0) + continue; + const int nx = ((x + dx) % n + n) % n; + const int ny = ((y + dy) % n + n) % n; + const Array row = a[ny]; + s += (int)row[nx]; + } + } + return s; + } + +public: + Array step_once(const Array &arr, int n) const { + Array next; + next.resize(n); + for (int y = 0; y < n; ++y) { + Array row; + row.resize(n); + const Array crow = arr[y]; + for (int x = 0; x < n; ++x) { + const bool alive = ((int)crow[x]) == 1; + const int cn = neighs(arr, n, x, y); + row.set(x, alive ? int(cn == 2 || cn == 3) : int(cn == 3)); + } + next.set(y, row); + } + return next; + } +}; + +extern "C" GDExtensionBool GDE_EXPORT +gol_library_init(GDExtensionInterfaceGetProcAddress get_proc_address, + GDExtensionClassLibraryPtr library, + GDExtensionInitialization *r_initialization) { + + static GDExtensionBinding::InitObject init(get_proc_address, library, + r_initialization); + + init.register_initializer([](ModuleInitializationLevel p_level) { + if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) + return; + ClassDB::register_class(); + }); + + init.register_terminator([](ModuleInitializationLevel /*p_level*/) { + // no-op + }); + + init.set_minimum_library_initialization_level( + MODULE_INITIALIZATION_LEVEL_SCENE); + return init.init(); +}