LCOV - code coverage report
Current view: top level - ugbase/bindings/lua - lua_table_handle.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 102 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 16 0

            Line data    Source code
       1              : // LICENSE HEADER
       2              : 
       3              : #include "lua_table_handle.h"
       4              : #include <iostream>
       5              : #include <assert.h>
       6              : #include "common/util/variant.h"
       7              : 
       8              : extern "C" {
       9              : #include "externals/lua/lua.h"
      10              : #include "externals/lua/lauxlib.h"
      11              : #include "externals/lua/lualib.h"
      12              : #include "externals/lua/ldo.h"
      13              : }
      14              : 
      15              : #define untested() ( std::cerr <<  "@@#\n@@@:"<< __FILE__ << ":"<< __LINE__ \
      16              :           <<":" << __func__ << "\n" )
      17              : 
      18              : namespace ug {
      19              : namespace impl {
      20              : 
      21            0 : static ug::Variant pop2var(lua_State* _L)
      22              : {
      23            0 :         int t = lua_type(_L, -1);
      24            0 :         ug::Variant ret;
      25              : 
      26            0 :         if(t == LUA_TTABLE){
      27            0 :                 LuaTableHandle h(_L, -1);
      28            0 :                 ret = ug::Variant(h);
      29            0 :         }else if(t == LUA_TNUMBER){
      30            0 :                 number n = lua_tonumber(_L, -1);
      31            0 :                 ret = ug::Variant(n);
      32            0 :         }else if(t == LUA_TBOOLEAN){
      33            0 :                 bool b = lua_toboolean(_L, -1);
      34            0 :                 ret = ug::Variant(b);
      35            0 :         }else if(lua_isstring(_L, -1)){
      36            0 :                 std::string s(lua_tostring(_L, -1));
      37            0 :                 ret = ug::Variant(s);
      38            0 :         }else if(t == LUA_TNIL){
      39              :         }else{
      40            0 :                 std::cerr << "type not handled " << t << "\n";
      41              :         }
      42              : 
      43            0 :         return ret;
      44            0 : }
      45              : 
      46              : struct LuaTableHandle_{
      47              : public:
      48              :         LuaTableHandle_(lua_State*, int);
      49              :         ~LuaTableHandle_();
      50              :         lua_State* _L{nullptr};
      51              :         int _ref{0};
      52              :         int _index{0};
      53              : 
      54              :         bool operator==(LuaTableHandle_ const& o) const{
      55            0 :                 return _ref == o._ref;
      56              :         }
      57              :         bool operator!=(LuaTableHandle_ const& o) const{
      58              :                 return !operator==(o);
      59              :         }
      60              : 
      61            0 :         static void attach(LuaTableHandle_* c, LuaTableHandle_** to) {
      62              :                 assert(to);
      63            0 :                 if (c == *to) { untested();
      64            0 :                 }else if (!c) { untested();
      65            0 :                         detach(to);
      66            0 :                 }else if (!*to) {
      67            0 :                         ++(c->_attach_count);
      68            0 :                         *to = c;
      69            0 :                 }else if (*c != **to) {
      70              :                         // They are different, usually by edit.
      71            0 :                         detach(to);
      72            0 :                         ++(c->_attach_count);
      73            0 :                         *to = c;
      74            0 :                 }else if (c->_attach_count == 0) { untested();
      75              :                         // The new and old are identical.
      76              :                         // Use the old one.
      77              :                         // The new one is not used anywhere, so throw it away.
      78            0 :                         delete c;
      79            0 :                 }else{ untested();
      80              :                         // The new and old are identical.
      81              :                         // Use the old one.
      82              :                         // The new one is also used somewhere else, so keep it.
      83              :                 }
      84            0 :         }
      85            0 :         static void detach(LuaTableHandle_** from) {
      86              :                 assert(from);
      87            0 :                 if (*from) {
      88              :                         assert((**from)._attach_count > 0);
      89            0 :                         --((**from)._attach_count);
      90            0 :                         if ((**from)._attach_count == 0) { untested();
      91            0 :                                 delete *from;
      92              :                         }else{
      93              :                         }
      94            0 :                         *from = NULL;
      95              :                 }else{
      96              :                 }
      97            0 :         }
      98              : 
      99              :         size_t size() const{
     100              :                 size_t n = 0;
     101              : #if 0 // count them. skip nils.
     102              :                 lua_pushnil(_L);
     103              :                 while (lua_next(_L, _index) != 0) { untested();
     104              :                         lua_pop(_L, 1);
     105              :                         ++n;
     106              :                 }
     107              : #else
     108            0 :                 n = lua_objlen(_L, _index);
     109              : #endif
     110              :                 return n;
     111              :         }
     112              : 
     113            0 :         ug::Variant get(int const& key) const{
     114            0 :                 lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref);
     115            0 :                 lua_rawgeti(_L, _index, key+1); // lua starts at 1.
     116              : 
     117            0 :                 ug::Variant ret = pop2var(_L);
     118              : 
     119            0 :                 lua_pop(_L, 1); // pop value
     120            0 :                 lua_pop(_L, 1); // pop ref
     121              : 
     122            0 :                 return ret;
     123            0 :         }
     124            0 :         ug::Variant get(std::string const& key) const{
     125            0 :                 lua_rawgeti(_L, LUA_REGISTRYINDEX, _ref);
     126            0 :                 lua_getfield(_L, _index, key.c_str());
     127              : 
     128              :                 // std::cerr << "getfield " << key << " type " << lua_type(_L, -1) << "\n";
     129              : 
     130            0 :                 ug::Variant ret = pop2var(_L);
     131              : 
     132            0 :                 lua_pop(_L, 1); // pop value
     133            0 :                 lua_pop(_L, 1); // pop ref
     134            0 :                 return ret;
     135            0 :         }
     136              : 
     137              : //      int get_int() const { }
     138              : 
     139              : private:
     140              :         int _attach_count{0};
     141              : };
     142              : 
     143            0 : LuaTableHandle_::LuaTableHandle_(lua_State* L, int index)
     144              : {
     145            0 :         lua_pushvalue(L, index); // copy table to top of stack.
     146            0 :         int ref = luaL_ref(L, LUA_REGISTRYINDEX); // pops copy from stack
     147              : 
     148            0 :         _ref = ref;
     149            0 :         _L = L;
     150            0 :         _index = index;
     151              : 
     152            0 :         _attach_count = 0;
     153            0 : }
     154              : 
     155            0 : LuaTableHandle_::~LuaTableHandle_()
     156            0 : { untested();
     157              :         assert(!_attach_count);
     158              : 
     159              :         // drop reference to table from index.
     160            0 :         luaL_unref(_L, LUA_REGISTRYINDEX, _ref);
     161            0 : }
     162              : 
     163              : } // impl
     164              : 
     165            0 : LuaTableHandle::LuaTableHandle(lua_State* L, int index)
     166            0 :         : _data(nullptr)
     167              : {
     168            0 :         auto d = new impl::LuaTableHandle_(L, index);
     169            0 :         impl::LuaTableHandle_::attach(d, &_data);
     170              :         //lua_settable(L, 0); // lapi.c?
     171              :         //lua_gettop(L); // lapi.c?
     172            0 : }
     173              : 
     174            0 : LuaTableHandle::LuaTableHandle(LuaTableHandle const& p)
     175            0 :     : _data(nullptr)
     176              : {
     177            0 :         impl::LuaTableHandle_::attach(p._data, &_data);
     178            0 : }
     179              : 
     180            0 : LuaTableHandle::LuaTableHandle(LuaTableHandle&& p)
     181            0 :     : _data(nullptr)
     182              : {
     183            0 :         impl::LuaTableHandle_::attach(p._data, &_data);
     184            0 :         impl::LuaTableHandle_::detach(&p._data);
     185            0 : }
     186              : 
     187            0 : LuaTableHandle::~LuaTableHandle()
     188              : {
     189            0 :         impl::LuaTableHandle_::detach(&_data);
     190            0 : }
     191              : 
     192              : 
     193            0 : LuaTableHandle& LuaTableHandle::operator=(LuaTableHandle const& p)
     194            0 : { untested();
     195            0 :         impl::LuaTableHandle_::attach(p._data, &_data);
     196            0 :         return *this;
     197              : }
     198              : 
     199            0 : LuaTableHandle& LuaTableHandle::operator=(LuaTableHandle&& p)
     200              : {
     201            0 :         impl::LuaTableHandle_::attach(p._data, &_data);
     202            0 :         impl::LuaTableHandle_::detach(&p._data);
     203            0 :         return *this;
     204              : }
     205              : 
     206            0 : size_t LuaTableHandle::size() const
     207              : {
     208              :         assert(_data);
     209            0 :         return _data->size();
     210              : }
     211              : 
     212            0 : ug::Variant LuaTableHandle::get(std::string const& key) const
     213              : {
     214              :         assert(_data);
     215            0 :         return _data->get(key);
     216              : }
     217              : 
     218            0 : ug::Variant LuaTableHandle::get(int const& key) const
     219              : {
     220              :         assert(_data);
     221            0 :         return _data->get(key);
     222              : }
     223              : 
     224              : } // ug
        

Generated by: LCOV version 2.0-1