summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--source/ManualBindings.cpp65
-rw-r--r--source/PluginLua.h37
-rw-r--r--source/World.cpp2
-rw-r--r--source/World.h4
4 files changed, 105 insertions, 3 deletions
diff --git a/source/ManualBindings.cpp b/source/ManualBindings.cpp
index a2b4c8810..4242db46a 100644
--- a/source/ManualBindings.cpp
+++ b/source/ManualBindings.cpp
@@ -896,6 +896,70 @@ tolua_lerror:
+class cLuaWorldTask :
+ public cWorld::cTask
+{
+public:
+ cLuaWorldTask(cPluginLua & a_Plugin, int a_FnRef) :
+ m_Plugin(a_Plugin),
+ m_FnRef(a_FnRef)
+ {
+ }
+
+protected:
+ cPluginLua & m_Plugin;
+ int m_FnRef;
+
+ // cWorld::cTask overrides:
+ virtual void Run(cWorld & a_World) override
+ {
+ m_Plugin.Call(m_FnRef, &a_World);
+ }
+} ;
+
+
+
+
+
+static int tolua_cWorld_QueueTask(lua_State * tolua_S)
+{
+ // Binding for cWorld::QueueTask
+ // Params: function
+
+ // Retrieve the cPlugin from the LuaState:
+ cPluginLua * Plugin = GetLuaPlugin(tolua_S);
+ if (Plugin == NULL)
+ {
+ // An error message has been already printed in GetLuaPlugin()
+ return 0;
+ }
+
+ // Retrieve the args:
+ cWorld * self = (cWorld *)tolua_tousertype(tolua_S, 1, 0);
+ if (self == NULL)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Not called on an object instance");
+ }
+ if (!lua_isfunction(tolua_S, 2))
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Expected a function for parameter #1");
+ }
+
+ // Create a reference to the function:
+ int FnRef = luaL_ref(tolua_S, LUA_REGISTRYINDEX);
+ if (FnRef == LUA_REFNIL)
+ {
+ return lua_do_error(tolua_S, "Error in function call '#funcname#': Could not get function reference of parameter #1");
+ }
+
+ self->QueueTask(new cLuaWorldTask(*Plugin, FnRef));
+ return 0;
+}
+
+
+
+
+
static int tolua_cPluginManager_GetAllPlugins(lua_State * tolua_S)
{
cPluginManager* self = (cPluginManager*) tolua_tousertype(tolua_S,1,0);
@@ -2032,6 +2096,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "ForEachPlayer", tolua_ForEach< cWorld, cPlayer, &cWorld::ForEachPlayer>);
tolua_function(tolua_S, "GetBlockInfo", tolua_cWorld_GetBlockInfo);
tolua_function(tolua_S, "GetBlockTypeMeta", tolua_cWorld_GetBlockTypeMeta);
+ tolua_function(tolua_S, "QueueTask", tolua_cWorld_QueueTask);
tolua_function(tolua_S, "SetSignLines", tolua_cWorld_SetSignLines);
tolua_function(tolua_S, "TryGetHeight", tolua_cWorld_TryGetHeight);
tolua_function(tolua_S, "UpdateSign", tolua_cWorld_SetSignLines);
diff --git a/source/PluginLua.h b/source/PluginLua.h
index fee9c4986..d5d202bf0 100644
--- a/source/PluginLua.h
+++ b/source/PluginLua.h
@@ -137,6 +137,43 @@ public:
Returns true if the hook was added successfully.
*/
bool AddHookRef(int a_HookType, int a_FnRefIdx);
+
+ // The following templates allow calls to arbitrary Lua functions residing in the plugin:
+
+ /// Call a Lua function with 0 args
+ template <typename FnT> bool Call(FnT a_Fn)
+ {
+ cCSLock Lock(m_CriticalSection);
+ return m_LuaState.Call(a_Fn);
+ }
+
+ /// Call a Lua function with 1 arg
+ template <typename FnT, typename ArgT0> bool Call(FnT a_Fn, ArgT0 a_Arg0)
+ {
+ cCSLock Lock(m_CriticalSection);
+ return m_LuaState.Call(a_Fn, a_Arg0);
+ }
+
+ /// Call a Lua function with 2 args
+ template <typename FnT, typename ArgT0, typename ArgT1> bool Call(FnT a_Fn, ArgT0 a_Arg0, ArgT1 a_Arg1)
+ {
+ cCSLock Lock(m_CriticalSection);
+ return m_LuaState.Call(a_Fn, a_Arg0, a_Arg1);
+ }
+
+ /// Call a Lua function with 3 args
+ template <typename FnT, typename ArgT0, typename ArgT1, typename ArgT2> bool Call(FnT a_Fn, ArgT0 a_Arg0, ArgT1 a_Arg1, ArgT2 a_Arg2)
+ {
+ cCSLock Lock(m_CriticalSection);
+ return m_LuaState.Call(a_Fn, a_Arg0, a_Arg1, a_Arg2);
+ }
+
+ /// Call a Lua function with 4 args
+ template <typename FnT, typename ArgT0, typename ArgT1, typename ArgT2, typename ArgT3> bool Call(FnT a_Fn, ArgT0 a_Arg0, ArgT1 a_Arg1, ArgT2 a_Arg2, ArgT3 a_ArgT3)
+ {
+ cCSLock Lock(m_CriticalSection);
+ return m_LuaState.Call(a_Fn, a_Arg0, a_Arg1, a_Arg2, a_Arg3);
+ }
protected:
/// Maps command name into Lua function reference
diff --git a/source/World.cpp b/source/World.cpp
index f4bde79bf..67b2738f0 100644
--- a/source/World.cpp
+++ b/source/World.cpp
@@ -869,7 +869,7 @@ void cWorld::TickQueuedTasks(void)
}
// Execute and delete each task:
- for (cTasks::iterator itr = m_Tasks.begin(), end = m_Tasks.end(); itr != end; ++itr)
+ for (cTasks::iterator itr = Tasks.begin(), end = Tasks.end(); itr != end; ++itr)
{
(*itr)->Run(*this);
delete *itr;
diff --git a/source/World.h b/source/World.h
index dcb197bd0..25bc0b338 100644
--- a/source/World.h
+++ b/source/World.h
@@ -508,7 +508,7 @@ public:
void QueueSaveAllChunks(void); // tolua_export
/// Queues a task onto the tick thread. The task object will be deleted once the task is finished
- void QueueTask(cTask * a_Task);
+ void QueueTask(cTask * a_Task); // Exported in ManualBindings.cpp
/// Returns the number of chunks loaded
int GetNumChunks() const; // tolua_export
@@ -589,7 +589,7 @@ public:
/// Appends all usernames starting with a_Text (case-insensitive) into Results
void TabCompleteUserName(const AString & a_Text, AStringVector & a_Results);
-
+
private:
friend class cRoot;