🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

"Class" fields for functions in Lua

Started by
4 comments, last by Servant of the Lord 9 years, 5 months ago

Hey everyone, I am implementing Lua script system into my engine, I have added simple functions like:

println
getclientnum
...
fastsqrt
gethostname
.. etc

But I want to make them like:

core.println
server.getclientnum
...
gamemath.fastsqrt
server.gethostname
.. etc

Here's my "RegisterFunction" code, it simply adds function into Lua script. I know lua_setfield, but when I try to use it doesn't work or whatever. I have tried to write "core:println('text')" and like core. ( with dot ).

    template<>
    void ncLuaScript::RegisterConstant<lua_CFunction>( lua_CFunction value, const char* constantname )
    {
        lua_pushcclosure( L, value, 0);
        lua_setglobal( L, constantname );
    }

Could someone help me with this, please? Thanks in advance!

Advertisement

But I want to make them like:
core.println

You'll need to create global lua tables "core", "server", etc, and put related functions in those tables.

See luaL_register() for lua 5.1.

For lua 5.2 you'll need to explicitly create table, fill it with luaL_setfuncs() and then store table in global variable.


tried to write "core:println('text')" and like core. ( with dot )

Be careful. Those are very different constructs.

While both will extract function to call from table, colon version (":") will also pass table itself as first argument to function.

Tha


But I want to make them like:
core.println

You'll need to create global lua tables "core", "server", etc, and put related functions in those tables.

See luaL_register() for lua 5.1.

For lua 5.2 you'll need to explicitly create table, fill it with luaL_setfuncs() and then store table in global variable.


tried to write "core:println('text')" and like core. ( with dot )

Be careful. Those are very different constructs.

While both will extract function to call from table, colon version (":") will also pass table itself as first argument to function.

Thanks! Figured it out:

 bool ncLuaScript::CreateClassTable( const char *classname ) {
        // Push table onto stack.
        lua_getglobal( L, classname );
        //lua_getfield(lstate, LUA_GLOBALSINDEX, "core");
        
        // Not a table, create it.
        if( !lua_istable( L, -1 ) )
        {
            lua_createtable( L, 0, 1 );      // Create new table.
            //lua_setfield( L, LUA_GLOBALSINDEX, tableName);  // Add it to global context.
            lua_setglobal( L, classname );
            // Reset table on stack.
            lua_pop(L, 1);                 // Pop table (nil value) from stack.
            //lua_getfield(lstate, LUA_GLOBALSINDEX, tableName);  // Push table onto stack.
            lua_getglobal( L, classname );
        }
        return true;
    }

And here's usage:

 
 
 
       template<>
    void ncLuaScript::RegisterConstant<lua_CFunction>( lua_CFunction value, const char *classname, const char* constantname )
    {
        CreateClassTable( classname );
        
        lua_pushstring( L, constantname );       // push key onto stack
        lua_pushcfunction( L, value ); // push value onto stack
        lua_settable( L, -3 );               // add key-value pair to table
        
        lua_pop( L, 1 );                     // Pop table from stack.
 
    }

Well, I got another problem with "variadic templates".

I have

template<typename... t>
void ExecuteArgs( t... args );

in foo class. If I call 'ExecuteArgs(1337, "hello");' from 'bar' class compiler shows linker error as undefined reference to 'ExecuteArgs( int, char const* )' - but well, eh, it's wrong!

How to fix this?


How to fix this?

Most likely you've declared template, but not defined it in include file.

You must either define entire ExecuteArgs() body within .h file, or explicitly instantiate that template in one of .cpp files.

Well, I got another problem with "variadic templates".

I have


template<typename... t>
void ExecuteArgs( t... args );

in foo class. If I call 'ExecuteArgs(1337, "hello");' from 'bar' class compiler shows linker error as undefined reference to 'ExecuteArgs( int, char const* )' - but well, eh, it's wrong!

How to fix this?

Are you trying to call your variadic template from Lua? Does Lua have support for C++'s variadic templates? I would assume it can only reference c-style functions. I mean, Lua can't exactly store a function pointer to a function that doesn't exist. Templates generate functions during compilation only if that function with those arguments are actually called. If you are delaying your function call until after compilation, by running a run-time script, the template can't generate the function while the game is running.

So, actually, the error message is right. There is an undefined reference to a function that doesn't exist because it hasn't been generated during compile time because no function, at compile time, actually called that specific version. You can wrap a few c-style functions to overload it. Or one c-style function that takes a variadic amount of Lua arguments that detect what type those arguments are and then forwards it to the C++ variadic template function - but you'd still have to "enable" a specific set and combination of arguments because of the aforementioned "not generated at compile-time" problem.

This topic is closed to new replies.

Advertisement