Robust exception handling
This commit is contained in:
parent
9f5267e23b
commit
3310901ce3
@ -7,12 +7,12 @@
|
|||||||
|
|
||||||
namespace effil {
|
namespace effil {
|
||||||
|
|
||||||
GarbageCollector::GarbageCollector() noexcept
|
GarbageCollector::GarbageCollector()
|
||||||
: state_(GCState::Idle),
|
: state_(GCState::Idle),
|
||||||
lastCleanup_(0),
|
lastCleanup_(0),
|
||||||
step_(200) {}
|
step_(200) {}
|
||||||
|
|
||||||
GCObject* GarbageCollector::get(GCObjectHandle handle) noexcept {
|
GCObject* GarbageCollector::get(GCObjectHandle handle) {
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
std::lock_guard<std::mutex> g(lock_);
|
||||||
auto it = objects_.find(handle);
|
auto it = objects_.find(handle);
|
||||||
if (it == objects_.end()) {
|
if (it == objects_.end()) {
|
||||||
@ -22,7 +22,7 @@ GCObject* GarbageCollector::get(GCObjectHandle handle) noexcept {
|
|||||||
return it->second.get();
|
return it->second.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GarbageCollector::has(GCObjectHandle handle) const noexcept {
|
bool GarbageCollector::has(GCObjectHandle handle) const {
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
std::lock_guard<std::mutex> g(lock_);
|
||||||
return objects_.find(handle) != objects_.end();
|
return objects_.find(handle) != objects_.end();
|
||||||
}
|
}
|
||||||
@ -63,25 +63,25 @@ void GarbageCollector::cleanup() {
|
|||||||
lastCleanup_.store(0);
|
lastCleanup_.store(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t GarbageCollector::size() const noexcept {
|
size_t GarbageCollector::size() const {
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
std::lock_guard<std::mutex> g(lock_);
|
||||||
return objects_.size();
|
return objects_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarbageCollector::stop() noexcept {
|
void GarbageCollector::stop() {
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
std::lock_guard<std::mutex> g(lock_);
|
||||||
assert(state_ == GCState::Idle || state_ == GCState::Stopped);
|
assert(state_ == GCState::Idle || state_ == GCState::Stopped);
|
||||||
state_ = GCState::Stopped;
|
state_ = GCState::Stopped;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GarbageCollector::resume() noexcept {
|
void GarbageCollector::resume() {
|
||||||
std::lock_guard<std::mutex> g(lock_);
|
std::lock_guard<std::mutex> g(lock_);
|
||||||
assert(state_ == GCState::Idle || state_ == GCState::Stopped);
|
assert(state_ == GCState::Idle || state_ == GCState::Stopped);
|
||||||
state_ = GCState::Idle;
|
state_ = GCState::Idle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GarbageCollector& getGC() noexcept {
|
GarbageCollector& getGC() {
|
||||||
static GarbageCollector pool;
|
static GarbageCollector pool;
|
||||||
return pool;
|
return pool;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -39,7 +39,7 @@ enum class GCState {
|
|||||||
|
|
||||||
class GarbageCollector {
|
class GarbageCollector {
|
||||||
public:
|
public:
|
||||||
GarbageCollector() noexcept;
|
GarbageCollector();
|
||||||
~GarbageCollector() = default;
|
~GarbageCollector() = default;
|
||||||
|
|
||||||
// This method is used to create all managed objects.
|
// This method is used to create all managed objects.
|
||||||
@ -53,15 +53,15 @@ public:
|
|||||||
return *object;
|
return *object;
|
||||||
}
|
}
|
||||||
|
|
||||||
GCObject* get(GCObjectHandle handle) noexcept;
|
GCObject* get(GCObjectHandle handle);
|
||||||
bool has(GCObjectHandle handle) const noexcept;
|
bool has(GCObjectHandle handle) const;
|
||||||
void cleanup();
|
void cleanup();
|
||||||
size_t size() const noexcept;
|
size_t size() const;
|
||||||
void stop() noexcept;
|
void stop();
|
||||||
void resume() noexcept;
|
void resume();
|
||||||
size_t step() const noexcept { return step_; }
|
size_t step() const { return step_; }
|
||||||
void step(size_t newStep) noexcept { step_ = newStep; }
|
void step(size_t newStep) { step_ = newStep; }
|
||||||
GCState state() const noexcept { return state_; }
|
GCState state() const { return state_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
mutable std::mutex lock_;
|
mutable std::mutex lock_;
|
||||||
@ -76,6 +76,6 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
GarbageCollector& getGC() noexcept;
|
GarbageCollector& getGC();
|
||||||
|
|
||||||
} // effil
|
} // effil
|
||||||
@ -7,17 +7,17 @@
|
|||||||
|
|
||||||
namespace effil {
|
namespace effil {
|
||||||
|
|
||||||
SharedTable::SharedTable() noexcept
|
SharedTable::SharedTable()
|
||||||
: GCObject(),
|
: GCObject(),
|
||||||
data_(std::make_shared<SharedData>()) {
|
data_(std::make_shared<SharedData>()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedTable::SharedTable(const SharedTable& init) noexcept
|
SharedTable::SharedTable(const SharedTable& init)
|
||||||
: GCObject(init),
|
: GCObject(init),
|
||||||
data_(init.data_) {
|
data_(init.data_) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object SharedTable::getUserType(sol::state_view &lua) noexcept {
|
sol::object SharedTable::getUserType(sol::state_view &lua) {
|
||||||
static sol::usertype<SharedTable> type(
|
static sol::usertype<SharedTable> type(
|
||||||
"new", sol::no_constructor,
|
"new", sol::no_constructor,
|
||||||
sol::meta_function::new_index, &SharedTable::luaSet,
|
sol::meta_function::new_index, &SharedTable::luaSet,
|
||||||
@ -28,7 +28,7 @@ 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) {
|
||||||
std::lock_guard<SpinMutex> g(data_->lock);
|
std::lock_guard<SpinMutex> g(data_->lock);
|
||||||
|
|
||||||
if (key->gcHandle()) refs_->insert(key->gcHandle());
|
if (key->gcHandle()) refs_->insert(key->gcHandle());
|
||||||
@ -38,7 +38,7 @@ void SharedTable::set(StoredObject&& key, StoredObject&& value) noexcept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue) {
|
void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue) {
|
||||||
ASSERT(luaKey.valid()) << "Invalid table index";
|
REQUIRE(luaKey.valid()) << "Indexing by nil";
|
||||||
|
|
||||||
StoredObject key = createStoredObject(luaKey);
|
StoredObject key = createStoredObject(luaKey);
|
||||||
if (luaValue.get_type() == sol::type::nil) {
|
if (luaValue.get_type() == sol::type::nil) {
|
||||||
@ -57,12 +57,12 @@ void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_objec
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object SharedTable::luaGet(const sol::stack_object& key, const sol::this_state& state) const {
|
sol::object SharedTable::luaGet(const sol::stack_object& luaKey, const sol::this_state& state) const {
|
||||||
ASSERT(key.valid());
|
REQUIRE(luaKey.valid()) << "Indexing by nil";
|
||||||
|
|
||||||
StoredObject cppKey = createStoredObject(key);
|
StoredObject key = createStoredObject(luaKey);
|
||||||
std::lock_guard<SpinMutex> g(data_->lock);
|
std::lock_guard<SpinMutex> g(data_->lock);
|
||||||
auto val = data_->entries.find(cppKey);
|
auto val = data_->entries.find(key);
|
||||||
if (val == data_->entries.end()) {
|
if (val == data_->entries.end()) {
|
||||||
return sol::nil;
|
return sol::nil;
|
||||||
} else {
|
} else {
|
||||||
@ -70,7 +70,7 @@ sol::object SharedTable::luaGet(const sol::stack_object& key, const sol::this_st
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t SharedTable::size() const noexcept {
|
size_t SharedTable::size() const {
|
||||||
std::lock_guard<SpinMutex> g(data_->lock);
|
std::lock_guard<SpinMutex> g(data_->lock);
|
||||||
return data_->entries.size();
|
return data_->entries.size();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,18 +13,18 @@ namespace effil {
|
|||||||
|
|
||||||
class SharedTable : public GCObject {
|
class SharedTable : public GCObject {
|
||||||
public:
|
public:
|
||||||
SharedTable() noexcept;
|
SharedTable();
|
||||||
SharedTable(SharedTable&&) = default;
|
SharedTable(SharedTable&&) = default;
|
||||||
SharedTable(const SharedTable& init) noexcept;
|
SharedTable(const SharedTable& init);
|
||||||
virtual ~SharedTable() = default;
|
virtual ~SharedTable() = default;
|
||||||
|
|
||||||
static sol::object getUserType(sol::state_view &lua) noexcept;
|
static sol::object getUserType(sol::state_view &lua);
|
||||||
void set(StoredObject&&, StoredObject&&) noexcept;
|
void set(StoredObject&&, StoredObject&&);
|
||||||
|
|
||||||
// These functions could be invoked from lua scripts
|
// These functions could be invoked from lua scripts
|
||||||
void luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue);
|
void luaSet(const sol::stack_object& luaKey, const sol::stack_object& luaValue);
|
||||||
sol::object luaGet(const sol::stack_object& key, const sol::this_state& state) const;
|
sol::object luaGet(const sol::stack_object& luaKey, const sol::this_state& state) const;
|
||||||
size_t size() const noexcept;
|
size_t size() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef std::unique_ptr<BaseHolder> StoredObject;
|
typedef std::unique_ptr<BaseHolder> StoredObject;
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public:
|
|||||||
FunctionHolder(SolObject luaObject) noexcept {
|
FunctionHolder(SolObject luaObject) noexcept {
|
||||||
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());
|
if (!dumper.valid()) throw Exception() << "Invalid string.dump()";
|
||||||
function_ = dumper(luaObject);
|
function_ = dumper(luaObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,9 +62,10 @@ public:
|
|||||||
sol::object unpack(sol::this_state state) const final {
|
sol::object unpack(sol::this_state state) const 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());
|
REQUIRE(loader.valid()) << "Invalid loadstring()";
|
||||||
sol::function result = loader(function_);
|
sol::function result = loader(function_);
|
||||||
ASSERT(result.valid()) << "Unable to restore function!\n" << "Content:\n" << function_;
|
// The result of restaring always is valid function.
|
||||||
|
assert(result.valid());
|
||||||
return sol::make_object(state, result);
|
return sol::make_object(state, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,28 +76,28 @@ private:
|
|||||||
class TableHolder : public BaseHolder {
|
class TableHolder : public BaseHolder {
|
||||||
public:
|
public:
|
||||||
template<typename SolType>
|
template<typename SolType>
|
||||||
TableHolder(const SolType& luaObject) noexcept {
|
TableHolder(const SolType& luaObject) {
|
||||||
assert(luaObject.template is<SharedTable>());
|
assert(luaObject.template is<SharedTable>());
|
||||||
handle_ = luaObject.template as<SharedTable>().handle();
|
handle_ = luaObject.template as<SharedTable>().handle();
|
||||||
assert(getGC().has(handle_));
|
assert(getGC().has(handle_));
|
||||||
}
|
}
|
||||||
|
|
||||||
TableHolder(GCObjectHandle handle) noexcept
|
TableHolder(GCObjectHandle handle)
|
||||||
: handle_(handle) {}
|
: handle_(handle) {}
|
||||||
|
|
||||||
bool rawCompare(const BaseHolder *other) const noexcept final {
|
bool rawCompare(const BaseHolder *other) const final {
|
||||||
return static_cast<const TableHolder*>(other)->handle_ == handle_;
|
return static_cast<const TableHolder*>(other)->handle_ == handle_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t hash() const noexcept final {
|
std::size_t hash() const final {
|
||||||
return std::hash<GCObjectHandle>()(handle_);
|
return std::hash<GCObjectHandle>()(handle_);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object unpack(sol::this_state state) const noexcept final {
|
sol::object unpack(sol::this_state state) const final {
|
||||||
return sol::make_object(state, *static_cast<SharedTable*>(getGC().get(handle_)));
|
return sol::make_object(state, *static_cast<SharedTable*>(getGC().get(handle_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
GCObjectHandle gcHandle() const noexcept override { return handle_; }
|
GCObjectHandle gcHandle() const override { return handle_; }
|
||||||
private:
|
private:
|
||||||
GCObjectHandle handle_;
|
GCObjectHandle handle_;
|
||||||
};
|
};
|
||||||
@ -165,7 +166,7 @@ StoredObject fromSolObject(const SolObject& luaObject) {
|
|||||||
return std::make_unique<TableHolder>(table.handle());
|
return std::make_unique<TableHolder>(table.handle());
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
ERROR << "Unable to store object of that type: " << (int)luaObject.get_type() << "\n";
|
throw Exception() << "Unable to store object of that type: " << (int)luaObject.get_type() << "\n";
|
||||||
}
|
}
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,16 +11,16 @@ public:
|
|||||||
BaseHolder() = default;
|
BaseHolder() = default;
|
||||||
virtual ~BaseHolder() = default;
|
virtual ~BaseHolder() = default;
|
||||||
|
|
||||||
bool compare(const BaseHolder* other) const noexcept {
|
bool compare(const BaseHolder* other) const {
|
||||||
return typeid(*this) == typeid(*other) && rawCompare(other);
|
return typeid(*this) == typeid(*other) && rawCompare(other);
|
||||||
}
|
}
|
||||||
virtual bool rawCompare(const BaseHolder* other) const = 0;
|
virtual bool rawCompare(const BaseHolder* other) const = 0;
|
||||||
virtual const std::type_info& type() { return typeid(*this); }
|
virtual const std::type_info& type() { return typeid(*this); }
|
||||||
|
|
||||||
virtual std::size_t hash() const noexcept = 0;
|
virtual std::size_t hash() const = 0;
|
||||||
virtual sol::object unpack(sol::this_state state) const = 0;
|
virtual sol::object unpack(sol::this_state state) const = 0;
|
||||||
|
|
||||||
virtual GCObjectHandle gcHandle() const noexcept { return GCNull; }
|
virtual GCObjectHandle gcHandle() const { return GCNull; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BaseHolder(const BaseHolder&) = delete;
|
BaseHolder(const BaseHolder&) = delete;
|
||||||
|
|||||||
@ -7,19 +7,19 @@ namespace effil {
|
|||||||
|
|
||||||
class LuaHookStopException : public std::exception {};
|
class LuaHookStopException : public std::exception {};
|
||||||
|
|
||||||
std::string threadId() noexcept
|
std::string threadId()
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << std::this_thread::get_id();
|
ss << std::this_thread::get_id();
|
||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void yield() noexcept
|
void yield()
|
||||||
{
|
{
|
||||||
std::this_thread::yield();
|
std::this_thread::yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
void sleep(int64_t time, sol::optional<std::string> period) noexcept
|
void sleep(int64_t time, sol::optional<std::string> period)
|
||||||
{
|
{
|
||||||
std::string metric = period ? period.value() : "s";
|
std::string metric = period ? period.value() : "s";
|
||||||
if (metric == "ms")
|
if (metric == "ms")
|
||||||
@ -38,7 +38,7 @@ thread_local LuaThread::ThreadData* LuaThread::pThreadLocalData = NULL;
|
|||||||
|
|
||||||
LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args) {
|
LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args) {
|
||||||
pThreadData_ = threadData;
|
pThreadData_ = threadData;
|
||||||
ASSERT(pThreadData_.get());
|
assert(pThreadData_);
|
||||||
pThreadData_->command = ThreadCommand::Nothing;
|
pThreadData_->command = ThreadCommand::Nothing;
|
||||||
pThreadData_->status = ThreadStatus::Running;
|
pThreadData_->status = ThreadStatus::Running;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
pThread_.reset(new std::thread(&LuaThread::work, pThreadData_, function, std::move(arguments)));
|
pThread_.reset(new std::thread(&LuaThread::work, pThreadData_, function, std::move(arguments)));
|
||||||
ASSERT(pThread_.get() != nullptr);
|
assert(pThread_);
|
||||||
pThread_->detach();
|
pThread_->detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -84,12 +84,12 @@ void LuaThread::luaHook(lua_State*, lua_Debug*)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments) noexcept {
|
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments) {
|
||||||
try {
|
try {
|
||||||
pThreadLocalData = threadData.get();
|
pThreadLocalData = threadData.get();
|
||||||
ASSERT(threadData.get()) << "invalid internal thread state\n";
|
assert(threadData);
|
||||||
const sol::object& stringLoader = threadData->luaState["loadstring"];
|
const sol::object& stringLoader = threadData->luaState["loadstring"];
|
||||||
ASSERT(stringLoader.valid() && stringLoader.get_type() == sol::type::function);
|
REQUIRE(stringLoader.valid() && stringLoader.get_type() == sol::type::function) << "Invalid loadstring function";
|
||||||
sol::function userFuncObj = static_cast<const sol::function&>(stringLoader)(strFunction);
|
sol::function userFuncObj = static_cast<const sol::function&>(stringLoader)(strFunction);
|
||||||
sol::function_result results = userFuncObj(sol::as_args(arguments));
|
sol::function_result results = userFuncObj(sol::as_args(arguments));
|
||||||
(void)results; // TODO: try to avoid use of useless sol::function_result here
|
(void)results; // TODO: try to avoid use of useless sol::function_result here
|
||||||
@ -111,22 +111,22 @@ void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string s
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaThread::cancel() noexcept
|
void LuaThread::cancel()
|
||||||
{
|
{
|
||||||
pThreadData_->command = ThreadCommand::Cancel;
|
pThreadData_->command = ThreadCommand::Cancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaThread::pause() noexcept
|
void LuaThread::pause()
|
||||||
{
|
{
|
||||||
pThreadData_->command = ThreadCommand::Pause;
|
pThreadData_->command = ThreadCommand::Pause;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaThread::resume() noexcept
|
void LuaThread::resume()
|
||||||
{
|
{
|
||||||
pThreadData_->command = ThreadCommand::Resume;
|
pThreadData_->command = ThreadCommand::Resume;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const noexcept
|
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
|
||||||
{
|
{
|
||||||
|
|
||||||
ThreadStatus stat = pThreadData_->status;
|
ThreadStatus stat = pThreadData_->status;
|
||||||
@ -145,7 +145,7 @@ std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
|
|||||||
return std::make_tuple(sol::make_object(state, threadStatusToString(stat)), std::move(returns));
|
return std::make_tuple(sol::make_object(state, threadStatusToString(stat)), std::move(returns));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaThread::threadStatusToString(ThreadStatus stat) const noexcept
|
std::string LuaThread::threadStatusToString(ThreadStatus stat) const
|
||||||
{
|
{
|
||||||
switch(stat)
|
switch(stat)
|
||||||
{
|
{
|
||||||
@ -159,12 +159,12 @@ std::string LuaThread::threadStatusToString(ThreadStatus stat) const noexcept
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string LuaThread::status() const noexcept
|
std::string LuaThread::status() const
|
||||||
{
|
{
|
||||||
return threadStatusToString(pThreadData_->status);
|
return threadStatusToString(pThreadData_->status);
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object LuaThread::getUserType(sol::state_view &lua) noexcept
|
sol::object LuaThread::getUserType(sol::state_view &lua)
|
||||||
{
|
{
|
||||||
static sol::usertype<LuaThread> type(
|
static sol::usertype<LuaThread> type(
|
||||||
"new", sol::no_constructor,
|
"new", sol::no_constructor,
|
||||||
@ -183,8 +183,7 @@ sol::object LuaThread::getUserType(sol::state_view &lua) noexcept
|
|||||||
ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step_(100U) {
|
ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step_(100U) {
|
||||||
sol::state_view lua(func.lua_state());
|
sol::state_view lua(func.lua_state());
|
||||||
const sol::object& dumper = lua["string"]["dump"];
|
const sol::object& dumper = lua["string"]["dump"];
|
||||||
ASSERT(dumper.valid() && dumper.get_type() == sol::type::function)
|
REQUIRE(dumper.valid() && dumper.get_type() == sol::type::function) << "Unable to get string.dump()";
|
||||||
<< "Unable to get string.dump()";
|
|
||||||
strFunction_ = static_cast<const sol::function&>(dumper)(func);
|
strFunction_ = static_cast<const sol::function&>(dumper)(func);
|
||||||
|
|
||||||
// Inherit all pathes from parent state by default
|
// Inherit all pathes from parent state by default
|
||||||
@ -193,8 +192,8 @@ ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& args) {
|
std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& args) {
|
||||||
std::shared_ptr<LuaThread::ThreadData> threadData(new LuaThread::ThreadData);
|
std::shared_ptr<LuaThread::ThreadData> threadData = std::make_shared<LuaThread::ThreadData>();
|
||||||
ASSERT(threadData.get());
|
assert(threadData.get());
|
||||||
threadData->luaState.open_libraries(
|
threadData->luaState.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
|
||||||
@ -246,7 +245,7 @@ std::string ThreadFactory::packageCPath(const sol::optional<std::string>& value)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
sol::object ThreadFactory::getUserType(sol::state_view &lua) noexcept
|
sol::object ThreadFactory::getUserType(sol::state_view &lua)
|
||||||
{
|
{
|
||||||
static sol::usertype<ThreadFactory> type(
|
static sol::usertype<ThreadFactory> type(
|
||||||
"new", sol::no_constructor,
|
"new", sol::no_constructor,
|
||||||
|
|||||||
@ -9,9 +9,9 @@
|
|||||||
namespace effil {
|
namespace effil {
|
||||||
|
|
||||||
// Lua this thread API
|
// Lua this thread API
|
||||||
std::string threadId() noexcept;
|
std::string threadId();
|
||||||
void yield() noexcept;
|
void yield();
|
||||||
void sleep(int64_t, sol::optional<std::string>) noexcept;
|
void sleep(int64_t, sol::optional<std::string>);
|
||||||
|
|
||||||
class LuaThread {
|
class LuaThread {
|
||||||
public:
|
public:
|
||||||
@ -39,22 +39,22 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args);
|
LuaThread(std::shared_ptr<ThreadData> threadData, const std::string& function, const sol::variadic_args& args);
|
||||||
static sol::object getUserType(sol::state_view &lua) noexcept;
|
static sol::object getUserType(sol::state_view &lua);
|
||||||
static void luaHook(lua_State*, lua_Debug*);
|
static void luaHook(lua_State*, lua_Debug*);
|
||||||
|
|
||||||
/* Public lua methods*/
|
/* Public lua methods*/
|
||||||
void cancel() noexcept;
|
void cancel();
|
||||||
void pause() noexcept;
|
void pause();
|
||||||
void resume() noexcept;
|
void resume();
|
||||||
std::string status() const noexcept;
|
std::string status() const;
|
||||||
std::tuple<sol::object, sol::table> wait(sol::this_state state) const noexcept;
|
std::tuple<sol::object, sol::table> wait(sol::this_state state) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LuaThread(const LuaThread&) = delete;
|
LuaThread(const LuaThread&) = delete;
|
||||||
LuaThread& operator=(const LuaThread&) = delete;
|
LuaThread& operator=(const LuaThread&) = delete;
|
||||||
|
|
||||||
std::string threadStatusToString(ThreadStatus stat) const noexcept;
|
std::string threadStatusToString(ThreadStatus stat) const;
|
||||||
static void work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments) noexcept;
|
static void work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments);
|
||||||
|
|
||||||
std::shared_ptr<ThreadData> pThreadData_;
|
std::shared_ptr<ThreadData> pThreadData_;
|
||||||
std::shared_ptr<std::thread> pThread_;
|
std::shared_ptr<std::thread> pThread_;
|
||||||
@ -65,7 +65,7 @@ private:
|
|||||||
class ThreadFactory {
|
class ThreadFactory {
|
||||||
public:
|
public:
|
||||||
ThreadFactory(const sol::function& func);
|
ThreadFactory(const sol::function& func);
|
||||||
static sol::object getUserType(sol::state_view &lua) noexcept;
|
static sol::object getUserType(sol::state_view &lua);
|
||||||
|
|
||||||
/* Public lua methods*/
|
/* Public lua methods*/
|
||||||
std::unique_ptr<LuaThread> runThread(const sol::variadic_args& args);
|
std::unique_ptr<LuaThread> runThread(const sol::variadic_args& args);
|
||||||
|
|||||||
@ -29,8 +29,7 @@ private:
|
|||||||
|
|
||||||
} // effil
|
} // effil
|
||||||
|
|
||||||
#define ERROR throw effil::Exception() << __FILE__ << ":" << __LINE__
|
#define REQUIRE(cond) if (!cond) throw effil::Exception()
|
||||||
#define ASSERT(cond) if (!(cond)) ERROR << "In condition '" << #cond << "': "
|
|
||||||
|
|
||||||
#ifdef NDEBUG
|
#ifdef NDEBUG
|
||||||
# define DEBUG if (false) std::cout
|
# define DEBUG if (false) std::cout
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user