mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
Merge branch 'master' of github.com:Rapptz/sol
Conflicts: tests.cpp
This commit is contained in:
commit
a6120631d8
36
README.md
36
README.md
|
@ -15,40 +15,9 @@ It should be noted that the library itself depends on `lua.hpp` to be found by y
|
||||||
|
|
||||||
If you want to contribute, please check CONTRIBUTING.md for details. Thank you!
|
If you want to contribute, please check CONTRIBUTING.md for details. Thank you!
|
||||||
|
|
||||||
## Example
|
## Examples
|
||||||
|
|
||||||
Here's an example on how to load a basic configuration struct with a Lua script.
|
Examples are provided in the examples directory.
|
||||||
|
|
||||||
```cpp
|
|
||||||
#include <sol.hpp>
|
|
||||||
#include <iostream>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
struct test {
|
|
||||||
int foo;
|
|
||||||
std::string bar;
|
|
||||||
double baz;
|
|
||||||
};
|
|
||||||
|
|
||||||
test load(const sol::table& t) {
|
|
||||||
return { t.get<int>("foo"), t.get<std::string>("bar"), t.get<double>("baz") };
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
try {
|
|
||||||
sol::state lua;
|
|
||||||
lua.script("foo = 1234;\n"
|
|
||||||
"bar = \"hello world\";\n"
|
|
||||||
"baz = 1.4;");
|
|
||||||
|
|
||||||
test c = load(lua.global_table());
|
|
||||||
std::cout << '(' << c.foo << ", " << c.bar << ", " << c.baz << ")\n";
|
|
||||||
}
|
|
||||||
catch(const std::exception& e) {
|
|
||||||
std::cerr << e.what() << '\n';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
|
@ -61,6 +30,5 @@ Sol makes use of C++11 features. GCC 4.7 and Clang 3.3 or higher should be able
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
- Support for `operator[]` based retrieval and modifying of tables (mostly finished).
|
|
||||||
- Possibly document functions and classes via doxygen.
|
- Possibly document functions and classes via doxygen.
|
||||||
- Provide more examples to showcase uses.
|
- Provide more examples to showcase uses.
|
||||||
|
|
27
examples/config.cpp
Normal file
27
examples/config.cpp
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
// shows how to load basic data to a struct
|
||||||
|
|
||||||
|
#include <sol.hpp>
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
struct config {
|
||||||
|
std::string name;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
|
||||||
|
void print() {
|
||||||
|
std::cout << "Name: " << name << '\n'
|
||||||
|
<< "Width: " << width << '\n'
|
||||||
|
<< "Height: " << height << '\n';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
sol::state lua;
|
||||||
|
config screen;
|
||||||
|
lua.open_file("config.lua");
|
||||||
|
screen.name = lua.get<std::string>("name");
|
||||||
|
screen.width = lua.get<int>("width");
|
||||||
|
screen.height = lua.get<int>("height");
|
||||||
|
screen.print();
|
||||||
|
}
|
3
examples/config.lua
Normal file
3
examples/config.lua
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
name = "Asus"
|
||||||
|
width = 1920
|
||||||
|
height = 1080
|
|
@ -150,11 +150,6 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
auto operator[](T&& key) -> decltype(global[std::forward<T>(key)]) {
|
|
||||||
return global[std::forward<T>(key)];
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
table create_table(T&& key, int narr = 0, int nrec = 0) {
|
table create_table(T&& key, int narr = 0, int nrec = 0) {
|
||||||
lua_createtable(L.get(), narr, nrec);
|
lua_createtable(L.get(), narr, nrec);
|
||||||
|
|
|
@ -42,8 +42,6 @@ T* get_ptr(T* val) {
|
||||||
|
|
||||||
class table : public reference {
|
class table : public reference {
|
||||||
friend class state;
|
friend class state;
|
||||||
template<typename Table, typename T> struct proxy;
|
|
||||||
|
|
||||||
template<typename T, typename U>
|
template<typename T, typename U>
|
||||||
T single_get(U&& key) const {
|
T single_get(U&& key) const {
|
||||||
push();
|
push();
|
||||||
|
@ -115,50 +113,11 @@ public:
|
||||||
std::forward<T>(key), std::forward<TFx>(fx), std::forward<TObj>(obj));
|
std::forward<T>(key), std::forward<TFx>(fx), std::forward<TObj>(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
proxy<table&, T> operator[](T&& key) {
|
|
||||||
return proxy<table&, T>(*this, std::forward<T>(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
proxy<const table&, T> operator[](T&& key) const {
|
|
||||||
return proxy<const table&, T>(*this, std::forward<T>(key));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t size() const {
|
size_t size() const {
|
||||||
push();
|
push();
|
||||||
return lua_rawlen(state(), -1);
|
return lua_rawlen(state(), -1);
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
template<typename Table, typename T>
|
|
||||||
struct proxy {
|
|
||||||
private:
|
|
||||||
Table t;
|
|
||||||
T& key;
|
|
||||||
public:
|
|
||||||
proxy(Table t, T& key) : t(t), key(key) {}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
EnableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
|
||||||
t.set_function(key, std::forward<U>(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
DisableIf<Function<Unqualified<U>>> operator=(U&& other) {
|
|
||||||
t.set(key, std::forward<U>(other));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename U>
|
|
||||||
operator U() const {
|
|
||||||
return t.get<U>(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename... Ret, typename... Args>
|
|
||||||
typename multi_return<Ret...>::type call(Args&&... args) {
|
|
||||||
return t.get<function>(key)(types<Ret...>(), std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename T, typename TFx>
|
template<typename T, typename TFx>
|
||||||
table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) {
|
table& set_isfunction_fx(std::true_type, T&& key, TFx&& fx) {
|
||||||
return set_fx(std::false_type(), std::forward<T>(key), std::forward<TFx>(fx));
|
return set_fx(std::false_type(), std::forward<T>(key), std::forward<TFx>(fx));
|
||||||
|
|
|
@ -38,31 +38,6 @@ using Unqualified = typename std::remove_reference<typename std::remove_cv<T>::t
|
||||||
template<typename T>
|
template<typename T>
|
||||||
using Decay = typename std::decay<T>::type;
|
using Decay = typename std::decay<T>::type;
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
// code borrowed from Gears
|
|
||||||
// https://github.com/Rapptz/Gears/
|
|
||||||
template<typename T, bool isclass = std::is_class<Unqualified<T>>::value>
|
|
||||||
struct is_function_impl : std::is_function<typename std::remove_pointer<T>::type> {};
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct is_function_impl<T, true> {
|
|
||||||
using yes = char;
|
|
||||||
using no = struct { char s[2]; };
|
|
||||||
|
|
||||||
struct F { void operator()(); };
|
|
||||||
struct Derived : T, F { };
|
|
||||||
template<typename U, U> struct Check;
|
|
||||||
|
|
||||||
template<typename V>
|
|
||||||
static no test(Check<void (F::*)(), &V::operator()>*);
|
|
||||||
|
|
||||||
template<typename>
|
|
||||||
static yes test(...);
|
|
||||||
|
|
||||||
static const bool value = sizeof(test<Derived>(0)) == sizeof(yes);
|
|
||||||
};
|
|
||||||
} // detail
|
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct multi_return {
|
struct multi_return {
|
||||||
typedef std::tuple<Args...> type;
|
typedef std::tuple<Args...> type;
|
||||||
|
@ -81,9 +56,6 @@ struct multi_return<> : types<>{
|
||||||
template<bool B>
|
template<bool B>
|
||||||
using Bool = std::integral_constant<bool, B>;
|
using Bool = std::integral_constant<bool, B>;
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
struct Function : Bool<detail::is_function_impl<T>::value> {};
|
|
||||||
|
|
||||||
template<typename TFuncSignature>
|
template<typename TFuncSignature>
|
||||||
struct function_traits;
|
struct function_traits;
|
||||||
|
|
||||||
|
|
73
tests.cpp
73
tests.cpp
|
@ -117,33 +117,33 @@ TEST_CASE("advanced/callLambdaReturns", "Checks for lambdas returning values") {
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; }));
|
REQUIRE_NOTHROW(lua.set_function("a", [ ] { return 42; }));
|
||||||
REQUIRE(lua["a"].call<int>() == 42);
|
REQUIRE(lua.get<sol::function>("a").call<int>() == 42);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; }));
|
REQUIRE_NOTHROW(lua.set_function("b", [ ] { return 42u; }));
|
||||||
REQUIRE(lua["b"].call<unsigned int>() == 42u);
|
REQUIRE(lua.get<sol::function>("b").call<unsigned int>() == 42u);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; }));
|
REQUIRE_NOTHROW(lua.set_function("c", [ ] { return 3.14; }));
|
||||||
REQUIRE(lua["c"].call<double>() == 3.14);
|
REQUIRE(lua.get<sol::function>("c").call<double>() == 3.14);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; }));
|
REQUIRE_NOTHROW(lua.set_function("d", [ ] { return 6.28f; }));
|
||||||
REQUIRE(lua["d"].call<float>() == 6.28f);
|
REQUIRE(lua.get<sol::function>("d").call<float>() == 6.28f);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; }));
|
REQUIRE_NOTHROW(lua.set_function("e", [ ] { return "lol"; }));
|
||||||
REQUIRE(lua["e"].call<std::string>() == lol);
|
REQUIRE(lua.get<sol::function>("e").call<std::string>() == lol);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; }));
|
REQUIRE_NOTHROW(lua.set_function("f", [ ] { return true; }));
|
||||||
REQUIRE(lua["f"].call<bool>());
|
REQUIRE(lua.get<sol::function>("f").call<bool>());
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); }));
|
REQUIRE_NOTHROW(lua.set_function("g", [ ] { return std::string("str"); }));
|
||||||
REQUIRE(lua["g"].call<std::string>() == str);
|
REQUIRE(lua.get<sol::function>("g").call<std::string>() == str);
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("h", [ ] { }));
|
REQUIRE_NOTHROW(lua.set_function("h", [ ] { }));
|
||||||
REQUIRE_NOTHROW(lua["h"].call());
|
REQUIRE_NOTHROW(lua.get<sol::function>("h").call());
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; }));
|
REQUIRE_NOTHROW(lua.set_function("i", [ ] { return sol::nil; }));
|
||||||
REQUIRE(lua["i"].call<sol::nil_t>() == sol::nil);
|
REQUIRE(lua.get<sol::function>("i").call<sol::nil_t>() == sol::nil);
|
||||||
REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
|
REQUIRE_NOTHROW(lua.set_function("j", [ ] { return std::make_tuple(1, 6.28f, 3.14, std::string("heh")); }));
|
||||||
REQUIRE((lua["j"].call<int, float, double, std::string>() == heh_tuple));
|
REQUIRE((lua.get<sol::function>("j").call<int, float, double, std::string>() == heh_tuple));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {
|
TEST_CASE("advanced/callLambda2", "A C++ lambda is exposed to lua and called") {
|
||||||
|
@ -237,56 +237,3 @@ TEST_CASE("functions/return_order_and_multi_get", "Check if return order is in t
|
||||||
REQUIRE(tlua == triple);
|
REQUIRE(tlua == triple);
|
||||||
REQUIRE(tluaget == triple);
|
REQUIRE(tluaget == triple);
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_CASE("tables/operator[]", "Check if operator[] retrieval and setting works properly") {
|
|
||||||
sol::state lua;
|
|
||||||
lua.open_libraries(sol::lib::base);
|
|
||||||
|
|
||||||
lua.script("foo = 20\nbar = \"hello world\"");
|
|
||||||
// basic retrieval
|
|
||||||
std::string bar = lua["bar"];
|
|
||||||
REQUIRE(bar == "hello world");
|
|
||||||
// Ambiguity case on operator= for compilation testing
|
|
||||||
// Have to use cast, there's no other way...
|
|
||||||
bar = (std::string)lua["bar"];
|
|
||||||
REQUIRE(bar == "hello world");
|
|
||||||
int foo = lua["foo"];
|
|
||||||
REQUIRE(bar == "hello world");
|
|
||||||
REQUIRE(foo == 20);
|
|
||||||
|
|
||||||
// basic setting
|
|
||||||
lua["bar"] = 20.4;
|
|
||||||
lua["foo"] = "goodbye";
|
|
||||||
|
|
||||||
// doesn't modify the actual values obviously.
|
|
||||||
REQUIRE(bar == "hello world");
|
|
||||||
REQUIRE(foo == 20);
|
|
||||||
|
|
||||||
// function setting
|
|
||||||
lua["test"] = plop_xyz;
|
|
||||||
REQUIRE_NOTHROW(lua.script("assert(test(10, 11, \"hello\") == 11)"));
|
|
||||||
|
|
||||||
// function retrieval
|
|
||||||
sol::function test = lua["test"];
|
|
||||||
REQUIRE(test.call<int>(10, 11, "hello") == 11);
|
|
||||||
|
|
||||||
// setting a lambda
|
|
||||||
lua["lamb"] = [](int x) {
|
|
||||||
return x * 2;
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE_NOTHROW(lua.script("assert(lamb(220) == 440)"));
|
|
||||||
|
|
||||||
// function retrieval of a lambda
|
|
||||||
sol::function lamb = lua["lamb"];
|
|
||||||
REQUIRE(lamb.call<int>(220) == 440);
|
|
||||||
|
|
||||||
// test const table retrieval
|
|
||||||
auto assert1 = [](const sol::table& t) {
|
|
||||||
std::string a = t["foo"];
|
|
||||||
int b = t["bar"];
|
|
||||||
std::cout << a << ',' << b << '\n';
|
|
||||||
};
|
|
||||||
|
|
||||||
REQUIRE_NOTHROW(assert1(lua.global_table()));
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user