Merge pull request #11 from loud-hound/optimizations

optimize data transferring and throw sol::error instead of writing to std::cerr
This commit is contained in:
Ilia 2017-01-24 23:01:26 +03:00 committed by GitHub
commit 5f1b620f6b
7 changed files with 63 additions and 47 deletions

View File

@ -16,14 +16,13 @@ sol::object SharedTable::getUserType(sol::state_view &lua) noexcept {
return sol::stack::pop<sol::object>(lua); return sol::stack::pop<sol::object>(lua);
} }
void SharedTable::set(StoredObject key, StoredObject value) noexcept { void SharedTable::set(StoredObject&& key, StoredObject&& value) noexcept {
std::lock_guard<SpinMutex> g(lock_); std::lock_guard<SpinMutex> g(lock_);
data_[std::move(key)] = std::move(value); data_[std::move(key)] = std::move(value);
} }
void SharedTable::luaSet(sol::stack_object luaKey, sol::stack_object luaValue) { void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue) {
if (!luaKey.valid()) ASSERT(luaKey.valid()) << "Invalid table index";
throw sol::error("Invalid table index");
StoredObject key(luaKey); StoredObject key(luaKey);
if (luaValue.get_type() == sol::type::nil) { if (luaValue.get_type() == sol::type::nil) {
@ -31,13 +30,11 @@ void SharedTable::luaSet(sol::stack_object luaKey, sol::stack_object luaValue) {
// in this case object is not obligatory to own data // in this case object is not obligatory to own data
data_.erase(key); data_.erase(key);
} else { } else {
StoredObject value(luaValue); set(std::move(key), StoredObject(luaValue));
std::lock_guard<SpinMutex> g(lock_);
data_[std::move(key)] = std::move(value);
} }
} }
sol::object SharedTable::luaGet(sol::stack_object key, sol::this_state state) const noexcept { sol::object SharedTable::luaGet(const sol::stack_object& key, const sol::this_state& state) const noexcept {
assert(key.valid()); assert(key.valid());
StoredObject cppKey(key); StoredObject cppKey(key);

View File

@ -17,12 +17,12 @@ public:
virtual ~SharedTable() = default; virtual ~SharedTable() = default;
static sol::object getUserType(sol::state_view &lua) noexcept; static sol::object getUserType(sol::state_view &lua) noexcept;
void set(StoredObject, StoredObject) noexcept; void set(StoredObject&&, StoredObject&&) noexcept;
size_t size() const noexcept; size_t size() const noexcept;
public: // lua bindings public: // lua bindings
void luaSet(sol::stack_object luaKey, sol::stack_object luaValue); void luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue);
sol::object luaGet(sol::stack_object key, sol::this_state state) const noexcept; sol::object luaGet(const sol::stack_object& key, const sol::this_state& state) const noexcept;
protected: protected:
mutable SpinMutex lock_; mutable SpinMutex lock_;

View File

@ -16,17 +16,17 @@ namespace {
template<typename StoredType> template<typename StoredType>
class PrimitiveHolder : public BaseHolder { class PrimitiveHolder : public BaseHolder {
public: public:
PrimitiveHolder(sol::stack_object luaObject) noexcept PrimitiveHolder(const sol::stack_object& luaObject) noexcept
: BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {} : BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {}
PrimitiveHolder(sol::object luaObject) noexcept PrimitiveHolder(const sol::object& luaObject) noexcept
: BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {} : BaseHolder(luaObject.get_type()), data_(luaObject.as<StoredType>()) {}
PrimitiveHolder(sol::type type, const StoredType& init) noexcept PrimitiveHolder(sol::type type, const StoredType& init) noexcept
: BaseHolder(type), data_(init) {} : BaseHolder(type), data_(init) {}
bool rawCompare(const BaseHolder* other) const noexcept final { bool rawCompare(const BaseHolder* other) const noexcept final {
assert(type_ == other->type()); ASSERT(type_ == other->type());
return static_cast<const PrimitiveHolder<StoredType>*>(other)->data_ == data_; return static_cast<const PrimitiveHolder<StoredType>*>(other)->data_ == data_;
} }
@ -50,7 +50,7 @@ public:
sol::state_view lua(luaObject.lua_state()); sol::state_view lua(luaObject.lua_state());
sol::function dumper = lua["string"]["dump"]; sol::function dumper = lua["string"]["dump"];
assert(dumper.valid()); ASSERT(dumper.valid());
function_ = dumper(luaObject); function_ = dumper(luaObject);
} }
@ -65,14 +65,11 @@ public:
sol::object unpack(sol::this_state state) const noexcept final { sol::object unpack(sol::this_state state) const noexcept final {
sol::state_view lua((lua_State*)state); sol::state_view lua((lua_State*)state);
sol::function loader = lua["loadstring"]; sol::function loader = lua["loadstring"];
assert(loader.valid()); ASSERT(loader.valid());
sol::function result = loader(function_); sol::function result = loader(function_);
if (!result.valid()) { ASSERT(result.valid()) << "Unable to restore function!\n"
ERROR << "Unable to restore function!" << std::endl; << "Content:\n" << function_;
ERROR << "Content:" << std::endl;
ERROR << function_ << std::endl;
}
return sol::make_object(state, result); return sol::make_object(state, result);
} }
@ -115,7 +112,7 @@ void dumpTable(SharedTable* target, sol::table luaTable, SolTableToShared& visit
} }
template<typename SolObject> template<typename SolObject>
std::unique_ptr<BaseHolder> fromSolObject(SolObject luaObject) { std::unique_ptr<BaseHolder> fromSolObject(const SolObject& luaObject) {
switch(luaObject.get_type()) { switch(luaObject.get_type()) {
case sol::type::nil: case sol::type::nil:
break; break;
@ -144,7 +141,7 @@ std::unique_ptr<BaseHolder> fromSolObject(SolObject luaObject) {
return std::make_unique<PrimitiveHolder<SharedTable*>>(sol::type::userdata, table); return std::make_unique<PrimitiveHolder<SharedTable*>>(sol::type::userdata, table);
} }
default: default:
ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << std::endl; ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << "\n";
} }
return nullptr; return nullptr;
} }
@ -158,11 +155,11 @@ StoredObject::StoredObject(SharedTable* table) noexcept
: data_(new PrimitiveHolder<SharedTable*>(sol::type::userdata, table)) { : data_(new PrimitiveHolder<SharedTable*>(sol::type::userdata, table)) {
} }
StoredObject::StoredObject(sol::object object) noexcept StoredObject::StoredObject(const sol::object& object) noexcept
: data_(fromSolObject(object)) { : data_(fromSolObject(object)) {
} }
StoredObject::StoredObject(sol::stack_object object) noexcept StoredObject::StoredObject(const sol::stack_object& object) noexcept
: data_(fromSolObject(object)) { : data_(fromSolObject(object)) {
} }

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <sol.hpp> #include <utils.h>
#include <utility> #include <utility>
#include <iostream> #include <iostream>
@ -17,7 +17,7 @@ public:
} }
bool compare(const BaseHolder* other) const noexcept { bool compare(const BaseHolder* other) const noexcept {
assert(other != nullptr); ASSERT(other != nullptr);
return type_ == other->type_ && rawCompare(other); return type_ == other->type_ && rawCompare(other);
} }
@ -40,8 +40,8 @@ public:
StoredObject() = default; StoredObject() = default;
StoredObject(StoredObject&& init) noexcept; StoredObject(StoredObject&& init) noexcept;
StoredObject(SharedTable*) noexcept; StoredObject(SharedTable*) noexcept;
StoredObject(sol::object) noexcept; StoredObject(const sol::object&) noexcept;
StoredObject(sol::stack_object) noexcept; StoredObject(const sol::stack_object&) noexcept;
operator bool() const noexcept; operator bool() const noexcept;
std::size_t hash() const noexcept; std::size_t hash() const noexcept;

