mirror of
https://github.com/ThePhD/sol2.git
synced 2024-03-22 13:10:44 +08:00
shiny new load_result
type, and thusly we're ready for 2.5
.
This commit is contained in:
parent
2497567897
commit
a2eced863f
|
@ -60,11 +60,12 @@ These functions run the desired blob of either code that is in a string, or code
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
:caption: function: load / load_file
|
:caption: function: load / load_file
|
||||||
|
:name: state-load-code
|
||||||
|
|
||||||
sol::stack_proxy load(const std::string& code);
|
sol::load_result load(const std::string& code);
|
||||||
sol::stack_proxy load_file(const std::string& filename);
|
sol::load_result load_file(const std::string& filename);
|
||||||
|
|
||||||
These functions *load* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It will not run: it returns a proxy that can be called, turned into a `sol::function`,. or similar, will run the loaded code.
|
These functions *load* the desired blob of either code that is in a string, or code that comes from a filename, on the ``lua_State*``. It will not run: it returns a ``load_result`` proxy that can be called, turned into a `sol::function`,. or similar, will run the loaded code.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
:caption: function: global table / registry table
|
:caption: function: global table / registry table
|
||||||
|
|
|
@ -40,17 +40,31 @@ This strongly-typed enumeration contains the errors potentially generated by a c
|
||||||
:name: thread-status
|
:name: thread-status
|
||||||
|
|
||||||
enum class thread_status : int {
|
enum class thread_status : int {
|
||||||
normal = LUA_OK,
|
ok = LUA_OK,
|
||||||
yielded = LUA_YIELD,
|
yielded = LUA_YIELD,
|
||||||
error_runtime = LUA_ERRRUN,
|
runtime = LUA_ERRRUN,
|
||||||
error_memory = LUA_ERRMEM,
|
memory = LUA_ERRMEM,
|
||||||
error_gc = LUA_ERRGCMM,
|
gc = LUA_ERRGCMM,
|
||||||
error_handler = LUA_ERRERR,
|
handler = LUA_ERRERR,
|
||||||
dead,
|
dead,
|
||||||
};
|
};
|
||||||
|
|
||||||
This enumeration contains the status of a thread. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.
|
This enumeration contains the status of a thread. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
:caption: status of a Lua load operation
|
||||||
|
:name: load-status
|
||||||
|
|
||||||
|
enum class load_status : int {
|
||||||
|
ok = LUA_OK,
|
||||||
|
runtime = LUA_ERRSYNTAX,
|
||||||
|
memory = LUA_ERRMEM,
|
||||||
|
gc = LUA_ERRGCMM,
|
||||||
|
file = LUA_ERRFILE,
|
||||||
|
};
|
||||||
|
|
||||||
|
This enumeration contains the status of a load operation from :ref:`state::load(_file)<state-load-code>`. The ``thread_status::dead`` state is generated when the thread has nothing on its stack and it is not running anything.
|
||||||
|
|
||||||
.. code-block:: cpp
|
.. code-block:: cpp
|
||||||
:caption: type enumeration
|
:caption: type enumeration
|
||||||
:name: type-enum
|
:name: type-enum
|
||||||
|
|
|
@ -34,6 +34,8 @@ For your system/game that already has lua, but you'd like something nice:
|
||||||
running lua code
|
running lua code
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
.. code-block:: cpp
|
||||||
|
|
||||||
sol::state lua;
|
sol::state lua;
|
||||||
// load and execute from string
|
// load and execute from string
|
||||||
lua.script("a = 'test'");
|
lua.script("a = 'test'");
|
||||||
|
@ -57,17 +59,26 @@ You can set/get everything.
|
||||||
|
|
||||||
sol::lua_state lua;
|
sol::lua_state lua;
|
||||||
|
|
||||||
lua.set("number", 24); // integer types
|
// integer types
|
||||||
lua["number2"] = 24.5; // floating point numbers
|
lua.set("number", 24);
|
||||||
lua["important_string"] = "woof woof"; // becomes string
|
// floating point numbers
|
||||||
lua["myuserdata"] = some_class(); // non-recognized types is stored as userdata
|
lua["number2"] = 24.5;
|
||||||
lua["a_function"] = [](){ return 100; }; // is callable, therefore gets stored as a function
|
// string types
|
||||||
|
lua["important_string"] = "woof woof";
|
||||||
|
// non-recognized types is stored as userdata
|
||||||
|
lua["myuserdata"] = some_class();
|
||||||
|
// is callable, therefore gets stored as a function
|
||||||
|
lua["a_function"] = [](){ return 100; };
|
||||||
|
|
||||||
int number = lua["number"]; // implicit conversion
|
// implicit conversion
|
||||||
auto number2 = lua.get<double>("number2"); // explicit get
|
int number = lua["number"];
|
||||||
std::string important_string = lua["important_string"]; // strings too
|
// explicit get
|
||||||
|
auto number2 = lua.get<double>("number2");
|
||||||
|
// strings too
|
||||||
|
std::string important_string = lua["important_string"];
|
||||||
|
|
||||||
some_class& myuserdata = lua["myuserdata"]; // returns a plain reference
|
// returns a plain reference
|
||||||
|
some_class& myuserdata = lua["myuserdata"];
|
||||||
// myuserdata.some_variable = 20 WILL (!!) modify
|
// myuserdata.some_variable = 20 WILL (!!) modify
|
||||||
// data inside of lua VM as well, if you get a pointer or a reference
|
// data inside of lua VM as well, if you get a pointer or a reference
|
||||||
|
|
||||||
|
|
139
sol/load_result.hpp
Normal file
139
sol/load_result.hpp
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
// The MIT License (MIT)
|
||||||
|
|
||||||
|
// Copyright (c) 2013-2016 Rapptz, ThePhD and contributors
|
||||||
|
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
// this software and associated documentation files (the "Software"), to deal in
|
||||||
|
// the Software without restriction, including without limitation the rights to
|
||||||
|
// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
// the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
// subject to the following conditions:
|
||||||
|
|
||||||
|
// The above copyright notice and this permission notice shall be included in all
|
||||||
|
// copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
#ifndef SOL_LOAD_RESULT_HPP
|
||||||
|
#define SOL_LOAD_RESULT_HPP
|
||||||
|
|
||||||
|
#include "stack.hpp"
|
||||||
|
#include "function.hpp"
|
||||||
|
#include "proxy_base.hpp"
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
|
namespace sol {
|
||||||
|
struct load_result : public proxy_base<load_result> {
|
||||||
|
private:
|
||||||
|
lua_State* L;
|
||||||
|
int index;
|
||||||
|
int returncount;
|
||||||
|
int popcount;
|
||||||
|
load_status err;
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
decltype(auto) tagged_get(types<sol::optional<T>>) const {
|
||||||
|
if (!valid()) {
|
||||||
|
return sol::optional<T>(nullopt);
|
||||||
|
}
|
||||||
|
return stack::get<sol::optional<T>>(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
decltype(auto) tagged_get(types<T>) const {
|
||||||
|
#ifdef SOL_CHECK_ARGUMENTS
|
||||||
|
if (!valid()) {
|
||||||
|
type_panic(L, index, type_of(L, index), type::none);
|
||||||
|
}
|
||||||
|
#endif // Check Argument Safety
|
||||||
|
return stack::get<T>(L, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::optional<sol::error> tagged_get(types<sol::optional<sol::error>>) const {
|
||||||
|
if (valid()) {
|
||||||
|
return nullopt;
|
||||||
|
}
|
||||||
|
return sol::error(detail::direct_error, stack::get<std::string>(L, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::error tagged_get(types<sol::error>) const {
|
||||||
|
#ifdef SOL_CHECK_ARGUMENTS
|
||||||
|
if (valid()) {
|
||||||
|
type_panic(L, index, type_of(L, index), type::none);
|
||||||
|
}
|
||||||
|
#endif // Check Argument Safety
|
||||||
|
return sol::error(detail::direct_error, stack::get<std::string>(L, index));
|
||||||
|
}
|
||||||
|
|
||||||
|
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(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) {
|
||||||
|
// Must be manual, otherwise destructor will screw us
|
||||||
|
// return count being 0 is enough to keep things clean
|
||||||
|
// but will be thorough
|
||||||
|
o.L = nullptr;
|
||||||
|
o.index = 0;
|
||||||
|
o.returncount = 0;
|
||||||
|
o.popcount = 0;
|
||||||
|
o.err = load_status::syntax;
|
||||||
|
}
|
||||||
|
load_result& operator=(load_result&& o) {
|
||||||
|
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 will be thorough
|
||||||
|
o.L = nullptr;
|
||||||
|
o.index = 0;
|
||||||
|
o.returncount = 0;
|
||||||
|
o.popcount = 0;
|
||||||
|
o.err = load_status::syntax;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
load_status error() const {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool valid() const {
|
||||||
|
return error() == load_status::ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
T get() const {
|
||||||
|
return tagged_get(types<meta::Unqualified<T>>());
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Ret, typename... Args>
|
||||||
|
decltype(auto) call(Args&&... args) {
|
||||||
|
return get<function>().template call<Ret...>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename... Args>
|
||||||
|
decltype(auto) operator()(Args&&... args) {
|
||||||
|
return call<>(std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_State* lua_state() const { return L; };
|
||||||
|
int stack_index() const { return index; };
|
||||||
|
|
||||||
|
~load_result() {
|
||||||
|
stack::remove(L, index, popcount);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // sol
|
||||||
|
|
||||||
|
#endif // SOL_LOAD_RESULT_HPP
|
|
@ -73,7 +73,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
protected_function_result() = default;
|
protected_function_result() = default;
|
||||||
protected_function_result(lua_State* L, int index = -1, int returncount = 0, int popcount = 0, call_status error = call_status::ok): L(L), index(index), returncount(returncount), popcount(popcount), err(error) {
|
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(const protected_function_result&) = default;
|
protected_function_result(const protected_function_result&) = default;
|
||||||
|
@ -127,4 +127,4 @@ public:
|
||||||
};
|
};
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
#endif // SOL_FUNCTION_RESULT_HPP
|
#endif // SOL_PROTECTED_FUNCTION_RESULT_HPP
|
||||||
|
|
|
@ -46,6 +46,10 @@ public:
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pop(int n = 1) const noexcept {
|
||||||
|
lua_pop(lua_state( ), n);
|
||||||
|
}
|
||||||
|
|
||||||
int stack_index () const noexcept {
|
int stack_index () const noexcept {
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
@ -58,6 +62,11 @@ public:
|
||||||
lua_State* lua_state() const noexcept {
|
lua_State* lua_state() const noexcept {
|
||||||
return L;
|
return L;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool valid () const noexcept {
|
||||||
|
type t = get_type();
|
||||||
|
return t != type::nil && t != type::none;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
} // sol
|
} // sol
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
|
|
||||||
#include "error.hpp"
|
#include "error.hpp"
|
||||||
#include "table.hpp"
|
#include "table.hpp"
|
||||||
|
#include "load_result.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace sol {
|
namespace sol {
|
||||||
|
@ -157,14 +158,14 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_proxy load(const std::string& code) {
|
load_result load(const std::string& code) {
|
||||||
luaL_loadstring(L, code.c_str());
|
load_status x = static_cast<load_status>(luaL_loadstring(L, code.c_str()));
|
||||||
return stack_proxy(L, -1);
|
return load_result(L, -1, 1, 1, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_proxy load_file(const std::string& filename) {
|
load_result load_file(const std::string& filename) {
|
||||||
luaL_loadfile(L, filename.c_str());
|
load_status x = static_cast<load_status>(luaL_loadfile(L, filename.c_str()));
|
||||||
return stack_proxy(L, -1);
|
return load_result(L, -1, 1, 1, x);
|
||||||
}
|
}
|
||||||
|
|
||||||
iterator begin () const {
|
iterator begin () const {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
thread_status status () const {
|
thread_status status () const {
|
||||||
lua_State* lthread = thread_state();
|
lua_State* lthread = thread_state();
|
||||||
thread_status lstat = static_cast<thread_status>(lua_status(lthread));
|
thread_status lstat = static_cast<thread_status>(lua_status(lthread));
|
||||||
if (lstat != thread_status::normal && lua_gettop(lthread) == 0) {
|
if (lstat != thread_status::ok && lua_gettop(lthread) == 0) {
|
||||||
// No thing on the thread's stack means its dead
|
// No thing on the thread's stack means its dead
|
||||||
return thread_status::dead;
|
return thread_status::dead;
|
||||||
}
|
}
|
||||||
|
|
|
@ -158,15 +158,23 @@ enum class call_status : int {
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class thread_status : int {
|
enum class thread_status : int {
|
||||||
normal = LUA_OK,
|
ok = LUA_OK,
|
||||||
yielded = LUA_YIELD,
|
yielded = LUA_YIELD,
|
||||||
error_runtime = LUA_ERRRUN,
|
runtime = LUA_ERRRUN,
|
||||||
error_memory = LUA_ERRMEM,
|
memory = LUA_ERRMEM,
|
||||||
error_gc = LUA_ERRGCMM,
|
gc = LUA_ERRGCMM,
|
||||||
error_handler = LUA_ERRERR,
|
handler = LUA_ERRERR,
|
||||||
dead,
|
dead,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class load_status : int {
|
||||||
|
ok = LUA_OK,
|
||||||
|
syntax = LUA_ERRSYNTAX,
|
||||||
|
memory = LUA_ERRMEM,
|
||||||
|
gc = LUA_ERRGCMM,
|
||||||
|
file = LUA_ERRFILE,
|
||||||
|
};
|
||||||
|
|
||||||
enum class type : int {
|
enum class type : int {
|
||||||
none = LUA_TNONE,
|
none = LUA_TNONE,
|
||||||
nil = LUA_TNIL,
|
nil = LUA_TNIL,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user