Adds requires feature - Closes #90

Function name for getting the status was actually changed to status in all places... being consistent, yay
This commit is contained in:
ThePhD 2016-05-19 17:27:12 -04:00
parent 54551af736
commit 9f019ae536
9 changed files with 117 additions and 30 deletions

View File

@ -1,7 +1,7 @@
protected_function
==================
Lua function calls that trap errors and provide error handler
-------------------------------------------------------------
Lua function calls that trap errors and provide error handling
--------------------------------------------------------------
.. code-block:: cpp

View File

@ -176,8 +176,8 @@ stack_proxy
.. _note 1:
On Function Objects and proxies
----------------------------------
on function objects and proxies
-------------------------------
Consider the following:

View File

@ -92,7 +92,7 @@ Explanations for a few categories are below (rest are self-explanatory).
| | plain C | luawrapper | lua-intf | luabind | Selene | Sol2 | oolua | lua-api-pp | kaguya | SLB | SWIG | luacppinterface | luwra |
| | | | | | | | | | | | | | |
+===========================+=============+============+==========+=========+==========+===========+===========+================+==========+==========+===========+=================+========+
| optional | ~ | ✗ | | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
| optional | ~ | ✗ | | ✗ | ✗ | ✔ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| tables | ~ | ~ | ~ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✗ | ✗ | ~ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
@ -114,11 +114,11 @@ Explanations for a few categories are below (rest are self-explanatory).
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| protected function | ~ | ✗ | ~ | ~ | ~ | ✔ | ~ | ✔ | ~ | ~ | ~ | ~ | ~ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | ~ |
| multi-return | ~ | ✗ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ✔ | ~ | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| variadic/variant argument | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ~ | ~ | ~ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| inheritance | ~ | ✔ | ~ | ✔ | ✔ | ✔ | ~ | ~ | ✔ | ~ | ✔ | ~ | ✗ |
| inheritance | ~ | ✔ | | ✔ | ✔ | ✔ | ~ | ~ | ✔ | ~ | ✔ | ~ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| overloading | ~ | ✗ | ✗ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✔ | ✗ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
@ -126,17 +126,17 @@ Explanations for a few categories are below (rest are self-explanatory).
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| coroutines | ~ | ✗ | ~ | ✔ | ✔ | ✔ | ✗ | ✗ | ✔ | ✗ | ✗ | ✔ | ✗ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | ~ |
| no-rtti support | ✔ | ✗ | ✔ | ✗ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | |
| no-exception support | ✔ | ✗ | ✔ | ~ | ✗ | ✔ | ✔ | ✗ | ✔ | ✔ | ~ | ✔ | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| Lua 5.1 | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ~ |
| Lua 5.1 | ✔ | ✔ | ✔ | ✔ | ✗ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| Lua 5.2 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| Lua 5.3 | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| luajit | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | ~ |
| luajit | ✔ | ✔ | ✔ | ✔ | ~ | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | ✗ | |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
| distribution | compile | header | both | compile | header | header | compile | compile | header | compile | generated | compile | header |
+---------------------------+-------------+------------+----------+---------+----------+-----------+-----------+----------------+----------+----------+-----------+-----------------+--------+
@ -250,7 +250,7 @@ oolua -
luwra -
* How do you store stateful functors / lambas ? Cannot find a way to support
* How do you store stateful functors / lambas? So far, no support for such.
* Cannot pull functions without first leaving them on the stack: manual cleanup becomes a thing
* Doesn't understand ``std::function`` conversions and the like (but with some extra code can get it to work)
* Recently improved by a lot: can chain tables and such, even if performance is a bit sad for that use case

View File

