#define SOL_ALL_SAFETIES_ON 1 #include #include struct ship { int bullets = 20; int life = 100; bool shoot() { if (bullets > 0) { --bullets; // successfully shot return true; } // cannot shoot return false; } bool hurt(int by) { life -= by; // have we died? return life < 1; } }; int main() { std::cout << "=== usertype basics ===" << std::endl; static const bool way_1 = true; sol::state lua; lua.open_libraries(sol::lib::base); if (way_1) { lua.new_usertype( "ship", // the name of the class, as you want it // to be used in lua List the member // functions you wish to bind: // "name_of_item", // &class_name::function_or_variable "shoot", &ship::shoot, "hurt", &ship::hurt, // bind variable types, too "life", &ship::life, // names in lua don't have to be the same as C++, // but it probably helps if they're kept the same, // here we change it just to show its possible "bullet_count", &ship::bullets); } else { // set usertype explicitly, with the given name sol::usertype usertype_table = lua.new_usertype("ship"); usertype_table["shoot"] = &ship::shoot; usertype_table["hurt"] = &ship::hurt; usertype_table["life"] = &ship::life; usertype_table["bullet_count"] = &ship::bullets; } const auto& code = R"( fwoosh = ship.new() -- note the ":" that is there: this is mandatory for member function calls -- ":" means "pass self" in Lua local success = fwoosh:shoot() local is_dead = fwoosh:hurt(20) -- check if it works print(is_dead) -- the ship is not dead at this point print(fwoosh.life .. "life left") -- 80 life left print(fwoosh.bullet_count) -- 19 )"; lua.script(code); std::cout << std::endl; return 0; }