Git Product home page Git Product logo

Comments (7)

kunitoki avatar kunitoki commented on June 29, 2024

Can you provide an example usage of this pointer from lua ? Seems like a weak pointer is what is needed.

from luabridge3.

rpatters1 avatar rpatters1 commented on June 29, 2024

I had in mind using it something like this:

function set_metadata(xmlnode, node_metadata)
     xmlnode:SetUserData(node_metadata)
end

Then in some central processing routine:

function process_node(xmlnode)
   local metadata = xmlnode:GetUserData()
   if (metadata) then
      -- do something with metadata
   end
end

The metadata might be a table or a string or any lua value. I realize there are lifetime issues around garbage collection. That's why I wonder if this is even worth pursuing.

from luabridge3.

rpatters1 avatar rpatters1 commented on June 29, 2024

To further flesh it out, here is a hypothetical outline of the proxy functions in C++ that I was imagining:

int proxySetter(lua_State* L)
{
   tinyxml2::XMLNode* node = luabridge::Stack<tinyxml2::XMLNode*>::get(L, 1).value();
   luabridge::LuaRef data = luabridge::Stack<luabridge::LuaRef>::get(L, 2).value();
   int ref = ??? // do some magic with the LuaRef, presumably to get the Lua registry index. not sure.
   node->SetUserData(reinterpret_cast<void*>(ref));
   return 0;
}

int proxyGetter(lua_State *L)
{
   const tinyxml2::XMLNode* node = luabridge::Stack<const tinyxml2::XMLNode*>::get(L, 1).value();
   int ref = reinterpret_cast<int>(node->GetUserData());
   if (!ref)
      lua_pushnil(L);
   else
   {
      luabridge::LuaRef data = ??? // do some magic with the ref to hydrate a LuaRef from the Lua registry index
      // if it has been garbage collected, we push nil, otherwise:
      luabridge::Stack<luabridge::LuaRef>::push(L, data).throw_on_error();
   }
   return 1;
}

from luabridge3.

kunitoki avatar kunitoki commented on June 29, 2024

Yeah this is not going to work easily, mainly because you have no way to keep the lifetime of said void* in neither c++ nor lua, unless you store the lua object in some global table and ensure it exceed the lifetime of the usage of that void* which might be out of your control.

You can probably try using a weak table in the registry, with a key being a lightuserdata with the address of your XMLNode and a weak value being the lua object you want to obtain (in this case you don't need the UserData at all). Not sure if this compiles, but should give you the idea (the trick here is to use the __mode as "v" to set weak values, so those entries are not keeping it those objects alive forever, and keys could be removed as soon as your XMLNode is destroyed, even tho you might need a finalizer).

// Setup
lua_newtable(L);
lua_newtable(L);
lua_pushstring(L, "v");
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, "__xml_user_data");

// Set
tinyxml2::XMLNode* node = luabridge::Stack<tinyxml2::XMLNode*>::get(L, 1).value();

lua_getfield(L, LUA_REGISTRYINDEX, "__xml_user_data");
lua_pushlightuserdata(L, node);
lua_pushvalue(L, 2); // the lua object you want to store
lua_settable(L, -3);

// Get
tinyxml2::XMLNode* node = luabridge::Stack<tinyxml2::XMLNode*>::get(L, 1).value();

lua_getfield(L, LUA_REGISTRYINDEX, "__xml_user_data");
lua_pushlightuserdata(L, node);
lua_gettable(L, -2);

from luabridge3.

kunitoki avatar kunitoki commented on June 29, 2024

Maybe that will not work as you want to keep the value alive, but only if the key is not expired (and the key should be the userdata).

// Setup
lua_newtable(L);
lua_newtable(L);
lua_pushstring(L, "k");
lua_setfield(L, -2, "__mode");
lua_setmetatable(L, -2);
lua_setfield(L, LUA_REGISTRYINDEX, "__xml_user_data");

// Set
lua_getfield(L, LUA_REGISTRYINDEX, "__xml_user_data");
lua_pushvalue(L, 1); // the tinyxml2::XMLNode* as key
lua_pushvalue(L, 2); // the lua object you want to store as value
lua_settable(L, -3);

// Get
lua_getfield(L, LUA_REGISTRYINDEX, "__xml_user_data");
lua_pushvalue(L, 1); // the tinyxml2::XMLNode* as key
lua_gettable(L, -2);

from luabridge3.

kunitoki avatar kunitoki commented on June 29, 2024

See http://lua-users.org/wiki/WeakTablesTutorial for some ideas

from luabridge3.

rpatters1 avatar rpatters1 commented on June 29, 2024

Thanks for all the ideas. I'll ponder it and give it more study. It may not make v1. I'm not sure how useful the feature in tinyxml2 is, in any case.

from luabridge3.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.