@ -72,12 +72,12 @@ namespace sol {
public:
load_result() = default;
load_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, load_status err = load_status::ok) : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
load_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, load_status err = load_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
}
load_result(const load_result&) = default;
load_result& operator=(const load_result&) = default;
load_result(load_result&& o) : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
load_result(load_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
@ -87,7 +87,7 @@ namespace sol {
o.popcount = 0;
o.err = load_status::syntax;
}
load_result& operator=(load_result&& o) {
load_result& operator=(load_result&& o) noexcept {
L = o.L;
index = o.index;
returncount = o.returncount;
@ -104,12 +104,12 @@ namespace sol {
return *this;
}
load_status error() const {
load_status status() const noexcept {
return err;
}
bool valid() const {
return error() == load_status::ok;
bool valid() const noexcept {
return status() == load_status::ok;
}
template<typename T>
@ -127,8 +127,8 @@ namespace sol {
return call<>(std::forward<Args>(args)...);
}
lua_State* lua_state() const { return L; };
int stack_index() const { return index; };
lua_State* lua_state() const noexcept { return L; };
int stack_index() const noexcept { return index; };
~load_result() {
stack::remove(L, index, popcount);

View File

@ -73,12 +73,12 @@ private:
public:
protected_function_result() = default;
protected_function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_status err = call_status::ok): L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
protected_function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_status err = call_status::ok) noexcept : L(L), index(index), returncount(returncount), popcount(popcount), err(err) {
}
protected_function_result(const protected_function_result&) = default;
protected_function_result& operator=(const protected_function_result&) = default;
protected_function_result(protected_function_result&& o) : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
protected_function_result(protected_function_result&& o) noexcept : L(o.L), index(o.index), returncount(o.returncount), popcount(o.popcount), err(o.err) {
// Must be manual, otherwise destructor will screw us
// return count being 0 is enough to keep things clean
// but we will be thorough
@ -88,7 +88,7 @@ public:
o.popcount = 0;
o.err = call_status::runtime;
}
protected_function_result& operator=(protected_function_result&& o) {
protected_function_result& operator=(protected_function_result&& o) noexcept {
L = o.L;
index = o.index;
returncount = o.returncount;
@ -105,12 +105,12 @@ public:
return *this;
}
call_status error() const {
call_status status() const noexcept {
return err;
}
bool valid() const {
return error() == call_status::ok || error() == call_status::yielded;
bool valid() const noexcept {
return status() == call_status::ok || status() == call_status::yielded;
}
template<typename T>
@ -118,8 +118,8 @@ public:
return tagged_get(types<meta::unqualified_t<T>>());
}
lua_State* lua_state() const { return L; };
int stack_index() const { return index; };
lua_State* lua_state() const noexcept { return L; };
int stack_index() const noexcept { return index; };
~protected_function_result() {
stack::remove(L, index, popcount);

View File

@ -49,6 +49,24 @@ private:
lua_State* L;
table reg;
global_table global;
template <typename T>
void ensure_package(const std::string& key, T&& sr) {
auto pkg = (*this)["package"];
if (!pkg.valid()) {
pkg = create_table_with("loaded", create_table_with(key, sr));
}
else {
auto ld = pkg["loaded"];
if (!ld.valid()) {
ld = create_table_with(key, sr);
}
else {
ld[key] = sr;
}
}
}
public:
typedef global_table::iterator iterator;
typedef global_table::const_iterator const_iterator;
@ -132,11 +150,13 @@ public:
case lib::ffi:
#ifdef SOL_LUAJIT
luaL_requiref(L, "ffi", luaopen_ffi, 1);
lua_pop(L, 1);
#endif
break;
case lib::jit:
#ifdef SOL_LUAJIT
luaL_requiref(L, "jit", luaopen_jit, 1);
lua_pop(L, 1);
#endif
break;
case lib::count:
@ -146,6 +166,44 @@ public:
}
}
template <typename Fx>
object require(const std::string& key, Fx&& open_function, bool is_global_library = true) {
auto openfx = [fx = std::forward<Fx>(open_function)](lua_State* L){
typedef lua_bind_traits<meta::unqualified_t<Fx>> traits;
return stack::call(typename traits::return_type(), typename traits::args_type(), L, fx);
};
stack::push(L, function_args<function_sig<>>(std::forward<Fx>(openfx)));
lua_CFunction openf = stack::pop<lua_CFunction>(L);
luaL_requiref(L, key.c_str(), openf, is_global_library ? 1 : 0);
object r stack::pop<object>(L);
lua_pop(L, 1);
return r;
}
object require_script(const std::string& key, const std::string& code) {
optional<object> loaded = traverse_get<optional<object>>("package", "loaded", key);
bool ismod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
if (ismod)
return std::move(*loaded);
script(code);
auto sr = stack::get<stack_reference>(L);
set(key, sr);
ensure_package(key, sr);
return stack::pop<object>(L);
}
object require_file(const std::string& key, const std::string& file) {
auto loaded = traverse_get<optional<object>>("package", "loaded", key);
bool ismod = loaded && !(loaded->is<bool>() && !loaded->as<bool>());
if (loaded)
return std::move(*loaded);
script_file(file);
auto sr = stack::get<stack_reference>(L);
set(key, sr);
ensure_package(key, sr);
return stack::pop<object>(L);
}
void script(const std::string& code) {
if(luaL_dostring(L, code.c_str())) {
lua_error(L);

View File

@ -156,8 +156,15 @@ public:
typedef iterator const_iterator;
basic_table_core( ) noexcept : base_t( ) { }
template <typename T, meta::enable<meta::boolean<!top_level>, meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, std::is_same<meta::unqualified_t<T>, global_table>> = meta::enabler>
basic_table_core( T&& r ) noexcept : base_t( std::forward<T>(r) ) { }
template <typename T, meta::enable<meta::neg<std::is_same<meta::unqualified_t<T>, basic_table_core>>, std::is_base_of<base_t, meta::unqualified_t<T>>> = meta::enabler>
basic_table_core( T&& r ) noexcept : base_t( std::forward<T>(r) ) {
#ifdef SOL_CHECK_ARGUMENTS
if (!is_table<meta::unqualified_t<T>>::value) {
auto pp = stack::push_pop(*this);
stack::check<basic_table_core>(base_t::lua_state(), -1, type_panic);
}
#endif // Safety
}
basic_table_core(const basic_table_core&) = default;
basic_table_core(basic_table_core&&) = default;
basic_table_core& operator=(const basic_table_core&) = default;

View File

@ -547,6 +547,12 @@ public:
static const std::size_t arity = base_t::arity - meta::count_for<is_transparent_argument, typename base_t::args_type>::value;
};
template <typename T>
struct is_table : std::false_type {};
template <bool x, typename T>
struct is_table<basic_table_core<x, T>> : std::true_type {};
template<typename T>
inline type type_of() {
return lua_type_of<meta::unqualified_t<T>>::value;

View File

@ -69,3 +69,19 @@ TEST_CASE("stack/strings", "test that strings can be roundtripped") {
REQUIRE(wide_to_char32 == utf32str[0]);
}
#endif // Shit C++
TEST_CASE("state/strings", "opening strings as 'requires' clauses") {
std::string code = "return { modfunc = function () return 221 end }";
sol::state lua;
sol::table thingy1 = lua.require_script("thingy", code);
sol::table thingy2 = lua.require_script("thingy", code);
int val1 = thingy1["modfunc"]();
int val2 = thingy2["modfunc"]();
REQUIRE(val1 == 221);
REQUIRE(val2 == 221);
// must have loaded the same table
REQUIRE(thingy1 == thingy2);
}