mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
add new examples
This commit is contained in:
parent
c124d51353
commit
0db6d99d4b
51
examples/self_from_lua.cpp
Normal file
51
examples/self_from_lua.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
struct thing {
|
||||||
|
|
||||||
|
thing(sol::this_state ts) {
|
||||||
|
lua_State* L = ts;
|
||||||
|
// references the object that called this function
|
||||||
|
// in constructors:
|
||||||
|
sol::stack_object selfobj(L, -1);
|
||||||
|
// the -1 (NEGATIVE one) above
|
||||||
|
// means "off the top fo the stack"
|
||||||
|
// (-1 is the top, -2 is one below, etc...)
|
||||||
|
|
||||||
|
// definitely the same
|
||||||
|
thing& self = selfobj.as<thing>();
|
||||||
|
assert(&self == this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void func(sol::this_state ts) const {
|
||||||
|
lua_State* L = ts;
|
||||||
|
// references the object that called this function
|
||||||
|
// in regular member functions:
|
||||||
|
sol::stack_object selfobj(L, 1);
|
||||||
|
// "1" is the bottom of the Lua stack
|
||||||
|
// 2 is one up, so on and so forth...
|
||||||
|
thing& self = selfobj.as<thing>();
|
||||||
|
|
||||||
|
// definitely the same
|
||||||
|
assert(&self == this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries(sol::lib::base);
|
||||||
|
|
||||||
|
lua.new_usertype<thing>("thing",
|
||||||
|
sol::constructors<thing(sol::this_state)>(),
|
||||||
|
"func", &thing::func
|
||||||
|
);
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
obj = thing.new()
|
||||||
|
obj:func()
|
||||||
|
)");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
165
examples/usertype_dynamic_getter_setter.cpp
Normal file
165
examples/usertype_dynamic_getter_setter.cpp
Normal file
|
@ -0,0 +1,165 @@
|
||||||
|
#define SOL_CHECK_ARGUMENTS
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
// Note that this is a bunch of if/switch statements
|
||||||
|
// for the sake of brevity and clarity
|
||||||
|
// A much more robust implementation could use a std::unordered_map
|
||||||
|
// to link between keys and desired actions for those keys on
|
||||||
|
// setting/getting
|
||||||
|
// The sky becomes the limit when you have this much control,
|
||||||
|
// so apply it wisely!
|
||||||
|
|
||||||
|
struct vec {
|
||||||
|
double x;
|
||||||
|
double y;
|
||||||
|
|
||||||
|
vec() : x(0), y(0) {}
|
||||||
|
vec(double x) : vec(x, x) {}
|
||||||
|
vec(double x, double y) : x(x), y(y) {}
|
||||||
|
|
||||||
|
sol::object getter(sol::stack_object key, sol::this_state L) {
|
||||||
|
// we use stack_object for the arguments because we know
|
||||||
|
// the values from Lua will remain on Lua's stack,
|
||||||
|
// so long we we don't mess with it
|
||||||
|
auto maybe_string_key = key.as<sol::optional<std::string>>();
|
||||||
|
if (maybe_string_key) {
|
||||||
|
const std::string& k = *maybe_string_key;
|
||||||
|
if (k == "x") {
|
||||||
|
// Return x
|
||||||
|
return sol::object(L, sol::in_place, this->x);
|
||||||
|
}
|
||||||
|
else if (k == "y") {
|
||||||
|
// Return y
|
||||||
|
return sol::object(L, sol::in_place, this->y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String keys failed, check for numbers
|
||||||
|
auto maybe_numeric_key = key.as<sol::optional<int>>();
|
||||||
|
if (maybe_numeric_key) {
|
||||||
|
int n = *maybe_numeric_key;
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
return sol::object(L, sol::in_place, this->x);
|
||||||
|
case 1:
|
||||||
|
return sol::object(L, sol::in_place, this->y);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// No valid key: push nil
|
||||||
|
// Note that the example above is a bit unnecessary:
|
||||||
|
// binding the variables x and y to the usertype
|
||||||
|
// would work just as well and we would not
|
||||||
|
// need to look it up here,
|
||||||
|
// but this is to show it works regardless
|
||||||
|
return sol::object(L, sol::in_place, sol::lua_nil);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setter(sol::stack_object key, sol::stack_object value, sol::this_state L) {
|
||||||
|
// we use stack_object for the arguments because we know
|
||||||
|
// the values from Lua will remain on Lua's stack,
|
||||||
|
// so long we we don't mess with it
|
||||||
|
auto maybe_string_key = key.as<sol::optional<std::string>>();
|
||||||
|
if (maybe_string_key) {
|
||||||
|
const std::string& k = *maybe_string_key;
|
||||||
|
if (k == "x") {
|
||||||
|
// set x
|
||||||
|
this->x = value.as<double>();
|
||||||
|
}
|
||||||
|
else if (k == "y") {
|
||||||
|
// set y
|
||||||
|
this->y = value.as<double>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// String keys failed, check for numbers
|
||||||
|
auto maybe_numeric_key = key.as<sol::optional<int>>();
|
||||||
|
if (maybe_numeric_key) {
|
||||||
|
int n = *maybe_numeric_key;
|
||||||
|
switch (n) {
|
||||||
|
case 0:
|
||||||
|
this->x = value.as<double>();
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
this->y = value.as<double>();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
std::cout << "=== usertype dynamic getter/setter example ===" << std::endl;
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
lua.open_libraries();
|
||||||
|
|
||||||
|
lua.new_usertype<vec>("vec",
|
||||||
|
sol::constructors<vec(), vec(double), vec(double, double)>(),
|
||||||
|
// index and newindex control what happens when a "key"
|
||||||
|
// is looked up that is not baked into the class itself
|
||||||
|
// it is called with the object and the key for index (get)s
|
||||||
|
// or it is called with the object, the key, and the index (set)
|
||||||
|
// we can use a member function to assume the "object" is of the `vec`
|
||||||
|
// type, and then just have a function that takes
|
||||||
|
// the key (get) or the key + the value (set)
|
||||||
|
sol::meta_function::index, &vec::getter,
|
||||||
|
sol::meta_function::new_index, &vec::setter
|
||||||
|
);
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
v1 = vec.new(1, 0)
|
||||||
|
v2 = vec.new(0, 1)
|
||||||
|
|
||||||
|
-- observe usage of getter/setter
|
||||||
|
print("v1:", v1.x, v1.y)
|
||||||
|
print("v2:", v2.x, v2.y)
|
||||||
|
-- gets 0, 1 by doing lookup into getter function
|
||||||
|
print("changing v2...")
|
||||||
|
v2.x = 3
|
||||||
|
v2[1] = 5
|
||||||
|
-- can use [0] [1] like popular
|
||||||
|
-- C++-style math vector classes
|
||||||
|
print("v1:", v1.x, v1.y)
|
||||||
|
print("v2:", v2.x, v2.y)
|
||||||
|
-- both obj.name and obj["name"]
|
||||||
|
-- are equivalent lookup methods
|
||||||
|
-- and both will trigger the getter
|
||||||
|
-- if it can't find 'name' on the object
|
||||||
|
assert(v1["x"] == v1.x)
|
||||||
|
assert(v1[0] == v1.x)
|
||||||
|
assert(v1["x"] == v1[0])
|
||||||
|
|
||||||
|
assert(v1["y"] == v1.y)
|
||||||
|
assert(v1[1] == v1.y)
|
||||||
|
assert(v1["y"] == v1[1])
|
||||||
|
)");
|
||||||
|
|
||||||
|
|
||||||
|
// Can also be manipulated from C++,
|
||||||
|
// and will call getter/setter methods:
|
||||||
|
sol::userdata v1 = lua["v1"];
|
||||||
|
double v1x = v1["x"];
|
||||||
|
double v1y = v1["y"];
|
||||||
|
assert(v1x == 1.000);
|
||||||
|
assert(v1y == 0.000);
|
||||||
|
v1[0] = 2.000;
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
assert(v1.x == 2.000)
|
||||||
|
assert(v1["x"] == 2.000)
|
||||||
|
assert(v1[0] == 2.000)
|
||||||
|
)");
|
||||||
|
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,7 +1,6 @@
|
||||||
#define SOL_CHECK_ARGUMENTS
|
#define SOL_CHECK_ARGUMENTS
|
||||||
#include <sol.hpp>
|
#include <sol.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -67,5 +66,5 @@ int main() {
|
||||||
assert(a1 == a2)
|
assert(a1 == a2)
|
||||||
)");
|
)");
|
||||||
|
|
||||||
std::cout << std::endl;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user