Fix codestyle
This commit is contained in:
parent
78f2306657
commit
e8bbb5d293
@ -8,9 +8,9 @@
|
||||
namespace effil {
|
||||
|
||||
GarbageCollector::GarbageCollector()
|
||||
: state_(GCState::Idle),
|
||||
lastCleanup_(0),
|
||||
step_(200) {}
|
||||
: state_(GCState::Idle)
|
||||
, lastCleanup_(0)
|
||||
, step_(200) {}
|
||||
|
||||
GCObject* GarbageCollector::get(GCObjectHandle handle) {
|
||||
std::lock_guard<std::mutex> g(lock_);
|
||||
@ -32,7 +32,8 @@ bool GarbageCollector::has(GCObjectHandle handle) const {
|
||||
void GarbageCollector::cleanup() {
|
||||
std::lock_guard<std::mutex> g(lock_);
|
||||
|
||||
if (state_ == GCState::Stopped) return;
|
||||
if (state_ == GCState::Stopped)
|
||||
return;
|
||||
assert(state_ != GCState::Running);
|
||||
state_ = GCState::Running;
|
||||
|
||||
@ -54,8 +55,7 @@ void GarbageCollector::cleanup() {
|
||||
grey.push_back(refHandle);
|
||||
}
|
||||
|
||||
DEBUG << "Removing " << (objects_.size() - black.size())
|
||||
<< " out of " << objects_.size() << std::endl;
|
||||
DEBUG << "Removing " << (objects_.size() - black.size()) << " out of " << objects_.size() << std::endl;
|
||||
// Sweep phase
|
||||
objects_ = std::move(black);
|
||||
|
||||
@ -80,7 +80,6 @@ void GarbageCollector::resume() {
|
||||
state_ = GCState::Idle;
|
||||
}
|
||||
|
||||
|
||||
GarbageCollector& getGC() {
|
||||
static GarbageCollector pool;
|
||||
return pool;
|
||||
|
||||
@ -18,7 +18,8 @@ static const GCObjectHandle GCNull = nullptr;
|
||||
// Child has to care about storing data and concurrent access.
|
||||
class GCObject {
|
||||
public:
|
||||
GCObject() noexcept : refs_(new std::set<GCObjectHandle>) {}
|
||||
GCObject() noexcept
|
||||
: refs_(new std::set<GCObjectHandle>) {}
|
||||
GCObject(const GCObject& init) = default;
|
||||
GCObject(GCObject&& init) = default;
|
||||
virtual ~GCObject() = default;
|
||||
@ -31,11 +32,7 @@ protected:
|
||||
std::shared_ptr<std::set<GCObjectHandle>> refs_;
|
||||
};
|
||||
|
||||
enum class GCState {
|
||||
Idle,
|
||||
Running,
|
||||
Stopped
|
||||
};
|
||||
enum class GCState { Idle, Running, Stopped };
|
||||
|
||||
class GarbageCollector {
|
||||
public:
|
||||
@ -45,7 +42,8 @@ public:
|
||||
// This method is used to create all managed objects.
|
||||
template <typename ObjectType, typename... Args>
|
||||
ObjectType create(Args&&... args) {
|
||||
if (lastCleanup_.fetch_add(1) == step_) cleanup();
|
||||
if (lastCleanup_.fetch_add(1) == step_)
|
||||
cleanup();
|
||||
auto object = std::make_shared<ObjectType>(std::forward<Args>(args)...);
|
||||
|
||||
std::lock_guard<std::mutex> g(lock_);
|
||||
@ -75,7 +73,6 @@ private:
|
||||
GarbageCollector(const GarbageCollector&) = delete;
|
||||
};
|
||||
|
||||
|
||||
GarbageCollector& getGC();
|
||||
|
||||
} // effil
|
||||
@ -12,9 +12,7 @@ sol::object createThreadFactory(sol::this_state lua, const sol::function& func)
|
||||
return sol::make_object(lua, std::make_unique<ThreadFactory>(func));
|
||||
}
|
||||
|
||||
sol::object createShare(sol::this_state lua) {
|
||||
return sol::make_object(lua, getGC().create<SharedTable>());
|
||||
}
|
||||
sol::object createShare(sol::this_state lua) { return sol::make_object(lua, getGC().create<SharedTable>()); }
|
||||
|
||||
} // namespace
|
||||
|
||||
@ -23,8 +21,7 @@ extern "C" int luaopen_libeffil(lua_State *L) {
|
||||
effil::LuaThread::getUserType(lua);
|
||||
SharedTable::getUserType(lua);
|
||||
ThreadFactory::getUserType(lua);
|
||||
sol::table public_api = lua.create_table_with(
|
||||
"thread", createThreadFactory, //
|
||||
sol::table public_api = lua.create_table_with("thread", createThreadFactory, //
|
||||
"thread_id", threadId, //
|
||||
"sleep", sleep, //
|
||||
"yield", yield, //
|
||||
@ -33,4 +30,3 @@ extern "C" int luaopen_libeffil(lua_State *L) {
|
||||
sol::stack::push(lua, public_api);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@ -8,18 +8,15 @@
|
||||
namespace effil {
|
||||
|
||||
SharedTable::SharedTable()
|
||||
: GCObject(),
|
||||
data_(std::make_shared<SharedData>()) {
|
||||
}
|
||||
: GCObject()
|
||||
, data_(std::make_shared<SharedData>()) {}
|
||||
|
||||
SharedTable::SharedTable(const SharedTable& init)
|
||||
: GCObject(init),
|
||||
data_(init.data_) {
|
||||
}
|
||||
: GCObject(init)
|
||||
, data_(init.data_) {}
|
||||
|
||||
sol::object SharedTable::getUserType(sol::state_view& lua) {
|
||||
static sol::usertype<SharedTable> type(
|
||||
"new", sol::no_constructor, //
|
||||
static sol::usertype<SharedTable> type("new", sol::no_constructor, //
|
||||
sol::meta_function::new_index, &SharedTable::luaSet, //
|
||||
sol::meta_function::index, &SharedTable::luaGet, //
|
||||
sol::meta_function::length, &SharedTable::length, //
|
||||
@ -33,8 +30,10 @@ sol::object SharedTable::getUserType(sol::state_view &lua) {
|
||||
void SharedTable::set(StoredObject&& key, StoredObject&& value) {
|
||||
std::lock_guard<SpinMutex> g(data_->lock);
|
||||
|
||||
if (key->gcHandle()) refs_->insert(key->gcHandle());
|
||||
if (value->gcHandle()) refs_->insert(value->gcHandle());
|
||||
if (key->gcHandle())
|
||||
refs_->insert(key->gcHandle());
|
||||
if (value->gcHandle())
|
||||
refs_->insert(value->gcHandle());
|
||||
|
||||
data_->entries[std::move(key)] = std::move(value);
|
||||
}
|
||||
@ -59,8 +58,10 @@ void SharedTable::luaSet(const sol::stack_object& luaKey, const sol::stack_objec
|
||||
// in this case object is not obligatory to own data
|
||||
auto it = data_->entries.find(key);
|
||||
if (it != data_->entries.end()) {
|
||||
if (it->first->gcHandle()) refs_->erase(it->first->gcHandle());
|
||||
if (it->second->gcHandle()) refs_->erase(it->second->gcHandle());
|
||||
if (it->first->gcHandle())
|
||||
refs_->erase(it->first->gcHandle());
|
||||
if (it->second->gcHandle())
|
||||
refs_->erase(it->second->gcHandle());
|
||||
data_->entries.erase(it);
|
||||
}
|
||||
|
||||
@ -85,14 +86,12 @@ size_t SharedTable::length() const {
|
||||
size_t len = 0u;
|
||||
sol::optional<double> value;
|
||||
auto iter = data_->entries.find(createStoredObject(static_cast<double>(1)));
|
||||
if (iter != data_->entries.end())
|
||||
{
|
||||
do
|
||||
{
|
||||
if (iter != data_->entries.end()) {
|
||||
do {
|
||||
++len;
|
||||
++iter;
|
||||
}
|
||||
while ((iter != data_->entries.end()) && (value = storedObjectToDouble(iter->first)) && (static_cast<size_t>(value.value()) == len + 1));
|
||||
} while ((iter != data_->entries.end()) && (value = storedObjectToDouble(iter->first)) &&
|
||||
(static_cast<size_t>(value.value()) == len + 1));
|
||||
}
|
||||
return len;
|
||||
}
|
||||
@ -104,8 +103,7 @@ SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::thi
|
||||
auto upper = data_->entries.upper_bound(obj);
|
||||
if (upper != data_->entries.end())
|
||||
return std::tuple<sol::object, sol::object>(upper->first->unpack(lua), upper->second->unpack(lua));
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (!data_->entries.empty()) {
|
||||
const auto& begin = data_->entries.begin();
|
||||
return std::tuple<sol::object, sol::object>(begin->first->unpack(lua), begin->second->unpack(lua));
|
||||
@ -117,12 +115,14 @@ SharedTable::PairsIterator SharedTable::getNext(const sol::object& key, sol::thi
|
||||
SharedTable::PairsIterator SharedTable::pairs(sol::this_state lua) const {
|
||||
auto next = [](sol::this_state lua, SharedTable table, sol::stack_object key) { return table.getNext(key, lua); };
|
||||
return std::tuple<sol::function, sol::object>(
|
||||
sol::make_object(lua, std::function<PairsIterator(sol::this_state lua, SharedTable table, sol::stack_object key)>(next)).as<sol::function>(),
|
||||
sol::make_object(lua, *this)
|
||||
);
|
||||
sol::make_object(
|
||||
lua, std::function<PairsIterator(sol::this_state lua, SharedTable table, sol::stack_object key)>(next))
|
||||
.as<sol::function>(),
|
||||
sol::make_object(lua, *this));
|
||||
}
|
||||
|
||||
std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable table, sol::optional<unsigned long> key) {
|
||||
std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable table,
|
||||
sol::optional<unsigned long> key) {
|
||||
size_t index = key ? key.value() + 1 : 1;
|
||||
auto objKey = createStoredObject(static_cast<double>(index));
|
||||
sol::object value = table.get(objKey, lua);
|
||||
@ -132,10 +132,8 @@ std::tuple<sol::object, sol::object> ipairsNext(sol::this_state lua, SharedTable
|
||||
}
|
||||
|
||||
std::tuple<sol::function, sol::object> SharedTable::ipairs(sol::this_state lua) const {
|
||||
return std::tuple<sol::function, sol::object>(
|
||||
sol::make_object(lua, ipairsNext).as<sol::function>(),
|
||||
sol::make_object(lua, *this)
|
||||
);
|
||||
return std::tuple<sol::function, sol::object>(sol::make_object(lua, ipairsNext).as<sol::function>(),
|
||||
sol::make_object(lua, *this));
|
||||
}
|
||||
|
||||
} // effil
|
||||
|
||||
@ -36,7 +36,6 @@ public:
|
||||
PairsIterator ipairs(sol::this_state) const;
|
||||
|
||||
private:
|
||||
|
||||
struct SharedData {
|
||||
SpinMutex lock;
|
||||
DataEntries entries;
|
||||
@ -46,4 +45,3 @@ private:
|
||||
};
|
||||
|
||||
} // effil
|
||||
|
||||
|
||||
@ -13,9 +13,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() noexcept {
|
||||
lock_.clear(std::memory_order_release);
|
||||
}
|
||||
void unlock() noexcept { lock_.clear(std::memory_order_release); }
|
||||
|
||||
private:
|
||||
std::atomic_flag lock_ = ATOMIC_FLAG_INIT;
|
||||
|
||||
@ -29,9 +29,7 @@ public:
|
||||
return data_ < static_cast<const PrimitiveHolder<StoredType>*>(other)->data_;
|
||||
}
|
||||
|
||||
sol::object unpack(sol::this_state state) const final {
|
||||
return sol::make_object(state, data_);
|
||||
}
|
||||
sol::object unpack(sol::this_state state) const final { return sol::make_object(state, data_); }
|
||||
|
||||
StoredType getData() { return data_; }
|
||||
|
||||
@ -45,7 +43,8 @@ public:
|
||||
FunctionHolder(SolObject luaObject) noexcept {
|
||||
sol::state_view lua(luaObject.lua_state());
|
||||
sol::function dumper = lua["string"]["dump"];
|
||||
if (!dumper.valid()) throw Exception() << "Invalid string.dump()";
|
||||
if (!dumper.valid())
|
||||
throw Exception() << "Invalid string.dump()";
|
||||
function_ = dumper(luaObject);
|
||||
}
|
||||
|
||||
@ -142,8 +141,7 @@ StoredObject fromSolObject(const SolObject& luaObject) {
|
||||
return std::make_unique<TableHolder>(luaObject);
|
||||
case sol::type::function:
|
||||
return std::make_unique<FunctionHolder>(luaObject);
|
||||
case sol::type::table:
|
||||
{
|
||||
case sol::type::table: {
|
||||
sol::table luaTable = luaObject;
|
||||
// Tables pool is used to store tables.
|
||||
// Right now not defiantly clear how ownership between states works.
|
||||
@ -164,29 +162,19 @@ StoredObject fromSolObject(const SolObject& luaObject) {
|
||||
|
||||
} // namespace
|
||||
|
||||
StoredObject createStoredObject(bool value) {
|
||||
return std::make_unique<PrimitiveHolder<bool>>(value);
|
||||
}
|
||||
StoredObject createStoredObject(bool value) { return std::make_unique<PrimitiveHolder<bool>>(value); }
|
||||
|
||||
StoredObject createStoredObject(double value) {
|
||||
return std::make_unique<PrimitiveHolder<double>>(value);
|
||||
}
|
||||
StoredObject createStoredObject(double value) { return std::make_unique<PrimitiveHolder<double>>(value); }
|
||||
|
||||
StoredObject createStoredObject(const std::string& value) {
|
||||
return std::make_unique<PrimitiveHolder<std::string>>(value);
|
||||
}
|
||||
|
||||
StoredObject createStoredObject(const sol::object &object) {
|
||||
return fromSolObject(object);
|
||||
}
|
||||
StoredObject createStoredObject(const sol::object& object) { return fromSolObject(object); }
|
||||
|
||||
StoredObject createStoredObject(const sol::stack_object &object) {
|
||||
return fromSolObject(object);
|
||||
}
|
||||
StoredObject createStoredObject(const sol::stack_object& object) { return fromSolObject(object); }
|
||||
|
||||
StoredObject createStoredObject(GCObjectHandle handle) {
|
||||
return std::make_unique<TableHolder>(handle);
|
||||
}
|
||||
StoredObject createStoredObject(GCObjectHandle handle) { return std::make_unique<TableHolder>(handle); }
|
||||
|
||||
template <typename DataType>
|
||||
sol::optional<DataType> getPrimitiveHolderData(const StoredObject& sobj) {
|
||||
@ -196,13 +184,9 @@ sol::optional<DataType> getPrimitiveHolderData(const StoredObject& sobj) {
|
||||
return sol::optional<DataType>();
|
||||
}
|
||||
|
||||
sol::optional<bool> storedObjectToBool(const StoredObject& sobj) {
|
||||
return getPrimitiveHolderData<bool>(sobj);
|
||||
}
|
||||
sol::optional<bool> storedObjectToBool(const StoredObject& sobj) { return getPrimitiveHolderData<bool>(sobj); }
|
||||
|
||||
sol::optional<double> storedObjectToDouble(const StoredObject& sobj) {
|
||||
return getPrimitiveHolderData<double>(sobj);
|
||||
}
|
||||
sol::optional<double> storedObjectToDouble(const StoredObject& sobj) { return getPrimitiveHolderData<double>(sobj); }
|
||||
|
||||
sol::optional<std::string> storedObjectToString(const StoredObject& sobj) {
|
||||
return getPrimitiveHolderData<std::string>(sobj);
|
||||
|
||||
@ -30,9 +30,7 @@ private:
|
||||
typedef std::unique_ptr<BaseHolder> StoredObject;
|
||||
|
||||
struct StoredObjectLess {
|
||||
bool operator()(const StoredObject& lhs, const StoredObject& rhs) const {
|
||||
return lhs->compare(rhs.get());
|
||||
}
|
||||
bool operator()(const StoredObject& lhs, const StoredObject& rhs) const { return lhs->compare(rhs.get()); }
|
||||
};
|
||||
|
||||
StoredObject createStoredObject(bool);
|
||||
|
||||
@ -7,20 +7,15 @@ namespace effil {
|
||||
|
||||
class LuaHookStopException : public std::exception {};
|
||||
|
||||
std::string threadId()
|
||||
{
|
||||
std::string threadId() {
|
||||
std::stringstream ss;
|
||||
ss << std::this_thread::get_id();
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
void yield()
|
||||
{
|
||||
std::this_thread::yield();
|
||||
}
|
||||
void yield() { std::this_thread::yield(); }
|
||||
|
||||
void sleep(int64_t time, sol::optional<std::string> period)
|
||||
{
|
||||
void sleep(int64_t time, sol::optional<std::string> period) {
|
||||
std::string metric = period ? period.value() : "s";
|
||||
if (metric == "ms")
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(time));
|
||||
@ -36,7 +31,8 @@ thread_local LuaThread::ThreadData* LuaThread::pThreadLocalData = NULL;
|
||||
|
||||
// class LuaThread
|
||||
|
||||
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;
|
||||
assert(pThreadData_);
|
||||
pThreadData_->command = ThreadCommand::Nothing;
|
||||
@ -53,14 +49,10 @@ LuaThread::LuaThread(std::shared_ptr<ThreadData> threadData, const std::string&
|
||||
pThread_->detach();
|
||||
}
|
||||
|
||||
void LuaThread::luaHook(lua_State*, lua_Debug*)
|
||||
{
|
||||
if (pThreadLocalData)
|
||||
{
|
||||
switch (pThreadLocalData->command)
|
||||
{
|
||||
case ThreadCommand::Pause:
|
||||
{
|
||||
void LuaThread::luaHook(lua_State*, lua_Debug*) {
|
||||
if (pThreadLocalData) {
|
||||
switch (pThreadLocalData->command) {
|
||||
case ThreadCommand::Pause: {
|
||||
pThreadLocalData->status = ThreadStatus::Paused;
|
||||
ThreadCommand cmd = pThreadLocalData->command;
|
||||
while (cmd == ThreadCommand::Pause) {
|
||||
@ -68,12 +60,11 @@ void LuaThread::luaHook(lua_State*, lua_Debug*)
|
||||
cmd = pThreadLocalData->command;
|
||||
}
|
||||
assert(cmd != ThreadCommand::Nothing);
|
||||
if (cmd == ThreadCommand::Resume)
|
||||
{
|
||||
if (cmd == ThreadCommand::Resume) {
|
||||
pThreadLocalData->status = ThreadStatus::Running;
|
||||
break; // Just go out of the function
|
||||
} else { /* HOOK_STOP - do nothing and go to the next case */
|
||||
}
|
||||
else { /* HOOK_STOP - do nothing and go to the next case */}
|
||||
}
|
||||
case ThreadCommand::Cancel:
|
||||
throw LuaHookStopException();
|
||||
@ -84,12 +75,14 @@ void LuaThread::luaHook(lua_State*, lua_Debug*)
|
||||
}
|
||||
}
|
||||
|
||||
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments) {
|
||||
void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string strFunction,
|
||||
std::vector<sol::object>&& arguments) {
|
||||
try {
|
||||
pThreadLocalData = threadData.get();
|
||||
assert(threadData);
|
||||
const sol::object& stringLoader = threadData->luaState["loadstring"];
|
||||
REQUIRE(stringLoader.valid() && stringLoader.get_type() == sol::type::function) << "Invalid loadstring 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_result results = userFuncObj(sol::as_args(arguments));
|
||||
(void)results; // TODO: try to avoid use of useless sol::function_result here
|
||||
@ -99,11 +92,9 @@ void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string s
|
||||
threadData->results.emplace_back(std::move(store));
|
||||
}
|
||||
threadData->status = ThreadStatus::Completed;
|
||||
}
|
||||
catch (const LuaHookStopException&) {
|
||||
} catch (const LuaHookStopException&) {
|
||||
threadData->status = ThreadStatus::Canceled;
|
||||
}
|
||||
catch (const sol::error& err) {
|
||||
} catch (const sol::error& err) {
|
||||
threadData->status = ThreadStatus::Failed;
|
||||
sol::stack::push(threadData->luaState, err.what());
|
||||
StoredObject store = createStoredObject(sol::stack::pop<sol::object>(threadData->luaState));
|
||||
@ -111,23 +102,13 @@ void LuaThread::work(std::shared_ptr<ThreadData> threadData, const std::string s
|
||||
}
|
||||
}
|
||||
|
||||
void LuaThread::cancel()
|
||||
{
|
||||
pThreadData_->command = ThreadCommand::Cancel;
|
||||
}
|
||||
void LuaThread::cancel() { pThreadData_->command = ThreadCommand::Cancel; }
|
||||
|
||||
void LuaThread::pause()
|
||||
{
|
||||
pThreadData_->command = ThreadCommand::Pause;
|
||||
}
|
||||
void LuaThread::pause() { pThreadData_->command = ThreadCommand::Pause; }
|
||||
|
||||
void LuaThread::resume()
|
||||
{
|
||||
pThreadData_->command = ThreadCommand::Resume;
|
||||
}
|
||||
void LuaThread::resume() { pThreadData_->command = ThreadCommand::Resume; }
|
||||
|
||||
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
|
||||
{
|
||||
std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const {
|
||||
|
||||
ThreadStatus stat = pThreadData_->status;
|
||||
while (stat == ThreadStatus::Running) {
|
||||
@ -135,52 +116,49 @@ std::tuple<sol::object, sol::table> LuaThread::wait(sol::this_state state) const
|
||||
stat = pThreadData_->status;
|
||||
}
|
||||
sol::table returns = sol::state_view(state).create_table();
|
||||
if (stat == ThreadStatus::Completed)
|
||||
{
|
||||
for (const StoredObject& obj: pThreadData_->results)
|
||||
{
|
||||
if (stat == ThreadStatus::Completed) {
|
||||
for (const StoredObject& obj : pThreadData_->results) {
|
||||
returns.add(obj->unpack(state));
|
||||
}
|
||||
}
|
||||
return std::make_tuple(sol::make_object(state, threadStatusToString(stat)), std::move(returns));
|
||||
}
|
||||
|
||||
std::string LuaThread::threadStatusToString(ThreadStatus stat) const
|
||||
{
|
||||
switch(stat)
|
||||
{
|
||||
case ThreadStatus::Running: return "running";
|
||||
case ThreadStatus::Paused: return "paused";
|
||||
case ThreadStatus::Canceled: return "canceled";
|
||||
case ThreadStatus::Completed: return "completed";
|
||||
case ThreadStatus::Failed: return "failed";
|
||||
std::string LuaThread::threadStatusToString(ThreadStatus stat) const {
|
||||
switch (stat) {
|
||||
case ThreadStatus::Running:
|
||||
return "running";
|
||||
case ThreadStatus::Paused:
|
||||
return "paused";
|
||||
case ThreadStatus::Canceled:
|
||||
return "canceled";
|
||||
case ThreadStatus::Completed:
|
||||
return "completed";
|
||||
case ThreadStatus::Failed:
|
||||
return "failed";
|
||||
}
|
||||
assert(false);
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
std::string LuaThread::status() const
|
||||
{
|
||||
return threadStatusToString(pThreadData_->status);
|
||||
}
|
||||
std::string LuaThread::status() const { return threadStatusToString(pThreadData_->status); }
|
||||
|
||||
sol::object LuaThread::getUserType(sol::state_view &lua)
|
||||
{
|
||||
static sol::usertype<LuaThread> type(
|
||||
"new", sol::no_constructor, //
|
||||
sol::object LuaThread::getUserType(sol::state_view& lua) {
|
||||
static sol::usertype<LuaThread> type("new", sol::no_constructor, //
|
||||
"cancel", &LuaThread::cancel, //
|
||||
"pause", &LuaThread::pause, //
|
||||
"resume", &LuaThread::resume, //
|
||||
"status", &LuaThread::status, //
|
||||
"wait", &LuaThread::wait
|
||||
);
|
||||
"wait", &LuaThread::wait);
|
||||
sol::stack::push(lua, type);
|
||||
return sol::stack::pop<sol::object>(lua);
|
||||
}
|
||||
|
||||
// class ThreadFactory
|
||||
|
||||
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());
|
||||
const sol::object& dumper = lua["string"]["dump"];
|
||||
REQUIRE(dumper.valid() && dumper.get_type() == sol::type::function) << "Unable to get string.dump()";
|
||||
@ -194,10 +172,8 @@ ThreadFactory::ThreadFactory(const sol::function& func) : stepwise_(false), step
|
||||
std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& args) {
|
||||
std::shared_ptr<LuaThread::ThreadData> threadData = std::make_shared<LuaThread::ThreadData>();
|
||||
assert(threadData.get());
|
||||
threadData->luaState.open_libraries(
|
||||
sol::lib::base, sol::lib::string,
|
||||
sol::lib::package, sol::lib::io, sol::lib::os
|
||||
);
|
||||
threadData->luaState.open_libraries(sol::lib::base, sol::lib::string, sol::lib::package, sol::lib::io,
|
||||
sol::lib::os);
|
||||
|
||||
if (stepwise_)
|
||||
lua_sethook(threadData->luaState, LuaThread::luaHook, LUA_MASKCOUNT, step_);
|
||||
@ -213,42 +189,36 @@ std::unique_ptr<LuaThread> ThreadFactory::runThread(const sol::variadic_args& ar
|
||||
return std::make_unique<LuaThread>(threadData, strFunction_, args);
|
||||
}
|
||||
|
||||
bool ThreadFactory::stepwise(const sol::optional<bool>& value)
|
||||
{
|
||||
bool ThreadFactory::stepwise(const sol::optional<bool>& value) {
|
||||
bool ret = stepwise_;
|
||||
if (value)
|
||||
stepwise_ = value.value();
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned int ThreadFactory::step(const sol::optional<unsigned int>& value)
|
||||
{
|
||||
unsigned int ThreadFactory::step(const sol::optional<unsigned int>& value) {
|
||||
bool ret = step_;
|
||||
if (value)
|
||||
step_ = value.value();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string ThreadFactory::packagePath(const sol::optional<std::string>& value)
|
||||
{
|
||||
std::string ThreadFactory::packagePath(const sol::optional<std::string>& value) {
|
||||
std::string& ret = packagePath_;
|
||||
if (value)
|
||||
packagePath_ = value.value();
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::string ThreadFactory::packageCPath(const sol::optional<std::string>& value)
|
||||
{
|
||||
std::string ThreadFactory::packageCPath(const sol::optional<std::string>& value) {
|
||||
std::string& ret = packageCPath_;
|
||||
if (value)
|
||||
packageCPath_ = value.value();
|
||||
return ret;
|
||||
}
|
||||
|
||||
sol::object ThreadFactory::getUserType(sol::state_view &lua)
|
||||
{
|
||||
static sol::usertype<ThreadFactory> type(
|
||||
"new", sol::no_constructor, //
|
||||
sol::object ThreadFactory::getUserType(sol::state_view& lua) {
|
||||
static sol::usertype<ThreadFactory> type("new", sol::no_constructor, //
|
||||
sol::meta_function::call, &ThreadFactory::runThread, //
|
||||
"stepwise", &ThreadFactory::stepwise, //
|
||||
"step", &ThreadFactory::step, //
|
||||
|
||||
@ -23,8 +23,7 @@ public:
|
||||
Failed,
|
||||
};
|
||||
|
||||
enum class ThreadCommand
|
||||
{
|
||||
enum class ThreadCommand {
|
||||
Nothing = 1,
|
||||
Cancel,
|
||||
Pause,
|
||||
@ -54,7 +53,8 @@ private:
|
||||
LuaThread& operator=(const LuaThread&) = delete;
|
||||
|
||||
std::string threadStatusToString(ThreadStatus stat) const;
|
||||
static void work(std::shared_ptr<ThreadData> threadData, const std::string strFunction, std::vector<sol::object>&& arguments);
|
||||
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<std::thread> pThread_;
|
||||
|
||||
@ -9,7 +9,8 @@ namespace effil {
|
||||
|
||||
class Exception : public sol::error {
|
||||
public:
|
||||
Exception() noexcept : sol::error("") {}
|
||||
Exception() noexcept
|
||||
: sol::error("") {}
|
||||
|
||||
template <typename T>
|
||||
Exception& operator<<(const T& value) {
|
||||
@ -19,9 +20,7 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
virtual const char* what() const noexcept override {
|
||||
return message_.c_str();
|
||||
}
|
||||
virtual const char* what() const noexcept override { return message_.c_str(); }
|
||||
|
||||
private:
|
||||
std::string message_;
|
||||
@ -29,10 +28,14 @@ private:
|
||||
|
||||
} // effil
|
||||
|
||||
#define REQUIRE(cond) if (!cond) throw effil::Exception()
|
||||
#define REQUIRE(cond) \
|
||||
if (!cond) \
|
||||
throw effil::Exception()
|
||||
|
||||
#ifdef NDEBUG
|
||||
# define DEBUG if (false) std::cout
|
||||
#define DEBUG \
|
||||
if (false) \
|
||||
std::cout
|
||||
#else
|
||||
#define DEBUG std::cout
|
||||
#endif
|
||||
|
||||
@ -29,8 +29,10 @@ TEST(gc, collect) {
|
||||
ASSERT_EQ(getGC().size(), (size_t)0);
|
||||
|
||||
{
|
||||
GCObject o1 = getGC().create<GCObject>();;
|
||||
GCObject o2 = getGC().create<GCObject>();;
|
||||
GCObject o1 = getGC().create<GCObject>();
|
||||
;
|
||||
GCObject o2 = getGC().create<GCObject>();
|
||||
;
|
||||
}
|
||||
EXPECT_EQ(getGC().size(), (size_t)2);
|
||||
getGC().cleanup();
|
||||
@ -42,7 +44,6 @@ namespace {
|
||||
struct Dummy : public GCObject {
|
||||
void add(GCObjectHandle ref) { refs_->insert(ref); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
TEST(gc, withRefs) {
|
||||
@ -75,7 +76,8 @@ TEST(gc, autoCleanup) {
|
||||
getGC().create<GCObject>();
|
||||
});
|
||||
|
||||
for(auto& thread : threads) thread.join();
|
||||
for (auto& thread : threads)
|
||||
thread.join();
|
||||
|
||||
EXPECT_LT(getGC().size(), getGC().step());
|
||||
}
|
||||
|
||||
@ -82,7 +82,8 @@ TEST(sharedTable, multipleThreads) {
|
||||
|
||||
threads.emplace_back([=]() {
|
||||
sol::state lua;
|
||||
bootstrapState(lua);;
|
||||
bootstrapState(lua);
|
||||
;
|
||||
lua["st"] = st;
|
||||
lua.script(R"(
|
||||
while not st.ready do end
|
||||
@ -112,7 +113,9 @@ st.thr = true)");
|
||||
lua["st"] = st;
|
||||
lua.script("st.ready = true");
|
||||
|
||||
for(auto& thread : threads) { thread.join(); }
|
||||
for (auto& thread : threads) {
|
||||
thread.join();
|
||||
}
|
||||
|
||||
EXPECT_EQ(lua["st"]["fst"], true);
|
||||
EXPECT_EQ(lua["st"]["snd"], true);
|
||||
@ -243,7 +246,8 @@ TEST(sharedTable, stressWithThreads) {
|
||||
std::stringstream ss;
|
||||
ss << "st[" << i << "] = 1" << std::endl;
|
||||
ss << "for i = 1, 100000 do" << std::endl;
|
||||
ss << " st[" << i << "] = " << "st[" << i << "] + 1" << std::endl;
|
||||
ss << " st[" << i << "] = "
|
||||
<< "st[" << i << "] + 1" << std::endl;
|
||||
ss << "end" << std::endl;
|
||||
lua.script(ss.str());
|
||||
});
|
||||
|
||||
@ -6,11 +6,7 @@
|
||||
namespace effil {
|
||||
|
||||
inline void bootstrapState(sol::state& lua) {
|
||||
lua.open_libraries(
|
||||
sol::lib::base,
|
||||
sol::lib::string,
|
||||
sol::lib::table
|
||||
);
|
||||
lua.open_libraries(sol::lib::base, sol::lib::string, sol::lib::table);
|
||||
SharedTable::getUserType(lua);
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user