Re: Assign a C++ function to a global lua variable
Teto <[email protected]>
| Newsgroups | gmane.comp.lang.lua.bind.user |
|---|---|
| Message-ID | <[email protected]> |
I think I've found what was wrong: the metatable I wanted to copy was not the one from the registry (lua_settable_dispatcher) but the one from object_rep (set_instance_value) In fact what I (but that would useful for everyone) would be interested in is a little explanation (on the website maybe) about luabind inner workings. Indeed, there are very few comments and I find it hard to understand what's going on. I've understood the binding process (additive scopes, one class_rep shared between object_rep, copy of base classes tables) I think but I'm a bit lost at runtime and at how metatbles are used (I have yet to understand what's the point of :lua_settable_dispatcher). When we access via globals["key"] = value; it creates an object_rep with its own metatable. Well when I succeed in making my global instance readonly (should be soon) I will send a link as how to do it. On Sun, May 29, 2011 at 3:56 AM, Teto <[email protected]> wrote: > Here is my current function to overwrite the global metatable (doesn't seem > possible to create a metatable per type_id) , everything is ok it works (I > put it there for other people interested): > bool > CLuaVM::setSpecialNewIndex(){ > > > luabind::detail::class_registry* reg = > detail::class_registry::get_registry( _vm ); > // with templates you could possibly set a metamethod per class_rep, but > right now any type actually registered can be used to access the generic > metatable > luabind::detail::class_rep* rep = reg->find_class( > typeid(irr::SIrrlichtCreationParameters) ); > > if(!rep){ > _LOG_WARNING << "could not find a class re for this type"; > return false; > } > else { > _INFO << "found rep for class '" << rep->name() << "'"; > } > int index = rep->metatable_ref(); > > > // voici la cle utilise pour acceder au tableau representant la > metatable > lua_pushinteger( _vm, index ); > // Pushes on top of stack the metatable > lua_gettable(_vm, LUA_REGISTRYINDEX); > lua_pushstring( _vm , "__newindex"); > // Here I set my own __newindex function replacing the default one > aka class_rep::lua_settable_dispatcher > lua_pushcclosure(_vm, &onNewIndex, 0); > lua_rawset( _vm, -3); > > // pop metatable > lua_pop( _vm,1); > return true; > } > > In fact for the moment my onNewIndex function is exactly the same as the > one provided by default (I put it so that you don't have to look for it) > int onNewIndex(lua_State *L) { > > //If the value at the given acceptable index is a full userdata, > returns its block address. If the value is a light userdata, returns its > pointer. Otherwise, returns NULL. > detail::class_rep* crep = > static_cast<detail::class_rep*>(lua_touserdata( L, 1)); > > > crep->get_table(L); > > // copy key, then value > lua_pushvalue(L, -3); > lua_pushvalue(L, -3); > lua_rawset(L, -3); > > // pop table > lua_pop(L, 1); > > // get default table > crep->get_default_table(L); > lua_replace(L, 1); > lua_rawset(L, -3); > > return 0; > } > > > This function __newindex is called on the only line of my script > "config.lua" which is: > EngineConfig.DriverType = 5; > > EngineConfig is a global registered from C++ (everything works if I don't > change the luabind metatable): > luabind::object globals; > script.getGlobals(globals); > globals["EngineConfig"] = &engineParam; > > The call to my personalized __newindex function crashes because > crep->get_table(L); and crep->get_default_table(L); both push nil on the > stack instead of tables. Why is that ? > > I know this is a long mail but if you could give me a hint please. I've > already spent a lot of time on this. > > matt > > nb : Here is how I bind things: > > luabind::class_<irr::SIrrlichtCreationParameters>("SIrrlichtCreationParameters") > > .def_readwrite("DriverType",&SIrrlichtCreationParameters::DriverType) > .enum_("DriverTypes") > [ > value("opengl", video::EDT_OPENGL), > value("directx8",video::EDT_DIRECT3D8), > value("directx9",video::EDT_DIRECT3D9), > value("software",video::EDT_BURNINGSVIDEO) > ] > > > > > On Thu, May 26, 2011 at 1:11 AM, Teto <[email protected]> wrote: > >> Hi folks, >> >> I want to overwrite the __newindex method for a certain type of class from >> the C++ side (to prevent creation of new properties without me noticing it, >> it prevents me from mistyping variables). >> >> Here is as far as I go: >> bool >> CLuaVM::setSpecialNewIndex(const char* class_name){ >> >> luabind::object obj = get_class_names( getVM() ); >> luabind::object mt = getmetatable(obj[class_name]); >> >> mt["__newindex"] = specialNewIndex; // specialNewIndex should be the >> function called when __newindex is called from lua for that class >> } >> >> It's late here so maybe that's why I miss something. >> >> Matt >> > > ------------------------------------------------------------------------------ vRanger cuts backup time in half-while increasing security. With the market-leading solution for virtual backup and recovery, you get blazing-fast, flexible, and affordable data protection. Download your free trial now. http://p.sf.net/sfu/quest-d2dcopy1 _______________________________________________ luabind-user mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/luabind-user