From da044bd21ccbae6971321da229809ceabb5f2bae Mon Sep 17 00:00:00 2001 From: S6066 Date: Sun, 17 Jun 2018 19:04:15 +0200 Subject: [PATCH] Make lua binding for std::vector (#164) * Make LuaImplQueryArg impl for std::vector * Fix shadowed argument * Make unit tests * Bugfix * Bugfix, for real this time * We didn't need these tests anyway * Revert "We didn't need these tests anyway" This reverts commit be88d4496a9cf62beb4d3ce1f30825589a4bacb2. * Add change to changelog * Update ChangeLog.md * Bugfix & use CallOnExit to pop stack --- ChangeLog.md | 2 ++ include/Nazara/Lua/LuaState.inl | 29 +++++++++++++++++++++++++++++ tests/Engine/Lua/LuaState.cpp | 29 +++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+) diff --git a/ChangeLog.md b/ChangeLog.md index 1a5abbb6b..fea6b4033 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -107,6 +107,8 @@ Nazara Engine: - Added AbstractViewer::Project and AbstractViewer::Unproject methods - Added AbstractViewer::ProjectDepth method - Fixed SocketPoller not be able to recover from some errors (like invalid sockets and such) +- Add LuaImplQuery implementation for std::vector +- Fixed LuaState::PushGlobal & LuaState::PushField to copy the object before moving it - ⚠️ Replaced currentBitPos and currentByte fields by [read|write][BitPos][Byte] to handle properly bit reading/writing. - InstancedRenderable::SetMaterial methods are now public. - Fixed Model copy constructor not copying materials diff --git a/include/Nazara/Lua/LuaState.inl b/include/Nazara/Lua/LuaState.inl index 7dcc4e36f..3d6f5ae1e 100644 --- a/include/Nazara/Lua/LuaState.inl +++ b/include/Nazara/Lua/LuaState.inl @@ -3,6 +3,7 @@ // For conditions of distribution and use, see copyright notice in Config.hpp #include +#include #include #include #include @@ -159,6 +160,34 @@ namespace Nz return LuaImplQueryArg(instance, index, arg, defValue, TypeTag()); } + template + unsigned int LuaImplQueryArg(const LuaState& instance, int index, std::vector* container, TypeTag>) + { + instance.CheckType(index, Nz::LuaType_Table); + std::size_t pos = 1; + + for (;;) + { + Nz::CallOnExit popStack { [&instance]() { instance.Pop(); } }; + instance.PushInteger(pos++); + + if (instance.GetTable() == Nz::LuaType_Nil) + break; + + T arg {}; + + if (LuaImplQueryArg(instance, -1, &arg, TypeTag()) != 1) + { + instance.Error("Type needs more than one place to be initialized"); + return 0; + } + + container->push_back(arg); + } + + return 1; + } + // Function returns inline int LuaImplReplyVal(const LuaState& instance, bool val, TypeTag) { diff --git a/tests/Engine/Lua/LuaState.cpp b/tests/Engine/Lua/LuaState.cpp index ef2965517..430927d98 100644 --- a/tests/Engine/Lua/LuaState.cpp +++ b/tests/Engine/Lua/LuaState.cpp @@ -183,5 +183,34 @@ SCENARIO("LuaState", "[LUA][LUASTATE]") CHECK(luaInstance.ToNumber(1) == Approx(-4.09).margin(0.1)); } } + + WHEN("We push a std::vector locally") + { + std::vector vec { 1, 5, -8, 6, -4 }; + luaInstance.Push(std::vector { vec }); + + THEN("We can retrieve it with correct values") + { + int index = 1; + std::vector otherVec = luaInstance.Check>(&index); + + for (std::size_t i {}; i < otherVec.size(); ++i) + CHECK(otherVec[i] == vec[i]); + } + } + + WHEN("We push a std::vector globally") + { + std::vector vec { 1, 5, -8, 6, -4 }; + luaInstance.PushGlobal("vector", std::vector { vec }); + + THEN("We can retrieve it with correct values") + { + std::vector otherVec = luaInstance.CheckGlobal>("vector"); + + for (std::size_t i {}; i < otherVec.size(); ++i) + CHECK(otherVec[i] == vec[i]); + } + } } }