View File

@ -9,7 +9,7 @@ LuaThread::LuaThread(const sol::function& function, const sol::variadic_args& ar
// 2. Create new state // 2. Create new state
p_state_.reset(new sol::state); p_state_.reset(new sol::state);
assert(p_state_.get() != NULL); ASSERT(p_state_.get() != NULL);
p_state_->open_libraries( p_state_->open_libraries(
sol::lib::base, sol::lib::string, sol::lib::base, sol::lib::string,
sol::lib::package, sol::lib::io, sol::lib::os sol::lib::package, sol::lib::io, sol::lib::os
@ -22,7 +22,7 @@ LuaThread::LuaThread(const sol::function& function, const sol::variadic_args& ar
// 4. Run thread // 4. Run thread
p_thread_.reset(new std::thread(&LuaThread::work, this)); p_thread_.reset(new std::thread(&LuaThread::work, this));
assert(p_thread_.get() != NULL); ASSERT(p_thread_.get() != NULL);
} }
void LuaThread::storeArgs(const sol::variadic_args &args) noexcept { void LuaThread::storeArgs(const sol::variadic_args &args) noexcept {
@ -49,15 +49,13 @@ void LuaThread::detach() noexcept {
} }
void LuaThread::work() noexcept { void LuaThread::work() noexcept {
if (p_state_.get() && p_arguments_.get()) { ASSERT(p_state_.get() && p_arguments_.get()) << "invalid thread Lua state\n";
std::string func_owner = std::move(str_function_);
std::shared_ptr<sol::state> state_owner = p_state_; std::string func_owner = std::move(str_function_);
std::shared_ptr<std::vector<sol::object>> arguments_owner = p_arguments_; std::shared_ptr<sol::state> state_owner = p_state_;
sol::function_result func = (*state_owner)["loadstring"](func_owner); std::shared_ptr<std::vector<sol::object>> arguments_owner = p_arguments_;
func.get<sol::function>()(sol::as_args(*arguments_owner)); sol::function_result func = (*state_owner)["loadstring"](func_owner);
} else { func.get<sol::function>()(sol::as_args(*arguments_owner));
throw sol::error("Internal error: invalid thread Lua state");
}
} }
std::string LuaThread::threadId() noexcept { std::string LuaThread::threadId() noexcept {

View File

@ -2,8 +2,6 @@
#include "shared-table.h" #include "shared-table.h"
#include <sol.hpp>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include <thread> #include <thread>

View File

@ -1,9 +1,35 @@
#pragma once #pragma once
#include <iostream> #include <iostream>
#include <sstream>
#ifdef NDEBUG #include <sol.hpp>
# define ERROR if(false) std::cerr
#else namespace effil {
# define ERROR std::cerr namespace utils {
#endif
class Exception : public sol::error {
public:
Exception() noexcept : sol::error("") {}
template<typename T>
Exception& operator<<(const T& value) {
std::stringstream ss;
ss << value;
message_ += ss.str();
return *this;
}
virtual const char* what() const noexcept override {
return message_.c_str();
}
private:
std::string message_;
};
} // utils
} // effil
#define ERROR throw effil::utils::Exception() << __FILE__ << ":" << __LINE__
#define ASSERT(cond) if (!(cond)) ERROR << "In condition '" << #cond << "': "