From 9e82abe8741db0418bb007a892a6631f24343bbe Mon Sep 17 00:00:00 2001 From: Felix Salfelder Date: Wed, 1 Jun 2022 00:00:00 +0100 Subject: [PATCH] LuaTableHandle continued - tidy up traces - tweak trace header - cleanup stray untested definitions - default constructible LuaTableHandle - index bug fix - iterate pairs to mimic lua pairs( .. ) --- ugbase/bindings/lua/lua_parsing.h | 1 - ugbase/bindings/lua/lua_table_handle.cpp | 200 +++++++++++++++++++++-- ugbase/bindings/lua/lua_table_handle.h | 31 +++- ugbase/common/util/trace.h | 21 +++ ugbase/common/util/variant.cpp | 3 +- ugbase/registry/parameter_stack.h | 3 +- 6 files changed, 237 insertions(+), 22 deletions(-) diff --git a/ugbase/bindings/lua/lua_parsing.h b/ugbase/bindings/lua/lua_parsing.h index bc32f7715..23d907aa7 100644 --- a/ugbase/bindings/lua/lua_parsing.h +++ b/ugbase/bindings/lua/lua_parsing.h @@ -175,7 +175,6 @@ struct LuaParsing{ } static LuaTableHandle get(lua_State* L, int index){ LuaTableHandle tmp(L, index); - untested(); return tmp; } static void push(lua_State* L, LuaTableHandle data){ diff --git a/ugbase/bindings/lua/lua_table_handle.cpp b/ugbase/bindings/lua/lua_table_handle.cpp index c8f5979ce..672a576c5 100644 --- a/ugbase/bindings/lua/lua_table_handle.cpp +++ b/ugbase/bindings/lua/lua_table_handle.cpp @@ -3,7 +3,13 @@ #include "lua_table_handle.h" #include #include +#include +#include #include "common/util/variant.h" +#include "common/util/trace.h" + +#define TRACE_UNTESTED +#include "common/util/trace.h" extern "C" { #include "externals/lua/lua.h" @@ -12,9 +18,6 @@ extern "C" { #include "externals/lua/ldo.h" } -#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ - <<":" << __func__ << "\n" ) - namespace ug { namespace impl { @@ -39,6 +42,7 @@ static ug::Variant pop2var(lua_State* _L) }else{ std::cerr << "type not handled " << t << "\n"; } + lua_pop(_L, 1); // pop value return ret; } @@ -97,39 +101,41 @@ struct LuaTableHandle_{ } size_t size() const{ + lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref); + size_t ret = lua_objlen(_L, -1); + lua_pop(_L, 1); + return ret; + } + + size_t count() const{ untested(); + lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref); size_t n = 0; -#if 0 // count them. skip nils. lua_pushnil(_L); - while (lua_next(_L, _index) != 0) { untested(); + while (lua_next(_L, -2) != 0) { untested(); lua_pop(_L, 1); ++n; } -#else - n = lua_objlen(_L, _index); -#endif + lua_pop(_L, 1); return n; } ug::Variant get(int const& key) const{ lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref); - lua_rawgeti(_L, _index, key+1); // lua starts at 1. + lua_rawgeti(_L, -1, key+1); // lua starts at 1. ug::Variant ret = pop2var(_L); - lua_pop(_L, 1); // pop value lua_pop(_L, 1); // pop ref return ret; } ug::Variant get(std::string const& key) const{ + // std::cerr << "LTH::get " << key << " ref " << _ref << "idx" << _index << "\n"; lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref); - lua_getfield(_L, _index, key.c_str()); - - // std::cerr << "getfield " << key << " type " << lua_type(_L, -1) << "\n"; + lua_getfield(_L, -1, key.c_str()); ug::Variant ret = pop2var(_L); - lua_pop(_L, 1); // pop value lua_pop(_L, 1); // pop ref return ret; } @@ -189,9 +195,19 @@ LuaTableHandle::~LuaTableHandle() impl::LuaTableHandle_::detach(&_data); } +bool LuaTableHandle::operator==(LuaTableHandle const& o) const +{ + if(_data == o._data){ + return true; + }else if(_data && o._data){ + return *_data == *o._data; + }else{ + return false; + } +} LuaTableHandle& LuaTableHandle::operator=(LuaTableHandle const& p) -{ untested(); +{ impl::LuaTableHandle_::attach(p._data, &_data); return *this; } @@ -203,6 +219,12 @@ LuaTableHandle& LuaTableHandle::operator=(LuaTableHandle&& p) return *this; } +size_t LuaTableHandle::count() const +{ untested(); + assert(_data); + return _data->count(); +} + size_t LuaTableHandle::size() const { assert(_data); @@ -216,9 +238,155 @@ ug::Variant LuaTableHandle::get(std::string const& key) const } ug::Variant LuaTableHandle::get(int const& key) const -{ +{ untested(); assert(_data); return _data->get(key); } +LuaTableHandle::const_iter LuaTableHandle::begin() +{ + return const_iter(_data); +} + +LuaTableHandle::const_iter LuaTableHandle::end() +{ + return const_iter(); +} + +LuaTableHandle::const_iter::const_iter() + : _data(nullptr), _keyref(-1), _valref(-1), _cnt(-1) +{ +} + +LuaTableHandle::const_iter::const_iter(LuaTableHandle::const_iter const& o) + : _data(nullptr), _keyref(o._keyref), _valref(o._valref), _cnt(o._cnt) +{ untested(); + impl::LuaTableHandle_::attach(o._data, &_data); + + if(!_data){ untested(); + }else if(_cnt!=-1){ untested(); + auto L = _data->_L; + lua_rawgeti(L, LUA_REGISTRYINDEX, _keyref); + _keyref = luaL_ref(L, LUA_REGISTRYINDEX); + lua_rawgeti(L, LUA_REGISTRYINDEX, _valref); + _valref = luaL_ref(L, LUA_REGISTRYINDEX); + }else{ untested(); + } +} + +LuaTableHandle::const_iter::~const_iter() +{ + if(_cnt==-1){ + }else if(_data){ untested(); + luaL_unref(_data->_L, LUA_REGISTRYINDEX, _keyref); + luaL_unref(_data->_L, LUA_REGISTRYINDEX, _valref); + impl::LuaTableHandle_::attach(nullptr, &_data); + }else{ + } +} + +LuaTableHandle::const_iter::const_iter(impl::LuaTableHandle_ /* const */ * d) + : _data(nullptr), _keyref(-1), _valref(-1), _cnt(-1) +{ + impl::LuaTableHandle_::attach(d, &_data); + assert(_data); + auto L = _data->_L; + lua_rawgeti(L, LUA_REGISTRYINDEX, _data->_ref); // get table. + + lua_pushnil(L); + + if(lua_next(L, -2)) { + _cnt = 0; + _valref = luaL_ref(L, LUA_REGISTRYINDEX); // pop value + _keyref = luaL_ref(L, LUA_REGISTRYINDEX); // pop key + }else{ + } +} + +LuaTableHandle::const_iter& +LuaTableHandle::const_iter::operator=(LuaTableHandle::const_iter const& o) +{ untested(); + _keyref = o._keyref; + _valref = o._valref; + _cnt = o._cnt; + impl::LuaTableHandle_::attach(o._data, &_data); + + if(!_data){ untested(); + }else if(_cnt!=-1){ untested(); + auto L = _data->_L; + lua_rawgeti(L, LUA_REGISTRYINDEX, _keyref); + _keyref = luaL_ref(L, LUA_REGISTRYINDEX); + lua_rawgeti(L, LUA_REGISTRYINDEX, _valref); + _valref = luaL_ref(L, LUA_REGISTRYINDEX); + }else{ untested(); + } + + return *this; +} + +bool LuaTableHandle::const_iter::operator==(LuaTableHandle::const_iter const& o) const +{ + return _cnt == o._cnt; +} + +static std::string lua_like_string(double number) +{ + std::ostringstream oss; + oss << std::fixed << std::setprecision(2) << number; + std::string s = oss.str(); + if(s.find('.') != std::string::npos) { + s = s.substr(0, s.find_last_not_of('0')+1); + if(s.find('.') == s.size()-1) { + s = s.substr(0, s.size()-1); + }else{ + } + }else{ + } + return s; +} + +LuaTableHandle::const_iter::value_type +LuaTableHandle::const_iter::operator*() const +{ + assert(_data); + auto L = _data->_L; + + lua_rawgeti(L, LUA_REGISTRYINDEX, _keyref); // get key + ug::Variant f = ug::impl::pop2var(L); // string? + + // std::cerr << "deref, key " << f << "\n"; + std::string ff; + try{ + ff = f.to_std_string(); + }catch(...){ + ff = lua_like_string(f.to_float()); + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, _valref); // get value + ug::Variant s = ug::impl::pop2var(L); + + return std::make_pair(ff, s); +} + +LuaTableHandle::const_iter& LuaTableHandle::const_iter::operator++() +{ + assert(_data); + auto L = _data->_L; + // std::cerr << "op++ " << _data->_ref << " " << _keyref << "\n"; + lua_rawgeti(L, LUA_REGISTRYINDEX, _data->_ref); + lua_rawgeti(L, LUA_REGISTRYINDEX, _keyref); // get key. + if(lua_next(L, -2)) { + ++_cnt; + lua_rawseti(L, LUA_REGISTRYINDEX, _valref); // pops from stack + lua_rawseti(L, LUA_REGISTRYINDEX, _keyref); // pops from stack + }else{ + _cnt = -1; + _keyref = -1; + _valref = -1; + lua_pop(L, 1); + } + lua_pop(L, 1); // pop table + return *this; +} + } // ug diff --git a/ugbase/bindings/lua/lua_table_handle.h b/ugbase/bindings/lua/lua_table_handle.h index 64c372d38..1d05fd2f9 100644 --- a/ugbase/bindings/lua/lua_table_handle.h +++ b/ugbase/bindings/lua/lua_table_handle.h @@ -48,17 +48,46 @@ struct LuaTableHandle_; /// Handle for a lua reference class LuaTableHandle /* public SuitableBaseClass */ { public: - LuaTableHandle() = delete; + class const_iter /* erase in SuitableBaseClass */ { + typedef std::pair value_type; + public: + const_iter(); + ~const_iter(); + const_iter(impl::LuaTableHandle_ /*const*/ * _data); + const_iter(const_iter const&); + + public: + value_type operator*() const; + const_iter& operator++(); + const_iter& operator=(const_iter const& o); + bool operator==(const_iter const& o) const; + bool operator!=(const_iter const& o) const{ + return !operator==(o); + } + + private: + impl::LuaTableHandle_ /*const*/ * _data; + int _keyref; + int _valref; + int _cnt; + }; // const_iter +public: + LuaTableHandle() : _data(nullptr) {} LuaTableHandle(LuaTableHandle const&); LuaTableHandle(LuaTableHandle&&); explicit LuaTableHandle(lua_State* ref, int idx); ~LuaTableHandle(); public: + bool operator==(LuaTableHandle const& o) const; size_t size() const; + size_t count() const; ug::Variant get(std::string const& key) const; ug::Variant get(int const& key) const; + const_iter begin(); + const_iter end(); + LuaTableHandle& operator=(LuaTableHandle const&); LuaTableHandle& operator=(LuaTableHandle&&); diff --git a/ugbase/common/util/trace.h b/ugbase/common/util/trace.h index 8d70b6ba1..91d7468ec 100644 --- a/ugbase/common/util/trace.h +++ b/ugbase/common/util/trace.h @@ -1,4 +1,13 @@ +#ifdef untested +#undef untested +#endif + +#ifdef itested +#undef itested +#endif + +// untested: not reached by any test. #ifdef TRACE_UNTESTED #define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ <<":" << __func__ << "\n" ) @@ -6,10 +15,22 @@ #define untested() #endif +// interactively tested: no test required. +#ifdef TRACE_ITESTED +#define itested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ + <<":" << __func__ << "\n" ) +#else #define itested() +#endif + +#ifndef incomplete #define incomplete() ( \ std::cerr << "@@#\n@@@\nincomplete:" \ << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n" ) +#endif + +#ifndef unreachable #define unreachable() ( \ std::cerr << "@@#\n@@@\nunreachable:" \ << __FILE__ << ":" << __LINE__ << ":" << __func__ << "\n" ) +#endif diff --git a/ugbase/common/util/variant.cpp b/ugbase/common/util/variant.cpp index 25c3fc9f6..0ad784ddc 100644 --- a/ugbase/common/util/variant.cpp +++ b/ugbase/common/util/variant.cpp @@ -32,10 +32,9 @@ #include "common/error.h" #include "variant.h" +#include "trace.h" #include -#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ - <<":" << __func__ << "\n" ) using namespace std; diff --git a/ugbase/registry/parameter_stack.h b/ugbase/registry/parameter_stack.h index 2da61c2d5..ecd484de7 100644 --- a/ugbase/registry/parameter_stack.h +++ b/ugbase/registry/parameter_stack.h @@ -36,6 +36,7 @@ #include "common/common.h" #include "common/util/smart_pointer.h" #include "common/util/variant.h" +#include "common/util/trace.h" #ifdef UG_FOR_LUA #include "bindings/lua/lua_function_handle.h" #endif @@ -44,8 +45,6 @@ #define __H__UG_BRIDGE__PARAMETER_STACK__ #include -#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \ - <<":" << __func__ << "\n" ) namespace ug {