as_function¶
make sure an object is pushed as a function
template <typename Sig = sol::function_sig<>, typename... Args>
function_argumants<Sig, Args...> as_function ( Args&& ... );
This function serves the purpose of ensuring that a callable struct (like a lambda) can be passed to the set( key, value )
calls on sol::table and be treated like a function binding instead of a userdata. It is recommended that one uses the sol::table::set_function call instead, but if for some reason one must use set
, then as_function
can help ensure a callable struct is handled like a lambda / callable, and not as just a userdata structure.
This class can also make it so usertypes bind variable types as functions to for usertype bindings.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main () {
struct callable {
int operator()( int a, bool b ) {
return a + (b ? 10 : 20);
}
};
sol::state lua;
// Binds struct as userdata
// can still be callable, but beware
// caveats
lua.set( "not_func", callable() );
// Binds struct as function
lua.set( "func", sol::as_function( callable() ) );
// equivalent: lua.set_function( "func", callable() );
// equivalent: lua["func"] = callable();
}
|
Note that if you actually want a userdata, but you want it to be callable, you simply need to create a sol::table::new_usertype and then bind the "__call"
metamethod (or just use sol::meta_function::call
enumeration). This may or may not be done automatically for you, depending on whether or not the call operator is overloaded and such.
Here’s an example of binding a variable as a function to a usertype:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #define SOL_ALL_SAFETIES_ON 1
#include <sol/sol.hpp>
int main () {
class B {
public:
int bvar = 24;
};
sol::state lua;
lua.open_libraries(sol::lib::base);
lua.new_usertype<B>("B",
// bind as variable
"b", &B::bvar,
// bind as function
"f", sol::as_function(&B::bvar)
);
B b;
lua.set("b", &b);
lua.script(R"(x = b:f()
y = b.b
assert(x == 24)
assert(y == 24)
)");
return 0;
}
|