2019-05-22 07:17:31 +08:00
|
|
|
#define SOL_ALL_SAFETIES_ON 1
|
2018-09-28 13:27:38 +08:00
|
|
|
#include <sol/sol.hpp>
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
struct Doge {
|
|
|
|
int tailwag = 50;
|
|
|
|
|
|
|
|
Doge() {
|
|
|
|
}
|
|
|
|
|
2021-03-06 14:03:23 +08:00
|
|
|
Doge(int wags) : tailwag(wags) {
|
2017-11-10 06:41:46 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
~Doge() {
|
2021-03-06 23:14:48 +08:00
|
|
|
std::cout << "Dog at " << this
|
|
|
|
<< " is being destroyed..." << std::endl;
|
2017-11-10 06:41:46 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-03-06 14:03:23 +08:00
|
|
|
int main(int, char*[]) {
|
2018-03-16 05:16:28 +08:00
|
|
|
std::cout << "=== userdata ===" << std::endl;
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
sol::state lua;
|
|
|
|
|
2021-03-06 14:03:23 +08:00
|
|
|
Doge dog { 30 };
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
// fresh one put into Lua
|
2021-03-06 14:03:23 +08:00
|
|
|
lua["dog"] = Doge {};
|
2021-03-06 23:14:48 +08:00
|
|
|
// Copy into lua: destroyed by Lua VM during garbage
|
|
|
|
// collection
|
2017-11-10 06:41:46 +08:00
|
|
|
lua["dog_copy"] = dog;
|
2021-03-06 23:14:48 +08:00
|
|
|
// OR: move semantics - will call move constructor if
|
|
|
|
// present instead Again, owned by Lua
|
2017-11-10 06:41:46 +08:00
|
|
|
lua["dog_move"] = std::move(dog);
|
|
|
|
lua["dog_unique_ptr"] = std::make_unique<Doge>(25);
|
|
|
|
lua["dog_shared_ptr"] = std::make_shared<Doge>(31);
|
|
|
|
|
|
|
|
// Identical to above
|
2021-03-06 14:03:23 +08:00
|
|
|
Doge dog2 { 30 };
|
|
|
|
lua.set("dog2", Doge {});
|
2017-11-10 06:41:46 +08:00
|
|
|
lua.set("dog2_copy", dog2);
|
|
|
|
lua.set("dog2_move", std::move(dog2));
|
2021-03-06 23:14:48 +08:00
|
|
|
lua.set("dog2_unique_ptr",
|
|
|
|
std::unique_ptr<Doge>(new Doge(25)));
|
|
|
|
lua.set("dog2_shared_ptr",
|
|
|
|
std::shared_ptr<Doge>(new Doge(31)));
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
// Note all of them can be retrieved the same way:
|
|
|
|
Doge& lua_dog = lua["dog"];
|
|
|
|
Doge& lua_dog_copy = lua["dog_copy"];
|
|
|
|
Doge& lua_dog_move = lua["dog_move"];
|
|
|
|
Doge& lua_dog_unique_ptr = lua["dog_unique_ptr"];
|
|
|
|
Doge& lua_dog_shared_ptr = lua["dog_shared_ptr"];
|
2021-03-06 14:03:23 +08:00
|
|
|
sol_c_assert(lua_dog.tailwag == 50);
|
|
|
|
sol_c_assert(lua_dog_copy.tailwag == 30);
|
|
|
|
sol_c_assert(lua_dog_move.tailwag == 30);
|
|
|
|
sol_c_assert(lua_dog_unique_ptr.tailwag == 25);
|
|
|
|
sol_c_assert(lua_dog_shared_ptr.tailwag == 31);
|
2017-11-10 06:41:46 +08:00
|
|
|
|
2021-03-06 23:14:48 +08:00
|
|
|
// lua will treat these types as opaque, and you will be
|
|
|
|
// able to pass them around to C++ functions and Lua
|
|
|
|
// functions alike
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
// Use a C++ reference to handle memory directly
|
|
|
|
// otherwise take by value, without '&'
|
2021-03-06 23:14:48 +08:00
|
|
|
lua["f"] = [](Doge& dog) {
|
|
|
|
std::cout << "dog wags its tail " << dog.tailwag
|
|
|
|
<< " times!" << std::endl;
|
|
|
|
};
|
2017-11-10 06:41:46 +08:00
|
|
|
|
|
|
|
// if you bind a function using a pointer,
|
|
|
|
// you can handle when `nil` is passed
|
|
|
|
lua["handling_f"] = [](Doge* dog) {
|
|
|
|
if (dog == nullptr) {
|
|
|
|
std::cout << "dog was nil!" << std::endl;
|
|
|
|
return;
|
|
|
|
}
|
2021-03-06 23:14:48 +08:00
|
|
|
std::cout << "dog wags its tail " << dog->tailwag
|
|
|
|
<< " times!" << std::endl;
|
2017-11-10 06:41:46 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
lua.script(R"(
|
|
|
|
f(dog)
|
|
|
|
f(dog_copy)
|
|
|
|
f(dog_move)
|
|
|
|
f(dog_unique_ptr)
|
|
|
|
f(dog_shared_ptr)
|
|
|
|
|
|
|
|
-- C++ arguments that are pointers can handle nil
|
|
|
|
handling_f(dog)
|
|
|
|
handling_f(dog_copy)
|
|
|
|
handling_f(dog_move)
|
|
|
|
handling_f(dog_unique_ptr)
|
|
|
|
handling_f(dog_shared_ptr)
|
|
|
|
handling_f(nil)
|
|
|
|
|
|
|
|
-- never do this
|
|
|
|
-- f(nil)
|
|
|
|
)");
|
|
|
|
|
|
|
|
std::cout << std::endl;
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|