Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LuaTableHandle continued #67

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion ugbase/bindings/lua/lua_parsing.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,6 @@ struct LuaParsing<LuaTableHandle>{
}
static LuaTableHandle get(lua_State* L, int index){
LuaTableHandle tmp(L, index);
untested();
return tmp;
}
static void push(lua_State* L, LuaTableHandle data){
Expand Down
200 changes: 184 additions & 16 deletions ugbase/bindings/lua/lua_table_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
#include "lua_table_handle.h"
#include <iostream>
#include <assert.h>
#include <sstream>
#include <iomanip>
#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"
Expand All @@ -12,9 +18,6 @@ extern "C" {
#include "externals/lua/ldo.h"
}

#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \
<<":" << __func__ << "\n" )

namespace ug {
namespace impl {

Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand All @@ -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);
Expand All @@ -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
31 changes: 30 additions & 1 deletion ugbase/bindings/lua/lua_table_handle.h
Original file line number Diff line number Diff line change
Expand Up @@ -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<std::string, ug::Variant> 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&&);

Expand Down
21 changes: 21 additions & 0 deletions ugbase/common/util/trace.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@

#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" )
#else
#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
3 changes: 1 addition & 2 deletions ugbase/common/util/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,9 @@

#include "common/error.h"
#include "variant.h"
#include "trace.h"

#include <iostream>
#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \
<<":" << __func__ << "\n" )

using namespace std;

Expand Down
3 changes: 1 addition & 2 deletions ugbase/registry/parameter_stack.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -44,8 +45,6 @@
#define __H__UG_BRIDGE__PARAMETER_STACK__

#include <iostream>
#define untested() ( std::cerr << "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \
<<":" << __func__ << "\n" )

namespace ug
{
Expand Down