summaryrefslogtreecommitdiff
path: root/library/include
diff options
context:
space:
mode:
authorAlexander Gavrilov2012-08-23 19:27:12 +0400
committerAlexander Gavrilov2012-08-23 19:27:28 +0400
commitc6c5ad56c9b4421e1bf8a5bc2f38323734a9d2eb (patch)
treed81ff429044aa2cfd70f901c615c64db48f5ad3e /library/include
parent7046a6abbc157dd0102189e7dd6769183196766f (diff)
downloaddfhack-c6c5ad56c9b4421e1bf8a5bc2f38323734a9d2eb.tar.gz
dfhack-c6c5ad56c9b4421e1bf8a5bc2f38323734a9d2eb.tar.bz2
dfhack-c6c5ad56c9b4421e1bf8a5bc2f38323734a9d2eb.tar.xz
Track lua event listener count, and let the C++ host know.
This allows completely avoiding the call overhead if there are none. The downside is that the event object now has to be a userdata with lots of metamethods.
Diffstat (limited to 'library/include')
-rw-r--r--library/include/LuaTools.h37
-rw-r--r--library/include/PluginManager.h21
2 files changed, 29 insertions, 29 deletions
diff --git a/library/include/LuaTools.h b/library/include/LuaTools.h
index 897e7032..6b1afb88 100644
--- a/library/include/LuaTools.h
+++ b/library/include/LuaTools.h
@@ -310,9 +310,18 @@ namespace DFHack {namespace Lua {
DFHACK_EXPORT bool IsCoreContext(lua_State *state);
- DFHACK_EXPORT int NewEvent(lua_State *state);
- DFHACK_EXPORT void MakeEvent(lua_State *state, void *key);
- DFHACK_EXPORT void InvokeEvent(color_ostream &out, lua_State *state, void *key, int num_args);
+ namespace Event {
+ struct DFHACK_EXPORT Owner {
+ virtual ~Owner() {}
+ virtual void on_count_changed(int new_cnt, int delta) {}
+ virtual void on_invoked(lua_State *state, int nargs, bool from_c) {}
+ };
+
+ DFHACK_EXPORT void New(lua_State *state, Owner *owner = NULL);
+ DFHACK_EXPORT void Make(lua_State *state, void *key, Owner *owner = NULL);
+ DFHACK_EXPORT void SetPrivateCallback(lua_State *state, int ev_idx);
+ DFHACK_EXPORT void Invoke(color_ostream &out, lua_State *state, void *key, int num_args);
+ }
class StackUnwinder {
lua_State *state;
@@ -365,18 +374,24 @@ namespace DFHack {namespace Lua {
}
}
- class DFHACK_EXPORT Notification {
+ class DFHACK_EXPORT Notification : public Event::Owner {
lua_State *state;
void *key;
function_identity_base *handler;
+ int count;
public:
Notification(function_identity_base *handler = NULL)
- : state(NULL), key(NULL), handler(handler) {}
+ : state(NULL), key(NULL), handler(handler), count(0) {}
+ int get_listener_count() { return count; }
lua_State *get_state() { return state; }
function_identity_base *get_handler() { return handler; }
+ lua_State *state_if_count() { return (count > 0) ? state : NULL; }
+
+ void on_count_changed(int new_cnt, int) { count = new_cnt; }
+
void invoke(color_ostream &out, int nargs);
void bind(lua_State *state, const char *name);
@@ -388,7 +403,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out) { \
handler(out); \
- if (name##_event.get_state()) { \
+ if (name##_event.state_if_count()) { \
name##_event.invoke(out, 0); \
} \
}
@@ -397,7 +412,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1) { \
handler(out, arg1); \
- if (auto state = name##_event.get_state()) { \
+ if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
name##_event.invoke(out, 1); \
} \
@@ -407,7 +422,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2) { \
handler(out, arg1, arg2); \
- if (auto state = name##_event.get_state()) { \
+ if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
DFHack::Lua::Push(state, arg2); \
name##_event.invoke(out, 2); \
@@ -418,7 +433,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2, arg_type3 arg3) { \
handler(out, arg1, arg2, arg3); \
- if (auto state = name##_event.get_state()) { \
+ if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
DFHack::Lua::Push(state, arg2); \
DFHack::Lua::Push(state, arg3); \
@@ -430,7 +445,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2, arg_type3 arg3, arg_type4 arg4) { \
handler(out, arg1, arg2, arg3, arg4); \
- if (auto state = name##_event.get_state()) { \
+ if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
DFHack::Lua::Push(state, arg2); \
DFHack::Lua::Push(state, arg3); \
@@ -443,7 +458,7 @@ namespace DFHack {namespace Lua {
static DFHack::Lua::Notification name##_event(df::wrap_function(handler, true)); \
void name(color_ostream &out, arg_type1 arg1, arg_type2 arg2, arg_type3 arg3, arg_type4 arg4, arg_type5 arg5) { \
handler(out, arg1, arg2, arg3, arg4, arg5); \
- if (auto state = name##_event.get_state()) { \
+ if (auto state = name##_event.state_if_count()) { \
DFHack::Lua::Push(state, arg1); \
DFHack::Lua::Push(state, arg2); \
DFHack::Lua::Push(state, arg3); \
diff --git a/library/include/PluginManager.h b/library/include/PluginManager.h
index 22171a15..25b05ad4 100644
--- a/library/include/PluginManager.h
+++ b/library/include/PluginManager.h
@@ -173,31 +173,16 @@ namespace DFHack
PluginManager * parent;
plugin_state state;
- struct LuaCommand {
- Plugin *owner;
- std::string name;
- int (*command)(lua_State *state);
- LuaCommand(Plugin *owner, std::string name) : owner(owner), name(name) {}
- };
+ struct LuaCommand;
std::map<std::string, LuaCommand*> lua_commands;
static int lua_cmd_wrapper(lua_State *state);
- struct LuaFunction {
- Plugin *owner;
- std::string name;
- function_identity_base *identity;
- LuaFunction(Plugin *owner, std::string name) : owner(owner), name(name) {}
- };
+ struct LuaFunction;
std::map<std::string, LuaFunction*> lua_functions;
static int lua_fun_wrapper(lua_State *state);
void push_function(lua_State *state, LuaFunction *fn);
- struct LuaEvent {
- LuaFunction handler;
- Lua::Notification *event;
- bool active;
- LuaEvent(Plugin *owner, std::string name) : handler(owner,name), active(false) {}
- };
+ struct LuaEvent;
std::map<std::string, LuaEvent*> lua_events;
void index_lua(DFLibrary *lib);