diff --git a/.gitignore b/.gitignore index 4caf500..d5c87cf 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ temp/ install/ .vscode/ .vs/ +.idea/ +cmake-build-*/ *.kdev4 *~ CMakeSettings.json diff --git a/include/wrenbind17/caller.hpp b/include/wrenbind17/caller.hpp index 9521cbb..8969b19 100644 --- a/include/wrenbind17/caller.hpp +++ b/include/wrenbind17/caller.hpp @@ -221,7 +221,7 @@ namespace wrenbind17 { static void getter(WrenVM* vm) { auto self = PopHelper::f(vm, 0); - PushHelper::f(vm, 0, std::forward*Ptr)>(self->*Ptr)); + PushHelper::f(vm, 0, &(self->*Ptr)); } }; } // namespace detail diff --git a/include/wrenbind17/push.hpp b/include/wrenbind17/push.hpp index 7c94a40..d3a459d 100644 --- a/include/wrenbind17/push.hpp +++ b/include/wrenbind17/push.hpp @@ -175,6 +175,12 @@ namespace wrenbind17 { } }; + template <> struct PushHelper { + static inline void f(WrenVM* vm, int idx, const std::string* value) { + wrenSetSlotString(vm, idx, value->c_str()); + } + }; + template struct PushHelper { static inline void f(WrenVM* vm, int idx, const char (&value)[N]) { wrenSetSlotString(vm, idx, value); diff --git a/tests/operators.cpp b/tests/operators.cpp index 4d1c0d3..69c7132 100644 --- a/tests/operators.cpp +++ b/tests/operators.cpp @@ -1,5 +1,6 @@ -#include #include +#include +#include #include namespace wren = wrenbind17; diff --git a/tests/props.cpp b/tests/props.cpp index a40702c..ccea354 100644 --- a/tests/props.cpp +++ b/tests/props.cpp @@ -284,3 +284,88 @@ TEST_CASE("Properties from base class") { } } +typedef struct Vector2 { + float x; + float y; +} Vector2; + +typedef struct Camera2D { + Vector2 offset; + float rotation; + + void debug() const { + std::cout << "Camera2D" << std::endl; + std::cout << "offset: " << offset.x << ", " << offset.y << std::endl; + std::cout << "rotation: " << rotation << std::endl; + } +} Camera2D; + +TEST_CASE("Properties of properties") { + wren::VM vm; + auto& m = vm.module("test"); + + { + auto& cls = m.klass("Vector2"); + cls.ctor<>(); + cls.var<&Vector2::x>("x"); + cls.var<&Vector2::y>("y"); + } + + { + auto& cls = m.klass("Camera2D"); + cls.ctor<>(); + cls.var<&Camera2D::offset>("offset"); + cls.var<&Camera2D::rotation>("rotation"); + cls.func<&Camera2D::debug>("debug"); + } + + const std::string code = R"( + import "test" for Camera2D, Vector2 + + class Main { + static main1() { + var cam = Camera2D.new() + + cam.rotation = 180 + cam.offset.x = 1280 + cam.offset.y = 768 + + System.print("Cam Offset: %(cam.offset.x), %(cam.offset.y) ") + cam.debug() + + return cam.offset.x + } + + static main2() { + var cam = Camera2D.new() + + cam.rotation = 180 + cam.offset.x = 1280 + cam.offset.y = 768 + + System.print("Cam Offset: %(cam.offset.x), %(cam.offset.y) ") + cam.debug() + + return cam.offset + } + } + )"; + + vm.runFromSource("main", code); + + { // Main 1, return a component of a property + auto main = vm.find("main", "Main").func("main1()"); + auto r = main(); + REQUIRE(r.is()); + REQUIRE(r.as() == Approx(1280.0f)); + } + + { // Main 2, return a property itself + auto main = vm.find("main", "Main").func("main2()"); + auto r = main(); + REQUIRE(r.is()); + auto vec = r.as(); + REQUIRE(vec.x == Approx(1280.0f)); + REQUIRE(vec.y == Approx(768.0f)); + } +}