#include #include #include #include struct foo { private: std::string name; public: foo(std::string name): name(std::string(name)) {} void print() { std::cout << name << '\n'; } int test(int x) { return name.length() + x; } }; struct vector { private: float x = 0; float y = 0; public: vector() = default; vector(float x): x(x) {} vector(float x, float y): x(x), y(y) {} bool is_unit() const { return (x * x + y * y) == 1.f; } }; int main() { sol::state lua; lua.open_libraries(sol::lib::base, sol::lib::math); // the simplest way to create a class is through // sol::state::new_userdata // the first template is the class type // the rest are the constructor parameters // using new_userdata you can only have one constructor // you must make sure that the name of the function // goes before the member function pointer lua.new_userdata("foo", "print", &foo::print, "test", &foo::test); // making the class from lua is simple // same with calling member functions lua.script("x = foo.new('test')\n" "x:print()\n" "y = x:test(10)"); auto y = lua.get("y"); assert(y == 14); // if you want a class to have more than one constructor // the way to do so is through set_userdata and creating // a userdata yourself with constructor types // first, define the different types of constructors sol::constructors, sol::types, sol::types> ctor; // second, create a new userdata class // note that you have to make sure the class is // alive throughout the scope of the program. // the only template parameter is the class type // the first argument of construction is the name // second is the constructor types // then the rest are function name and member function pointer pairs sol::userdata udata("vector", ctor, "is_unit", &vector::is_unit); // then you must register it lua.set_userdata(udata); // calling it is the same as new_userdata lua.script("v = vector.new()\n" "v = vector.new(12)\n" "v = vector.new(10, 10)\n" "assert(not v:is_unit())\n"); }