2

I have a problem with Lua and I don't know if I going in the right direction. In C++ I have a dictionary that I use to pass parameter to a resource manager. This dictionary is really similar to a map of hash and string.

In Lua I want to access to these resource so I need a representation of hashes. Also hashes must be unique cause are used as index in a table. Our hash function is 64bit and I'm working on 32bit enviroment (PS3).

C++ I have somethings like that:

paramMap.insert(std::make_pair(hash64("vehicleId"), std::string("004")));
resourceManager.createResource(ResourceType("Car"), paramMap);

In Lua want use these resources to create a factory for other userdata. I do stuff like:

function findBike(carId)
   bikeParam = { vehicleId = carId }
   return ResourceManager.findResource('car', bikeParam)
end

So, sometime parameter are created by Lua, sometime parameter are created by C++. Cause my hashkey ('vehicleId') is an index of a table it need to be unique. I have used lightuserdata to implement uint64_t, but cause I'm in a 32bit enviroment I can't simply store int64 in pointer. :(

I have to create a table to store all int64 used by the program and save a reference in userdata.

void pushUInt64(lua_State *L, GEM::GUInt64 v)
{
  Int64Ref::Handle handle = Int64Ref::getInstance().allocateSlot(v);
  lua_pushlightuserdata(L, reinterpret_cast<void*>(handle));
  luaL_setmetatable(L, s_UInt64LuaName);
}

but userdata are never garbage collected. Then my int64 are never released and my table will grow forever. Also lightuserdata don't keep reference to metadata so they interfere with other light userdata. Checking the implementation the metadata table is added in L->G_->mt_[2]. doing that

a = createLightUserDataType1()
b = createLightUserDataType2()
a:someFunction()

will use the metatable of b.

I thought that metatable where bounded to type. I'm pretty confused, with the current implementation lightuserdata have a really limited use case.

With Python you have a hash metafunction that is called anytime the type is used as index for a dictionary. It's possible to do something similar?

Sorry for my english, I'm from Italy. :-/

ilmale
  • 418
  • 3
  • 12
  • What about using full userdata? Those are managed and garbage collected by lua. And each full userdata can have its own metatable. – greatwolf Dec 14 '13 at 21:03
  • @greatwolf: I use full userdata almost for anything, but in this particular case I have to index a table.If hash64(str) produce a full user data then a = hash64("vType"); b = hash64("vType"); c ={}; c[a] = "car"; print(c[b]); will print nil, cause a end b have different pointer. – ilmale Dec 15 '13 at 11:39
  • What if you cache and map the computed hash value to a weak table? This way you ensure that when you do `a = hash64("vType"); b = hash64("vType");`, `a` and `b` will refer to the same userdata. – greatwolf Dec 16 '13 at 05:25
  • What if you store your hash as a lua string? – Daniel Jan 21 '14 at 15:54
  • Now cause we need to close the project we are doing exactly that. And it works, but when I have some more time I'll use the solution suggested by greatwolf. A weak table and before give a new hash64 object around I check if the object already exist in the table. – ilmale Jan 21 '14 at 21:00

0 Answers0