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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.