Initial commit

This commit is contained in:
Rapptz 2013-11-25 04:56:27 -05:00
commit f775790c2d
10 changed files with 657 additions and 0 deletions

7
.gitignore vendored Normal file
View File

@ -0,0 +1,7 @@
obj/*
bin/*
*.ninja*
demacro.txt
Shinobi2
dev.*
main.cpp

20
LICENSE.txt Normal file
View File

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2013 Danny Y., Rapptz
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.

69
README.md Normal file
View File

@ -0,0 +1,69 @@
## Sol
Sol is a C++ library binding to Lua. It currently supports Lua 5.2. Sol aims to be easy to use and easy to add to a project.
At this time, the library is header-only for easy integration with projects.
## Caveats
As a change of mechanism to the C API, the Lua Stack is completely abstracted away. Not only that, but all lua errors are
thrown as exceptions instead. This allows you to handle the errors gracefully without being forced to exit.
It should be noted that the library itself depends on `lua.hpp` to be found by your compiler. It uses angle brackets, e.g.
`#include <lua.hpp>`.
## Example
Here's an example on how to load a basic configuration struct with a Lua script.
```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
Sol is distributed with an MIT License. You can see LICENSE.txt for more info.
## Supported Compilers
Sol makes use of C++11 features. The features used are as follows:
- rvalue references
- move semantics
- variadic templates
- <tuple>
- <type_traits>
- std::unique_ptr
- enum classes
- auto
- uniform initialisation
- noexcept
GCC 4.7 and Clang 3.3 or higher should be able to compile without problems. Visual Studio 2013 with the November CTP should
be able to support this as well.

27
sol.hpp Normal file
View File

@ -0,0 +1,27 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_HPP
#define SOL_HPP
#include "sol/state.hpp"
#endif // SOL_HPP

35
sol/error.hpp Normal file
View File

@ -0,0 +1,35 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_ERROR_HPP
#define SOL_ERROR_HPP
#include <stdexcept>
#include <string>
namespace sol {
class sol_error : public std::runtime_error {
public:
sol_error(const std::string& str) noexcept: std::runtime_error("sol: error: " + str) {}
};
} // sol
#endif // SOL_ERROR_HPP

96
sol/reference.hpp Normal file
View File

@ -0,0 +1,96 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_REFERENCE_HPP
#define SOL_REFERENCE_HPP
#include "types.hpp"
namespace sol {
class reference {
private:
lua_State* L = nullptr; // non-owning
int ref = LUA_NOREF;
int copy() const {
push();
return luaL_ref(L, LUA_REGISTRYINDEX);
}
public:
constexpr reference() noexcept = default;
reference(lua_State* L, int index): L(L) {
lua_pushvalue(L, index);
ref = luaL_ref(L, LUA_REGISTRYINDEX);
}
virtual ~reference() {
luaL_unref(L, LUA_REGISTRYINDEX, ref);
}
void push() const noexcept {
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
}
reference(reference&& o) noexcept {
L = o.L;
ref = o.ref;
o.L = nullptr;
o.ref = LUA_NOREF;
}
reference& operator=(reference&& o) noexcept {
L = o.L;
ref = o.ref;
o.L = nullptr;
o.ref = LUA_NOREF;
return *this;
}
reference(const reference& o) noexcept {
L = o.L;
ref = o.copy();
}
reference& operator=(const reference& o) noexcept {
L = o.L;
ref = o.copy();
return *this;
}
type get_type() {
push();
int result = lua_type(L, -1);
lua_pop(L, 1);
return static_cast<type>(result);
}
lua_State* state() const noexcept {
return L;
}
};
} // sol
#endif // SOL_REFERENCE_HPP

146
sol/stack.hpp Normal file
View File

@ -0,0 +1,146 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_STACK_HPP
#define SOL_STACK_HPP
#include "reference.hpp"
#include <utility>
#include <type_traits>
namespace sol {
namespace stack {
namespace detail {
template<typename T>
inline T pop_unsigned(lua_State* L, std::true_type) {
return lua_tounsigned(L, -1);
}
template<typename T>
inline T pop_unsigned(lua_State* L, std::false_type) {
return lua_tointeger(L, -1);
}
template<typename T>
inline T pop_arithmetic(lua_State* L, std::false_type) {
// T is a floating point
return lua_tonumber(L, -1);
}
template<typename T>
inline T pop_arithmetic(lua_State* L, std::true_type) {
// T is an integral
return pop_unsigned<T>(L, std::is_unsigned<T>{});
}
template<typename T>
inline T pop_helper(lua_State* L, std::true_type) {
// T is a class type
return T(L, -1);
}
template<typename T>
inline T pop_helper(lua_State* L, std::false_type) {
// T is a fundamental type
return pop_arithmetic<T>(L, std::is_integral<T>{});
}
template<typename T>
inline void push_unsigned(lua_State* L, T x, std::true_type) {
lua_pushunsigned(L, x);
}
template<typename T>
inline void push_unsigned(lua_State* L, T x, std::false_type) {
lua_pushinteger(L, x);
}
template<typename T>
inline void push_arithmetic(lua_State* L, T x, std::true_type) {
// T is an integral type
push_unsigned(L, x, std::is_unsigned<T>{});
}
template<typename T>
inline void push_arithmetic(lua_State* L, T x, std::false_type) {
// T is an floating point type
lua_pushnumber(L, x);
}
} // detail
template<typename T>
inline T pop(lua_State* L) {
auto result = detail::pop_helper<T>(L, std::is_class<T>{});
lua_pop(L, 1);
return result;
}
template<>
inline bool pop<bool>(lua_State* L) {
auto result = lua_toboolean(L, -1);
lua_pop(L, 1);
return result;
}
template<>
inline std::string pop<std::string>(lua_State* L) {
std::string::size_type len;
auto str = lua_tolstring(L, -1, &len);
lua_pop(L, 1);
return { str, len };
}
template<>
inline const char* pop<const char*>(lua_State* L) {
auto result = lua_tostring(L, -1);
lua_pop(L, 1);
return result;
}
template<typename T>
inline void push(lua_State* L, T arithmetic) {
detail::push_arithmetic(L, arithmetic, std::is_integral<T>{});
}
inline void push(lua_State* L, bool boolean) {
lua_pushboolean(L, boolean);
}
inline void push(lua_State* L, const nil_t&) {
lua_pushnil(L);
}
inline void push(lua_State* L, lua_CFunction func) {
lua_pushcfunction(L, func);
}
template<size_t N>
inline void push(lua_State* L, const char (&str)[N]) {
lua_pushlstring(L, str, N - 1);
}
inline void push(lua_State* L, const std::string& str) {
lua_pushlstring(L, str.c_str(), str.size());
}
} // stack
} // sol
#endif // SOL_STACK_HPP

91
sol/state.hpp Normal file
View File

@ -0,0 +1,91 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_STATE_HPP
#define SOL_STATE_HPP
#include "error.hpp"
#include "table.hpp"
#include <memory>
namespace sol {
int atpanic(lua_State* L) {
throw sol_error(lua_tostring(L, -1));
}
class state {
private:
std::unique_ptr<lua_State, void(*)(lua_State*)> L;
table reg;
table global;
public:
state():
L(luaL_newstate(), lua_close),
reg(L.get(), LUA_REGISTRYINDEX),
global(reg.get<table>(LUA_RIDX_GLOBALS)) {
lua_atpanic(L.get(), atpanic);
}
state(const std::string& filename):
L(luaL_newstate(), lua_close),
reg(L.get(), LUA_REGISTRYINDEX),
global(reg.get<table>(LUA_RIDX_GLOBALS)) {
lua_atpanic(L.get(), atpanic);
open_file(filename);
}
void open_libraries() {
luaL_openlibs(L.get());
}
void script(const std::string& code) {
if(luaL_dostring(L.get(), code.c_str())) {
lua_error(L.get());
}
}
void open_file(const std::string& filename) {
if(luaL_dofile(L.get(), filename.c_str())) {
lua_error(L.get());
}
}
template<typename T, typename U>
T get(U&& key) const {
return global.get<T>(std::forward<U>(key));
}
template<typename T, typename U>
state& set(T&& key, U&& value) {
return global.set(std::forward<T>(key), std::forward<U>(value));
}
table global_table() const {
return global;
}
table registry() const {
return reg;
}
};
} // sol
#endif // SOL_STATE_HPP

58
sol/table.hpp Normal file
View File

@ -0,0 +1,58 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_TABLE_HPP
#define SOL_TABLE_HPP
#include "stack.hpp"
namespace sol {
class table : virtual public reference {
public:
table() noexcept: reference{} {}
table(lua_State* L, int index = -1): reference(L, index) {
type_assert(L, index, type::table);
}
template<typename T, typename U>
T get(U&& key) const {
push();
stack::push(state(), std::forward<U>(key));
lua_gettable(state(), -2);
type_assert(state(), -1, type_of<T>());
auto result = stack::pop<T>(state());
lua_pop(state(), 1);
return result;
}
template<typename T, typename U>
table& set(T&& key, U&& value) {
push();
stack::push(state(), std::forward<T>(key));
stack::push(state(), std::forward<U>(value));
lua_settable(state(), -3);
lua_pop(state(), 1);
return *this;
}
};
} // sol
#endif // SOL_TABLE_HPP

108
sol/types.hpp Normal file
View File

@ -0,0 +1,108 @@
// The MIT License (MIT)
// Copyright (c) 2013 Danny Y., Rapptz
// 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_TYPES_HPP
#define SOL_TYPES_HPP
#include <lua.hpp>
#include <string>
#include <type_traits>
namespace sol {
struct nil_t {};
constexpr nil_t nil{};
enum class type : int {
none = LUA_TNONE,
nil = LUA_TNIL,
string = LUA_TSTRING,
number = LUA_TNUMBER,
thread = LUA_TTHREAD,
boolean = LUA_TBOOLEAN,
function = LUA_TFUNCTION,
userdata = LUA_TUSERDATA,
lightuserdata = LUA_TLIGHTUSERDATA,
table = LUA_TTABLE
};
inline void type_error(lua_State* L, int expected, int actual) {
luaL_error(L, "expected %s, received %s", lua_typename(L, expected), lua_typename(L, actual));
}
inline void type_assert(lua_State* L, int index, type expected) {
int actual = lua_type(L, index);
if(static_cast<int>(expected) != actual) {
type_error(L, static_cast<int>(expected), actual);
}
}
class table;
class function;
namespace detail {
template<typename T>
inline type arithmetic(std::true_type) {
return type::number;
}
template<typename T>
inline type arithmetic(std::false_type) {
return type::none;
}
} // detail
template<typename T>
inline type type_of() {
return detail::arithmetic<T>(std::is_arithmetic<T>{});
}
template<>
inline type type_of<table>() {
return type::table;
}
template<>
inline type type_of<function>() {
return type::function;
}
template<>
inline type type_of<const char*>() {
return type::string;
}
template<>
inline type type_of<std::string>() {
return type::string;
}
template<>
inline type type_of<nil_t>() {
return type::nil;
}
template<>
inline type type_of<bool>() {
return type::boolean;
}
} // sol
#endif // SOL_TYPES_HPP