Initial SharedTable support
This commit is contained in:
parent
8aa635f8c1
commit
74b4e61a36
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
.idea
|
||||||
|
.work_dir
|
||||||
|
build
|
||||||
|
*.user
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
[submodule "src/sol"]
|
||||||
|
path = src/sol
|
||||||
|
url = https://github.com/ThePhD/sol2.git
|
||||||
@ -1,5 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
project(bevy)
|
project(woofer)
|
||||||
|
|
||||||
find_package(Lua REQUIRED)
|
find_package(Lua REQUIRED)
|
||||||
|
|
||||||
@ -7,20 +7,24 @@ if( "${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}" LESS "5.2")
|
|||||||
message(FATAL_ERROR "Wrong Lua version ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}, use 5.2 or higher")
|
message(FATAL_ERROR "Wrong Lua version ${LUA_VERSION_MAJOR}.${LUA_VERSION_MINOR}, use 5.2 or higher")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
include_directories(src/lib src/sol2/single/sol ${LUA_INCLUDE_DIR})
|
include_directories(src src/sol/single/sol ${LUA_INCLUDE_DIR})
|
||||||
|
|
||||||
FILE(GLOB SOURCES src/lib/*.cpp)
|
FILE(GLOB SOURCES src/*.cpp src/*.h)
|
||||||
|
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/build)
|
||||||
|
|
||||||
add_library(bevy SHARED ${SOURCES})
|
add_library(woofer SHARED ${SOURCES})
|
||||||
target_link_libraries(bevy -lpthread ${LUA_LIBRARY})
|
target_link_libraries(woofer -lpthread ${LUA_LIBRARY})
|
||||||
set_target_properties(bevy PROPERTIES COMPILE_FLAGS "-Wall -Wextra -pedantic -O3 -g -std=c++14 -pthread")
|
|
||||||
|
set(GENERAL "-std=c++14 -pthread")
|
||||||
|
set(ENABLE_WARNINGS "-Wall -Wextra -pedantic")
|
||||||
|
set(BUILD_FLAVOR "-O3 -UNDEBUG")
|
||||||
|
set_target_properties(woofer PROPERTIES COMPILE_FLAGS "${ENABLE_WARNINGS} ${GENERAL} ${BUILD_FLAVOR}")
|
||||||
|
|
||||||
#----------
|
#----------
|
||||||
# INSTALL -
|
# INSTALL -
|
||||||
#----------
|
#----------
|
||||||
|
|
||||||
FILE(GLOB TESTS tests/*)
|
FILE(GLOB TESTS tests/*)
|
||||||
FILE(GLOB LUA_SOURCES src/*.lua)
|
FILE(GLOB LUA_SOURCES lua-api/*.lua)
|
||||||
install(FILES ${TESTSz} ${LUA_SOURCES} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
install(FILES ${TESTS} ${LUA_SOURCES} DESTINATION ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})
|
||||||
@ -1,5 +1,6 @@
|
|||||||
--local thr = require('libbevy')
|
--local thr = require('libbevy')
|
||||||
require('libbevy')
|
package.cpath = package.cpath .. ";./?.dylib"
|
||||||
|
require('libwoofer')
|
||||||
local thr = thread
|
local thr = thread
|
||||||
return {
|
return {
|
||||||
new = function(func)
|
new = function(func)
|
||||||
|
|||||||
67
src/shared-table.cpp
Normal file
67
src/shared-table.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
#include "shared-table.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
void SharedTable::bind(sol::state_view& lua) noexcept {
|
||||||
|
lua.new_usertype<SharedTable>("shared_table",
|
||||||
|
sol::meta_function::new_index, &SharedTable::luaSet,
|
||||||
|
sol::meta_function::index, &SharedTable::luaGet,
|
||||||
|
sol::meta_function::length, &SharedTable::size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SharedTable::luaSet(sol::stack_object luaKey, sol::stack_object luaValue) noexcept {
|
||||||
|
assert(luaKey.valid());
|
||||||
|
|
||||||
|
StoredObject key(luaKey);
|
||||||
|
if (luaValue.get_type() == sol::type::nil) {
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
// in this case object is not obligatory to own data
|
||||||
|
data_.erase(key);
|
||||||
|
} else {
|
||||||
|
StoredObject value(luaValue);
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
data_.emplace(std::make_pair(std::move(key), std::move(value)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::object SharedTable::luaGet(sol::stack_object key, sol::this_state state) noexcept {
|
||||||
|
assert(key.valid());
|
||||||
|
|
||||||
|
StoredObject cppKey(key);
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
auto val = data_.find(cppKey);
|
||||||
|
if (val == data_.end()) {
|
||||||
|
return sol::nil;
|
||||||
|
} else {
|
||||||
|
return val->second.unpack(state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t SharedTable::size() noexcept {
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
return data_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
SharedTable* TablePool::getNew() noexcept {
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
data_.push_back(std::make_unique<SharedTable>());
|
||||||
|
return (*data_.rend()).get();
|
||||||
|
}
|
||||||
|
std::size_t TablePool::size() const noexcept {
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
return data_.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TablePool::clear() noexcept {
|
||||||
|
std::lock_guard<SpinMutex> g(lock_);
|
||||||
|
data_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
TablePool& defaultPool() noexcept {
|
||||||
|
static TablePool pool;
|
||||||
|
return pool;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // core
|
||||||
53
src/shared-table.h
Normal file
53
src/shared-table.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "stored-object.h"
|
||||||
|
#include "spin-mutex.h"
|
||||||
|
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class SharedTable {
|
||||||
|
public:
|
||||||
|
SharedTable() = default;
|
||||||
|
virtual ~SharedTable() = default;
|
||||||
|
void luaSet(sol::stack_object luaKey, sol::stack_object luaValue) noexcept;
|
||||||
|
sol::object luaGet(sol::stack_object key, sol::this_state state) noexcept;
|
||||||
|
|
||||||
|
// Add usertype to state
|
||||||
|
static void bind(sol::state_view& lua) noexcept;
|
||||||
|
|
||||||
|
private: // lau bindings
|
||||||
|
size_t size() noexcept;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SpinMutex lock_;
|
||||||
|
std::unordered_map<StoredObject, StoredObject> data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
SharedTable(const SharedTable&) = delete;
|
||||||
|
SharedTable& operator=(const SharedTable&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
class TablePool {
|
||||||
|
public:
|
||||||
|
TablePool() = default;
|
||||||
|
SharedTable* getNew() noexcept;
|
||||||
|
std::size_t size() const noexcept;
|
||||||
|
void clear() noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
mutable SpinMutex lock_;
|
||||||
|
std::vector<std::unique_ptr<SharedTable>> data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
TablePool(const TablePool&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
TablePool& defaultPool() noexcept;
|
||||||
|
|
||||||
|
} // core
|
||||||
1
src/sol
Submodule
1
src/sol
Submodule
@ -0,0 +1 @@
|
|||||||
|
Subproject commit 039331e163bb3a4870426e7b8ae7b55b53ecc579
|
||||||
24
src/spin-mutex.h
Normal file
24
src/spin-mutex.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class SpinMutex {
|
||||||
|
public:
|
||||||
|
void lock() noexcept {
|
||||||
|
while(lock_.test_and_set(std::memory_order_acquire)) {
|
||||||
|
std::this_thread::yield();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock() noexcept {
|
||||||
|
lock_.clear(std::memory_order_release);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // core
|
||||||
118
src/stored-object.cpp
Normal file
118
src/stored-object.cpp
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "stored-object.h"
|
||||||
|
|
||||||
|
#include "shared-table.h"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
#define ERROR std::cerr
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
FunctionHolder::FunctionHolder(sol::stack_object luaObject) noexcept {
|
||||||
|
sol::state_view lua(luaObject.lua_state());
|
||||||
|
sol::function dumper = lua["string"]["dump"];
|
||||||
|
|
||||||
|
assert(dumper.valid());
|
||||||
|
function_ = dumper(luaObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionHolder::rawCompare(const BaseHolder* other) const noexcept {
|
||||||
|
return function_ == static_cast<const FunctionHolder*>(other)->function_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool FunctionHolder::rawLess(const BaseHolder* other) const noexcept {
|
||||||
|
return function_ < static_cast<const FunctionHolder*>(other)->function_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t FunctionHolder::hash() const noexcept {
|
||||||
|
return std::hash<std::string>()(function_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::object FunctionHolder::unpack(sol::this_state state) const noexcept {
|
||||||
|
sol::state_view lua((lua_State*)state);
|
||||||
|
sol::function loader = lua["loadstring"];
|
||||||
|
assert(loader.valid());
|
||||||
|
|
||||||
|
sol::function result = loader(function_);
|
||||||
|
if (!result.valid()) {
|
||||||
|
ERROR << "Unable to restore function!" << std::endl;
|
||||||
|
ERROR << "Content:" << std::endl;
|
||||||
|
ERROR << function_ << std::endl;
|
||||||
|
}
|
||||||
|
return sol::make_object(state, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
StoredObject::StoredObject(StoredObject&& init) noexcept
|
||||||
|
: data_(std::move(init.data_)) {}
|
||||||
|
|
||||||
|
StoredObject::StoredObject(sol::stack_object luaObject) noexcept
|
||||||
|
: data_(nullptr) {
|
||||||
|
switch(luaObject.get_type()) {
|
||||||
|
case sol::type::nil:
|
||||||
|
break;
|
||||||
|
case sol::type::boolean:
|
||||||
|
data_.reset(new PrimitiveHolder<bool>(luaObject));
|
||||||
|
break;
|
||||||
|
case sol::type::number:
|
||||||
|
data_.reset(new PrimitiveHolder<double>(luaObject));
|
||||||
|
break;
|
||||||
|
case sol::type::string:
|
||||||
|
data_.reset(new PrimitiveHolder<std::string>(luaObject));
|
||||||
|
break;
|
||||||
|
case sol::type::userdata:
|
||||||
|
data_.reset(new PrimitiveHolder<SharedTable*>(luaObject));
|
||||||
|
break;
|
||||||
|
case sol::type::function:
|
||||||
|
data_.reset(new FunctionHolder(luaObject));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
StoredObject::operator bool() const noexcept {
|
||||||
|
return (bool)data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
StoredObject::StoredObject(SharedTable* table) noexcept
|
||||||
|
: data_(new PrimitiveHolder<SharedTable*>(table)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t StoredObject::hash() const noexcept {
|
||||||
|
if (data_)
|
||||||
|
return data_->hash();
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::object StoredObject::unpack(sol::this_state state) const noexcept {
|
||||||
|
if (data_)
|
||||||
|
return data_->unpack(state);
|
||||||
|
else
|
||||||
|
return sol::nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
StoredObject& StoredObject::operator=(StoredObject&& o) noexcept {
|
||||||
|
data_ = std::move(o.data_);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoredObject::operator==(const StoredObject& o) const noexcept {
|
||||||
|
if (data_)
|
||||||
|
return data_->compare(o.data_.get());
|
||||||
|
else
|
||||||
|
return data_.get() == o.data_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool StoredObject::operator<(const StoredObject& o) const noexcept {
|
||||||
|
if (data_)
|
||||||
|
return data_->less(o.data_.get());
|
||||||
|
else
|
||||||
|
return data_.get() < o.data_.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // core
|
||||||
120
src/stored-object.h
Normal file
120
src/stored-object.h
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sol.hpp>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
namespace core {
|
||||||
|
|
||||||
|
class BaseHolder {
|
||||||
|
public:
|
||||||
|
BaseHolder() noexcept : type_(sol::type::nil) {}
|
||||||
|
virtual ~BaseHolder() = default;
|
||||||
|
|
||||||
|
sol::type type() const noexcept {
|
||||||
|
return type_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool compare(const BaseHolder* other) const noexcept {
|
||||||
|
assert(other != nullptr);
|
||||||
|
return type_ == other->type_ && rawCompare(other);
|
||||||
|
}
|
||||||
|
virtual bool less(const BaseHolder* other) const noexcept {
|
||||||
|
assert(other != nullptr);
|
||||||
|
return type_ < other->type_ && rawLess(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool rawCompare(const BaseHolder* other) const noexcept = 0;
|
||||||
|
virtual bool rawLess(const BaseHolder* other) const noexcept = 0;
|
||||||
|
virtual std::size_t hash() const noexcept = 0;
|
||||||
|
virtual sol::object unpack(sol::this_state state) const noexcept = 0;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
sol::type type_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BaseHolder(const BaseHolder&) = delete;
|
||||||
|
BaseHolder(BaseHolder&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename StoredType>
|
||||||
|
class PrimitiveHolder : public BaseHolder {
|
||||||
|
public:
|
||||||
|
PrimitiveHolder(sol::stack_object luaObject) noexcept
|
||||||
|
: data_(luaObject.as<StoredType>()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
PrimitiveHolder(const StoredType& init) noexcept
|
||||||
|
: data_(init) {}
|
||||||
|
|
||||||
|
bool rawCompare(const BaseHolder* other) const noexcept final {
|
||||||
|
assert(type_ == other->type());
|
||||||
|
return static_cast<const PrimitiveHolder<StoredType>*>(other)->data_ == data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool rawLess(const BaseHolder* other) const noexcept final {
|
||||||
|
assert(type_ == other->type());
|
||||||
|
return data_ < static_cast<const PrimitiveHolder<StoredType>*>(other)->data_;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t hash() const noexcept final {
|
||||||
|
return std::hash<StoredType>()(data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
sol::object unpack(sol::this_state state) const noexcept final {
|
||||||
|
return sol::make_object(state, data_);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
StoredType data_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FunctionHolder : public BaseHolder {
|
||||||
|
public:
|
||||||
|
FunctionHolder(sol::stack_object luaObject) noexcept;
|
||||||
|
bool rawCompare(const BaseHolder* other) const noexcept final;
|
||||||
|
bool rawLess(const BaseHolder* other) const noexcept final;
|
||||||
|
std::size_t hash() const noexcept final;
|
||||||
|
sol::object unpack(sol::this_state state) const noexcept final;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string function_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SharedTable;
|
||||||
|
|
||||||
|
class StoredObject {
|
||||||
|
public:
|
||||||
|
StoredObject() = default;
|
||||||
|
StoredObject(StoredObject&& init) noexcept;
|
||||||
|
StoredObject(sol::stack_object luaObject) noexcept;
|
||||||
|
//StoredObject(sol::object luaObject) noexcept;
|
||||||
|
StoredObject(SharedTable*) noexcept;
|
||||||
|
|
||||||
|
operator bool() const noexcept;
|
||||||
|
std::size_t hash() const noexcept;
|
||||||
|
sol::object unpack(sol::this_state state) const noexcept;
|
||||||
|
StoredObject& operator=(StoredObject&& o) noexcept;
|
||||||
|
bool operator==(const StoredObject& o) const noexcept;
|
||||||
|
bool operator<(const StoredObject& o) const noexcept;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<BaseHolder> data_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
StoredObject(const StoredObject&) = delete;
|
||||||
|
StoredObject& operator=(const StoredObject&) = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // core
|
||||||
|
|
||||||
|
namespace std {
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct hash<core::StoredObject> {
|
||||||
|
std::size_t operator()(const core::StoredObject &object) const noexcept {
|
||||||
|
return object.hash();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // std
|
||||||
@ -77,7 +77,7 @@ static std::string ThreadId()
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int luaopen_libbevy(lua_State *L)
|
extern "C" int luaopen_libwoofer(lua_State *L)
|
||||||
{
|
{
|
||||||
sol::state_view lua(L);
|
sol::state_view lua(L);
|
||||||
lua.new_usertype<LuaThread>("thread",
|
lua.new_usertype<LuaThread>("thread",
|
||||||
|
|||||||
198
tests/shared-table.cpp
Normal file
198
tests/shared-table.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
#include <boost/test/unit_test.hpp>
|
||||||
|
|
||||||
|
#include "shared-table.h"
|
||||||
|
#include "lua-utils.h"
|
||||||
|
|
||||||
|
#include <logging.h>
|
||||||
|
|
||||||
|
using namespace core;
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(singleThreadSet) {
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
|
||||||
|
SharedTable st;
|
||||||
|
|
||||||
|
lua["st"] = &st;
|
||||||
|
|
||||||
|
auto res1 = lua.script(R"(
|
||||||
|
st.fst = "first"
|
||||||
|
st.snd = 2
|
||||||
|
st.thr = true
|
||||||
|
st.del = "secret"
|
||||||
|
st.del = nil
|
||||||
|
)");
|
||||||
|
if (!res1.valid()) {
|
||||||
|
BOOST_FAIL("Set res1 failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK(lua["st"]["fst"] == std::string("first"));
|
||||||
|
BOOST_CHECK(lua["st"]["snd"] == (double)2);
|
||||||
|
BOOST_CHECK(lua["st"]["thr"] == true);
|
||||||
|
BOOST_CHECK(lua["st"]["del"] == sol::nil);
|
||||||
|
BOOST_CHECK(lua["st"]["nex"] == sol::nil);
|
||||||
|
|
||||||
|
auto res2 = lua.script(R"(
|
||||||
|
st[1] = 3
|
||||||
|
st[2] = "number"
|
||||||
|
st[-1] = false
|
||||||
|
st[42] = "answer"
|
||||||
|
st[42] = nil
|
||||||
|
st.deleted = st[42] == nil
|
||||||
|
)");
|
||||||
|
if (!res2.valid()) {
|
||||||
|
BOOST_FAIL("Set res2 failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK(lua["st"][1] == 3);
|
||||||
|
BOOST_CHECK(lua["st"][2] == std::string("number"));
|
||||||
|
BOOST_CHECK(lua["st"][-1] == false);
|
||||||
|
BOOST_CHECK(lua["st"]["deleted"] == true);
|
||||||
|
|
||||||
|
auto res3 = lua.script(R"(
|
||||||
|
st[true] = false
|
||||||
|
st[false] = 9
|
||||||
|
)");
|
||||||
|
if (!res3.valid()) {
|
||||||
|
BOOST_FAIL("Set res3 failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_CHECK(lua["st"][true] == false);
|
||||||
|
BOOST_CHECK(lua["st"][false] == 9);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(asGlobalTable) {
|
||||||
|
sol::state lua;
|
||||||
|
SharedTable st;
|
||||||
|
bootstrapState(lua);
|
||||||
|
|
||||||
|
lua["st"] = &st;
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
_G = st
|
||||||
|
n = 1
|
||||||
|
b = false
|
||||||
|
s = "Oo"
|
||||||
|
)");
|
||||||
|
|
||||||
|
BOOST_CHECK(lua["n"] == 1);
|
||||||
|
BOOST_CHECK(lua["b"] == false);
|
||||||
|
BOOST_CHECK(lua["s"] == std::string("Oo"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(severalStates) {
|
||||||
|
sol::state lua1, lua2;
|
||||||
|
bootstrapState(lua1);
|
||||||
|
bootstrapState(lua2);
|
||||||
|
|
||||||
|
auto st = std::make_unique<SharedTable>();
|
||||||
|
|
||||||
|
lua1["cats"] = st.get();
|
||||||
|
lua2["dogs"] = st.get();
|
||||||
|
|
||||||
|
auto res1 = lua1.script(R"(
|
||||||
|
cats.fluffy = "gav"
|
||||||
|
cats.sparky = false
|
||||||
|
cats.wow = 3
|
||||||
|
)");
|
||||||
|
|
||||||
|
BOOST_CHECK(lua2["dogs"]["fluffy"] == std::string("gav"));
|
||||||
|
BOOST_CHECK(lua2["dogs"]["sparky"] == false);
|
||||||
|
BOOST_CHECK(lua2["dogs"]["wow"] == 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(multipleThreads) {
|
||||||
|
SharedTable st;
|
||||||
|
|
||||||
|
std::vector<std::thread> threads;
|
||||||
|
|
||||||
|
threads.emplace_back([&](){
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
lua["st"] = &st;
|
||||||
|
lua.script(R"(
|
||||||
|
while not st.ready do end
|
||||||
|
st.fst = true)");
|
||||||
|
});
|
||||||
|
|
||||||
|
threads.emplace_back([&](){
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
lua["st"] = &st;
|
||||||
|
lua.script(R"(
|
||||||
|
while not st.ready do end
|
||||||
|
st.snd = true)");
|
||||||
|
});
|
||||||
|
|
||||||
|
threads.emplace_back([&](){
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
lua["st"] = &st;
|
||||||
|
lua.script(R"(
|
||||||
|
while not st.ready do end
|
||||||
|
st.thr = true)");
|
||||||
|
});
|
||||||
|
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
lua["st"] = &st;
|
||||||
|
lua.script("st.ready = true");
|
||||||
|
|
||||||
|
for(auto& thread : threads) { thread.join(); }
|
||||||
|
|
||||||
|
BOOST_CHECK(lua["st"]["fst"] == true);
|
||||||
|
BOOST_CHECK(lua["st"]["snd"] == true);
|
||||||
|
BOOST_CHECK(lua["st"]["thr"] == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(nestedTables) {
|
||||||
|
SharedTable recursive, st1, st2;
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
|
||||||
|
lua["recursive"] = &recursive;
|
||||||
|
lua["st1"] = &st1;
|
||||||
|
lua["st2"] = &st2;
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
st1.proxy = st2
|
||||||
|
st1.proxy.value = true
|
||||||
|
recursive.next = recursive
|
||||||
|
recursive.val = "yes"
|
||||||
|
)");
|
||||||
|
BOOST_CHECK(lua["st2"]["value"] == true);
|
||||||
|
BOOST_CHECK(lua["recursive"]["next"]["next"]["next"]["val"] == std::string("yes"));
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOST_AUTO_TEST_CASE(playingWithFunctions) {
|
||||||
|
SharedTable st;
|
||||||
|
sol::state lua;
|
||||||
|
bootstrapState(lua);
|
||||||
|
|
||||||
|
lua["st"] = &st;
|
||||||
|
|
||||||
|
lua.script(R"(
|
||||||
|
st.fn = function ()
|
||||||
|
print "Hello C++"
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
st.fn()
|
||||||
|
)");
|
||||||
|
|
||||||
|
sol::function sf = lua["st"]["fn"];
|
||||||
|
BOOST_CHECK((bool)sf());
|
||||||
|
|
||||||
|
sol::state lua2;
|
||||||
|
bootstrapState(lua2);
|
||||||
|
|
||||||
|
lua2["st2"] = &st;
|
||||||
|
lua2.script(R"(
|
||||||
|
st2.fn2 = function(str)
|
||||||
|
return "*" .. str .. "*"
|
||||||
|
end
|
||||||
|
)");
|
||||||
|
|
||||||
|
sol::function sf2 = lua["st"]["fn2"];
|
||||||
|
|
||||||
|
BOOST_CHECK(sf2(std::string("SUCCESS")).get<std::string>() == std::string("*SUCCESS*"));
|
||||||
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
local thr = require('bevy')
|
local thr = require('woofer')
|
||||||
t = thr.new(
|
t = thr.new(
|
||||||
function()
|
function()
|
||||||
local thr = require('bevy')
|
local thr = require('woofer')
|
||||||
print(share['key1'])
|
print(share['key1'])
|
||||||
print(share['key2'])
|
print(share['key2'])
|
||||||
print(share['key3'])
|
print(share['key3'])
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user