Lua.cpp: Get rid of register-queue
This commit is contained in:
parent
ba3446697e
commit
a77c6a4df6
4 changed files with 181 additions and 87 deletions
|
@ -387,25 +387,12 @@ public:
|
|||
/**
|
||||
* Enumerate all callbacks.
|
||||
*/
|
||||
std::list<callback_list*> get_callbacks()
|
||||
{
|
||||
if(master)
|
||||
return master->get_callbacks();
|
||||
std::list<callback_list*> r;
|
||||
for(auto i : callbacks)
|
||||
r.push_back(i.second);
|
||||
return r;
|
||||
}
|
||||
|
||||
void do_register(const std::string& name, callback_list& callback)
|
||||
{
|
||||
callbacks[name] = &callback;
|
||||
}
|
||||
|
||||
void do_unregister(const std::string& name, callback_list* dummy)
|
||||
{
|
||||
callbacks.erase(name);
|
||||
}
|
||||
std::list<callback_list*> get_callbacks();
|
||||
/**
|
||||
* Register/Unregister a callback list.
|
||||
*/
|
||||
void do_register(const std::string& name, callback_list& callback);
|
||||
void do_unregister(const std::string& name, callback_list& callback);
|
||||
|
||||
//All kinds of Lua API functions.
|
||||
void pop(int n) { lua_pop(lua_handle, n); }
|
||||
|
@ -466,9 +453,6 @@ private:
|
|||
void (*oom_handler)();
|
||||
state* master;
|
||||
lua_State* lua_handle;
|
||||
std::set<std::pair<function_group*, int>> function_groups;
|
||||
std::set<std::pair<class_group*, int>> class_groups;
|
||||
std::map<std::string, callback_list*> callbacks;
|
||||
state(state&);
|
||||
state& operator=(state&);
|
||||
};
|
||||
|
|
|
@ -30,7 +30,7 @@ public:
|
|||
/**
|
||||
* Drop a class from group.
|
||||
*/
|
||||
void do_unregister(const std::string& name, class_base* dummy);
|
||||
void do_unregister(const std::string& name, class_base& fun);
|
||||
/**
|
||||
* Request callbacks on all currently registered functions.
|
||||
*/
|
||||
|
@ -47,10 +47,7 @@ public:
|
|||
*/
|
||||
void drop_callback(int handle);
|
||||
private:
|
||||
int next_handle;
|
||||
std::map<std::string, class_base*> classes;
|
||||
std::map<int, std::function<void(std::string, class_base*)>> callbacks;
|
||||
std::map<int, std::function<void(class_group*)>> dcallbacks;
|
||||
char dummy;
|
||||
};
|
||||
|
||||
struct class_ops
|
||||
|
|
|
@ -27,7 +27,7 @@ public:
|
|||
/**
|
||||
* Drop a function from group.
|
||||
*/
|
||||
void do_unregister(const std::string& name, function* dummy);
|
||||
void do_unregister(const std::string& name, function& dummy);
|
||||
/**
|
||||
* Request callbacks on all currently registered functions.
|
||||
*/
|
||||
|
@ -44,10 +44,7 @@ public:
|
|||
*/
|
||||
void drop_callback(int handle);
|
||||
private:
|
||||
int next_handle;
|
||||
std::map<std::string, function*> functions;
|
||||
std::map<int, std::function<void(std::string, function*)>> callbacks;
|
||||
std::map<int, std::function<void(function_group*)>> dcallbacks;
|
||||
char dummy;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,12 +3,58 @@
|
|||
#include "lua-function.hpp"
|
||||
#include "lua-params.hpp"
|
||||
#include "lua-pin.hpp"
|
||||
#include "register-queue.hpp"
|
||||
#include "stateobject.hpp"
|
||||
#include "threads.hpp"
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
namespace lua
|
||||
{
|
||||
namespace
|
||||
{
|
||||
threads::rlock* global_lock;
|
||||
threads::rlock& get_lua_lock()
|
||||
{
|
||||
if(!global_lock) global_lock = new threads::rlock;
|
||||
return *global_lock;
|
||||
}
|
||||
|
||||
struct state_internal
|
||||
{
|
||||
std::map<std::string, state::callback_list*> callbacks;
|
||||
std::set<std::pair<function_group*, int>> function_groups;
|
||||
std::set<std::pair<class_group*, int>> class_groups;
|
||||
};
|
||||
|
||||
struct fgroup_internal
|
||||
{
|
||||
fgroup_internal()
|
||||
{
|
||||
next_handle = 0;
|
||||
}
|
||||
std::map<std::string, function*> functions;
|
||||
int next_handle;
|
||||
std::map<int, std::function<void(std::string, function*)>> callbacks;
|
||||
std::map<int, std::function<void(function_group*)>> dcallbacks;
|
||||
};
|
||||
|
||||
struct cgroup_internal
|
||||
{
|
||||
cgroup_internal()
|
||||
{
|
||||
next_handle = 0;
|
||||
}
|
||||
int next_handle;
|
||||
std::map<std::string, class_base*> classes;
|
||||
std::map<int, std::function<void(std::string, class_base*)>> callbacks;
|
||||
std::map<int, std::function<void(class_group*)>> dcallbacks;
|
||||
};
|
||||
|
||||
typedef stateobject::type<state, state_internal> state_internal_t;
|
||||
typedef stateobject::type<function_group, fgroup_internal> fgroup_internal_t;
|
||||
typedef stateobject::type<class_group, cgroup_internal> cgroup_internal_t;
|
||||
}
|
||||
|
||||
std::unordered_map<std::type_index, void*>& class_types()
|
||||
{
|
||||
static std::unordered_map<std::type_index, void*> x;
|
||||
|
@ -254,11 +300,6 @@ namespace
|
|||
{
|
||||
fun->register_state(L);
|
||||
}
|
||||
|
||||
typedef register_queue<state, function> regqueue_t;
|
||||
typedef register_queue<state, state::callback_list> regqueue2_t;
|
||||
typedef register_queue<function_group, function> regqueue3_t;
|
||||
typedef register_queue<class_group, class_base> regqueue4_t;
|
||||
}
|
||||
|
||||
state::state() throw(std::bad_alloc)
|
||||
|
@ -266,7 +307,6 @@ state::state() throw(std::bad_alloc)
|
|||
master = NULL;
|
||||
lua_handle = NULL;
|
||||
oom_handler = builtin_oom;
|
||||
regqueue2_t::do_ready(*this, true);
|
||||
}
|
||||
|
||||
state::state(state& _master, lua_State* L)
|
||||
|
@ -279,13 +319,16 @@ state::~state() throw()
|
|||
{
|
||||
if(master)
|
||||
return;
|
||||
for(auto i : function_groups)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i : state->function_groups)
|
||||
i.first->drop_callback(i.second);
|
||||
for(auto i : class_groups)
|
||||
for(auto i : state->class_groups)
|
||||
i.first->drop_callback(i.second);
|
||||
regqueue2_t::do_ready(*this, false);
|
||||
if(lua_handle)
|
||||
lua_close(lua_handle);
|
||||
state_internal_t::clear(this);
|
||||
}
|
||||
|
||||
void state::builtin_oom()
|
||||
|
@ -310,12 +353,12 @@ void* state::builtin_alloc(void* user, void* old, size_t olds, size_t news)
|
|||
function::function(function_group& _group, const std::string& func) throw(std::bad_alloc)
|
||||
: group(_group)
|
||||
{
|
||||
regqueue3_t::do_register(group, fname = func, *this);
|
||||
group.do_register(fname = func, *this);
|
||||
}
|
||||
|
||||
function::~function() throw()
|
||||
{
|
||||
regqueue3_t::do_unregister(group, fname);
|
||||
group.do_unregister(fname, *this);
|
||||
}
|
||||
|
||||
class_base::class_base(class_group& _group, const std::string& _name)
|
||||
|
@ -327,19 +370,22 @@ class_base::class_base(class_group& _group, const std::string& _name)
|
|||
class_base::~class_base() throw()
|
||||
{
|
||||
if(registered)
|
||||
regqueue4_t::do_unregister(group, name);
|
||||
group.do_unregister(name, *this);
|
||||
}
|
||||
|
||||
void state::reset() throw(std::bad_alloc, std::runtime_error)
|
||||
{
|
||||
if(master)
|
||||
return master->reset();
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
if(lua_handle) {
|
||||
lua_State* tmp = lua_newstate(state::builtin_alloc, this);
|
||||
if(!tmp)
|
||||
throw std::runtime_error("Can't re-initialize Lua interpretter");
|
||||
lua_close(lua_handle);
|
||||
for(auto& i : callbacks)
|
||||
for(auto& i : state->callbacks)
|
||||
i.second->clear();
|
||||
lua_handle = tmp;
|
||||
} else {
|
||||
|
@ -348,11 +394,11 @@ void state::reset() throw(std::bad_alloc, std::runtime_error)
|
|||
if(!lua_handle)
|
||||
throw std::runtime_error("Can't initialize Lua interpretter");
|
||||
}
|
||||
for(auto i : function_groups)
|
||||
for(auto i : state->function_groups)
|
||||
i.first->request_callback([this](std::string name, function* func) -> void {
|
||||
register_function(*this, name, func);
|
||||
});
|
||||
for(auto i : class_groups)
|
||||
for(auto i : state->class_groups)
|
||||
i.first->request_callback([this](std::string name, class_base* clazz) -> void {
|
||||
register_class(*this, name, clazz);
|
||||
});
|
||||
|
@ -369,13 +415,18 @@ void state::deinit() throw()
|
|||
|
||||
void state::add_function_group(function_group& group)
|
||||
{
|
||||
function_groups.insert(std::make_pair(&group, group.add_callback([this](const std::string& name,
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = state_internal_t::get(this);
|
||||
state.function_groups.insert(std::make_pair(&group, group.add_callback([this](const std::string& name,
|
||||
function* func) -> void {
|
||||
this->function_callback(name, func);
|
||||
}, [this](function_group* x) {
|
||||
for(auto i = this->function_groups.begin(); i != this->function_groups.end();)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i = state->function_groups.begin(); i != state->function_groups.end();)
|
||||
if(i->first == x)
|
||||
i = this->function_groups.erase(i);
|
||||
i = state->function_groups.erase(i);
|
||||
else
|
||||
i++;
|
||||
})));
|
||||
|
@ -383,13 +434,18 @@ void state::add_function_group(function_group& group)
|
|||
|
||||
void state::add_class_group(class_group& group)
|
||||
{
|
||||
class_groups.insert(std::make_pair(&group, group.add_callback([this](const std::string& name,
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = state_internal_t::get(this);
|
||||
state.class_groups.insert(std::make_pair(&group, group.add_callback([this](const std::string& name,
|
||||
class_base* clazz) -> void {
|
||||
this->class_callback(name, clazz);
|
||||
}, [this](class_group* x) {
|
||||
for(auto i = this->class_groups.begin(); i != this->class_groups.end();)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i = state->class_groups.begin(); i != state->class_groups.end();)
|
||||
if(i->first == x)
|
||||
i = this->class_groups.erase(i);
|
||||
i = state->class_groups.erase(i);
|
||||
else
|
||||
i++;
|
||||
})));
|
||||
|
@ -429,15 +485,44 @@ bool state::do_once(void* key)
|
|||
}
|
||||
}
|
||||
|
||||
std::list<state::callback_list*> state::get_callbacks()
|
||||
{
|
||||
if(master)
|
||||
return master->get_callbacks();
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
std::list<callback_list*> r;
|
||||
if(state)
|
||||
for(auto i : state->callbacks)
|
||||
r.push_back(i.second);
|
||||
return r;
|
||||
}
|
||||
|
||||
void state::do_register(const std::string& name, callback_list& callback)
|
||||
{
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = state_internal_t::get(this);
|
||||
if(state.callbacks.count(name)) return;
|
||||
state.callbacks[name] = &callback;
|
||||
}
|
||||
|
||||
void state::do_unregister(const std::string& name, callback_list& callback)
|
||||
{
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = state_internal_t::get_soft(this);
|
||||
if(state && state->callbacks.count(name) && state->callbacks[name] == &callback)
|
||||
state->callbacks.erase(name);
|
||||
}
|
||||
|
||||
state::callback_list::callback_list(state& _L, const std::string& _name, const std::string& fncbname)
|
||||
: L(_L), name(_name), fn_cbname(fncbname)
|
||||
{
|
||||
regqueue2_t::do_register(L, name, *this);
|
||||
L.do_register(name, *this);
|
||||
}
|
||||
|
||||
state::callback_list::~callback_list()
|
||||
{
|
||||
regqueue2_t::do_unregister(L, name);
|
||||
L.do_unregister(name, *this);
|
||||
if(!L.handle())
|
||||
return;
|
||||
for(auto& i : callbacks) {
|
||||
|
@ -474,99 +559,130 @@ void state::callback_list::_unregister(state& _L)
|
|||
|
||||
function_group::function_group()
|
||||
{
|
||||
next_handle = 0;
|
||||
regqueue3_t::do_ready(*this, true);
|
||||
}
|
||||
|
||||
function_group::~function_group()
|
||||
{
|
||||
for(auto i : dcallbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = fgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i : state->dcallbacks)
|
||||
i.second(this);
|
||||
regqueue3_t::do_ready(*this, false);
|
||||
fgroup_internal_t::clear(this);
|
||||
}
|
||||
|
||||
void function_group::request_callback(std::function<void(std::string, function*)> cb)
|
||||
{
|
||||
for(auto i : functions)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = fgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i : state->functions)
|
||||
cb(i.first, i.second);
|
||||
}
|
||||
|
||||
int function_group::add_callback(std::function<void(std::string, function*)> cb,
|
||||
std::function<void(function_group*)> dcb)
|
||||
{
|
||||
int handle = next_handle++;
|
||||
callbacks[handle] = cb;
|
||||
dcallbacks[handle] = dcb;
|
||||
for(auto i : functions)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = fgroup_internal_t::get(this);
|
||||
int handle = state.next_handle++;
|
||||
state.callbacks[handle] = cb;
|
||||
state.dcallbacks[handle] = dcb;
|
||||
for(auto i : state.functions)
|
||||
cb(i.first, i.second);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void function_group::drop_callback(int handle)
|
||||
{
|
||||
callbacks.erase(handle);
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = fgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
state->callbacks.erase(handle);
|
||||
}
|
||||
|
||||
void function_group::do_register(const std::string& name, function& fun)
|
||||
{
|
||||
functions[name] = &fun;
|
||||
for(auto i : callbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = fgroup_internal_t::get(this);
|
||||
if(state.functions.count(name)) return;
|
||||
state.functions[name] = &fun;
|
||||
for(auto i : state.callbacks)
|
||||
i.second(name, &fun);
|
||||
}
|
||||
|
||||
void function_group::do_unregister(const std::string& name, function* dummy)
|
||||
void function_group::do_unregister(const std::string& name, function& fun)
|
||||
{
|
||||
functions.erase(name);
|
||||
for(auto i : callbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = fgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
if(state && state->functions.count(name) && state->functions[name] == &fun)
|
||||
state->functions.erase(name);
|
||||
for(auto i : state->callbacks)
|
||||
i.second(name, NULL);
|
||||
}
|
||||
|
||||
class_group::class_group()
|
||||
{
|
||||
next_handle = 0;
|
||||
regqueue4_t::do_ready(*this, true);
|
||||
}
|
||||
|
||||
class_group::~class_group()
|
||||
{
|
||||
for(auto i : dcallbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = cgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i : state->dcallbacks)
|
||||
i.second(this);
|
||||
regqueue4_t::do_ready(*this, false);
|
||||
cgroup_internal_t::clear(this);
|
||||
}
|
||||
|
||||
void class_group::request_callback(std::function<void(std::string, class_base*)> cb)
|
||||
{
|
||||
for(auto i : classes)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = cgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
for(auto i : state->classes)
|
||||
cb(i.first, i.second);
|
||||
}
|
||||
|
||||
int class_group::add_callback(std::function<void(std::string, class_base*)> cb,
|
||||
std::function<void(class_group*)> dcb)
|
||||
{
|
||||
int handle = next_handle++;
|
||||
callbacks[handle] = cb;
|
||||
dcallbacks[handle] = dcb;
|
||||
for(auto i : classes)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = cgroup_internal_t::get(this);
|
||||
int handle = state.next_handle++;
|
||||
state.callbacks[handle] = cb;
|
||||
state.dcallbacks[handle] = dcb;
|
||||
for(auto i : state.classes)
|
||||
cb(i.first, i.second);
|
||||
return handle;
|
||||
}
|
||||
|
||||
void class_group::drop_callback(int handle)
|
||||
{
|
||||
callbacks.erase(handle);
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = cgroup_internal_t::get_soft(this);
|
||||
if(!state) return;
|
||||
state->callbacks.erase(handle);
|
||||
}
|
||||
|
||||
void class_group::do_register(const std::string& name, class_base& fun)
|
||||
{
|
||||
classes[name] = &fun;
|
||||
for(auto i : callbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto& state = cgroup_internal_t::get(this);
|
||||
if(state.classes.count(name)) return;
|
||||
state.classes[name] = &fun;
|
||||
for(auto i : state.callbacks)
|
||||
i.second(name, &fun);
|
||||
}
|
||||
|
||||
void class_group::do_unregister(const std::string& name, class_base* dummy)
|
||||
void class_group::do_unregister(const std::string& name, class_base& fun)
|
||||
{
|
||||
classes.erase(name);
|
||||
for(auto i : callbacks)
|
||||
threads::arlock h(get_lua_lock());
|
||||
auto state = cgroup_internal_t::get_soft(this);
|
||||
if(!state || !state->classes.count(name) || state->classes[name] != &fun) return;
|
||||
state->classes.erase(name);
|
||||
for(auto i : state->callbacks)
|
||||
i.second(name, NULL);
|
||||
}
|
||||
|
||||
|
@ -745,7 +861,7 @@ again2:
|
|||
|
||||
void class_base::delayed_register()
|
||||
{
|
||||
regqueue4_t::do_register(group, name, *this);
|
||||
group.do_register(name, *this);
|
||||
}
|
||||
|
||||
functions::functions(function_group& grp, const std::string& basetable, std::initializer_list<entry> fnlist)
|
||||
|
|
Loading…
Add table
Reference in a new issue