Implemented cPluginManager:CallPlugin() API.
This function supersedes cPlugin:Call(), is safer to use in regards to multithreading and once again removes the need for the cPlugin class being exported at all.
This commit is contained in:
+183
-16
@@ -235,7 +235,7 @@ bool cLuaState::PushFunction(const char * a_FunctionName)
|
||||
if (!lua_isfunction(m_LuaState, -1))
|
||||
{
|
||||
LOGWARNING("Error in %s: Could not find function %s()", m_SubsystemName.c_str(), a_FunctionName);
|
||||
lua_pop(m_LuaState, 1);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return false;
|
||||
}
|
||||
m_CurrentFunctionName.assign(a_FunctionName);
|
||||
@@ -258,7 +258,7 @@ bool cLuaState::PushFunction(int a_FnRef)
|
||||
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_FnRef); // same as lua_getref()
|
||||
if (!lua_isfunction(m_LuaState, -1))
|
||||
{
|
||||
lua_pop(m_LuaState, 1);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return false;
|
||||
}
|
||||
m_CurrentFunctionName = "<callback>";
|
||||
@@ -282,7 +282,7 @@ bool cLuaState::PushFunction(const cTableRef & a_TableRef)
|
||||
if (!lua_istable(m_LuaState, -1))
|
||||
{
|
||||
// Not a table, bail out
|
||||
lua_pop(m_LuaState, 1);
|
||||
lua_pop(m_LuaState, 2);
|
||||
return false;
|
||||
}
|
||||
lua_getfield(m_LuaState, -1, a_TableRef.GetFnName());
|
||||
@@ -742,6 +742,10 @@ bool cLuaState::CallFunction(int a_NumResults)
|
||||
}
|
||||
m_NumCurrentFunctionArgs = -1;
|
||||
m_CurrentFunctionName.clear();
|
||||
|
||||
// Remove the error handler from the stack:
|
||||
lua_remove(m_LuaState, -a_NumResults - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1025,21 +1029,184 @@ void cLuaState::LogStackTrace(lua_State * a_LuaState)
|
||||
|
||||
AString cLuaState::GetTypeText(int a_StackPos)
|
||||
{
|
||||
int Type = lua_type(m_LuaState, a_StackPos);
|
||||
switch (Type)
|
||||
return lua_typename(m_LuaState, lua_type(m_LuaState, a_StackPos));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cLuaState::CallFunctionWithForeignParams(
|
||||
const AString & a_FunctionName,
|
||||
cLuaState & a_SrcLuaState,
|
||||
int a_SrcParamStart,
|
||||
int a_SrcParamEnd
|
||||
)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
ASSERT(a_SrcLuaState.IsValid());
|
||||
|
||||
// Store the stack position before any changes
|
||||
int OldTop = lua_gettop(m_LuaState);
|
||||
|
||||
// Push the function to call, including the error handler:
|
||||
if (!PushFunction(a_FunctionName.c_str()))
|
||||
{
|
||||
case LUA_TNONE: return "TNONE";
|
||||
case LUA_TNIL: return "TNIL";
|
||||
case LUA_TBOOLEAN: return "TBOOLEAN";
|
||||
case LUA_TLIGHTUSERDATA: return "TLIGHTUSERDATA";
|
||||
case LUA_TNUMBER: return "TNUMBER";
|
||||
case LUA_TSTRING: return "TSTRING";
|
||||
case LUA_TTABLE: return "TTABLE";
|
||||
case LUA_TFUNCTION: return "TFUNCTION";
|
||||
case LUA_TUSERDATA: return "TUSERDATA";
|
||||
case LUA_TTHREAD: return "TTHREAD";
|
||||
LOGWARNING("Function '%s' not found", a_FunctionName.c_str());
|
||||
lua_pop(m_LuaState, 2);
|
||||
return -1;
|
||||
}
|
||||
return Printf("Unknown (%d)", Type);
|
||||
|
||||
// Copy the function parameters to the target state
|
||||
if (CopyStackFrom(a_SrcLuaState, a_SrcParamStart, a_SrcParamEnd) < 0)
|
||||
{
|
||||
// Something went wrong, fix the stack and exit
|
||||
lua_pop(m_LuaState, 2);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Call the function, with an error handler:
|
||||
int s = lua_pcall(m_LuaState, a_SrcParamEnd - a_SrcParamStart + 1, LUA_MULTRET, OldTop);
|
||||
if (ReportErrors(s))
|
||||
{
|
||||
LOGWARN("Error while calling function '%s' in '%s'", a_FunctionName.c_str(), m_SubsystemName.c_str());
|
||||
// Fix the stack.
|
||||
// We don't know how many values have been pushed, so just get rid of any that weren't there initially
|
||||
int CurTop = lua_gettop(m_LuaState);
|
||||
if (CurTop > OldTop)
|
||||
{
|
||||
lua_pop(m_LuaState, CurTop - OldTop);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Reset the internal checking mechanisms:
|
||||
m_NumCurrentFunctionArgs = -1;
|
||||
|
||||
// Remove the error handler from the stack:
|
||||
lua_remove(m_LuaState, OldTop + 1);
|
||||
|
||||
// Return the number of return values:
|
||||
return lua_gettop(m_LuaState) - OldTop;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int cLuaState::CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_SrcEnd)
|
||||
{
|
||||
/*
|
||||
// DEBUG:
|
||||
LOGD("Copying stack values from %d to %d", a_SrcStart, a_SrcEnd);
|
||||
a_SrcLuaState.LogStack("Src stack before copying:");
|
||||
LogStack("Dst stack before copying:");
|
||||
*/
|
||||
for (int i = a_SrcStart; i <= a_SrcEnd; ++i)
|
||||
{
|
||||
int t = lua_type(a_SrcLuaState, i);
|
||||
switch (t)
|
||||
{
|
||||
case LUA_TNIL:
|
||||
{
|
||||
lua_pushnil(m_LuaState);
|
||||
break;
|
||||
}
|
||||
case LUA_TSTRING:
|
||||
{
|
||||
AString s;
|
||||
a_SrcLuaState.ToString(i, s);
|
||||
Push(s);
|
||||
break;
|
||||
}
|
||||
case LUA_TBOOLEAN:
|
||||
{
|
||||
bool b = (tolua_toboolean(a_SrcLuaState, i, false) != 0);
|
||||
Push(b);
|
||||
break;
|
||||
}
|
||||
case LUA_TNUMBER:
|
||||
{
|
||||
lua_Number d = tolua_tonumber(a_SrcLuaState, i, 0);
|
||||
Push(d);
|
||||
break;
|
||||
}
|
||||
case LUA_TUSERDATA:
|
||||
{
|
||||
// Get the class name:
|
||||
const char * type = NULL;
|
||||
if (lua_getmetatable(a_SrcLuaState, i) == 0)
|
||||
{
|
||||
LOGWARNING("%s: Unknown class in pos %d, cannot copy.", __FUNCTION__, i);
|
||||
lua_pop(m_LuaState, i - a_SrcStart);
|
||||
return -1;
|
||||
}
|
||||
lua_rawget(a_SrcLuaState, LUA_REGISTRYINDEX); // Stack +1
|
||||
type = lua_tostring(a_SrcLuaState, -1);
|
||||
lua_pop(a_SrcLuaState, 1); // Stack -1
|
||||
|
||||
// Copy the value:
|
||||
void * ud = tolua_touserdata(a_SrcLuaState, i, NULL);
|
||||
tolua_pushusertype(m_LuaState, ud, type);
|
||||
}
|
||||
default:
|
||||
{
|
||||
LOGWARNING("%s: Unsupported value: '%s' at stack position %d. Can only copy numbers, strings, bools and classes!",
|
||||
__FUNCTION__, lua_typename(a_SrcLuaState, t), i
|
||||
);
|
||||
a_SrcLuaState.LogStack("Stack where copying failed:");
|
||||
lua_pop(m_LuaState, i - a_SrcStart);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return a_SrcEnd - a_SrcStart + 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::ToString(int a_StackPos, AString & a_String)
|
||||
{
|
||||
size_t len;
|
||||
const char * s = lua_tolstring(m_LuaState, a_StackPos, &len);
|
||||
if (s != NULL)
|
||||
{
|
||||
a_String.assign(s, len);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::LogStack(const char * a_Header)
|
||||
{
|
||||
LogStack(m_LuaState, a_Header);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::LogStack(lua_State * a_LuaState, const char * a_Header)
|
||||
{
|
||||
LOGD((a_Header != NULL) ? a_Header : "Lua C API Stack contents:");
|
||||
for (int i = lua_gettop(a_LuaState); i >= 0; i--)
|
||||
{
|
||||
AString Value;
|
||||
int Type = lua_type(a_LuaState, i);
|
||||
switch (Type)
|
||||
{
|
||||
case LUA_TBOOLEAN: Value.assign((lua_toboolean(a_LuaState, i) != 0) ? "true" : "false"); break;
|
||||
case LUA_TLIGHTUSERDATA: Printf(Value, "%p", lua_touserdata(a_LuaState, i)); break;
|
||||
case LUA_TNUMBER: Printf(Value, "%f", (double)lua_tonumber(a_LuaState, i)); break;
|
||||
case LUA_TSTRING: Printf(Value, "%s", lua_tostring(a_LuaState, i)); break;
|
||||
default: break;
|
||||
}
|
||||
LOGD(" Idx %d: type %d (%s) %s", i, Type, lua_typename(a_LuaState, Type), Value.c_str());
|
||||
} // for i - stack idx
|
||||
}
|
||||
|
||||
|
||||
|
||||
+85
-58
@@ -60,23 +60,23 @@ class cBlockEntity;
|
||||
|
||||
|
||||
|
||||
/// Encapsulates a Lua state and provides some syntactic sugar for common operations
|
||||
/** Encapsulates a Lua state and provides some syntactic sugar for common operations */
|
||||
class cLuaState
|
||||
{
|
||||
public:
|
||||
|
||||
/// Used for storing references to object in the global registry
|
||||
/** Used for storing references to object in the global registry */
|
||||
class cRef
|
||||
{
|
||||
public:
|
||||
/// Creates a reference in the specified LuaState for object at the specified StackPos
|
||||
/** Creates a reference in the specified LuaState for object at the specified StackPos */
|
||||
cRef(cLuaState & a_LuaState, int a_StackPos);
|
||||
~cRef();
|
||||
|
||||
/// Returns true if the reference is valid
|
||||
/** Returns true if the reference is valid */
|
||||
bool IsValid(void) const {return (m_Ref != LUA_REFNIL); }
|
||||
|
||||
/// Allows to use this class wherever an int (i. e. ref) is to be used
|
||||
/** Allows to use this class wherever an int (i. e. ref) is to be used */
|
||||
operator int(void) const { return m_Ref; }
|
||||
|
||||
protected:
|
||||
@@ -102,7 +102,7 @@ public:
|
||||
} ;
|
||||
|
||||
|
||||
/// A dummy class that's used only to delimit function args from return values for cLuaState::Call()
|
||||
/** A dummy class that's used only to delimit function args from return values for cLuaState::Call() */
|
||||
class cRet
|
||||
{
|
||||
} ;
|
||||
@@ -123,22 +123,22 @@ public:
|
||||
|
||||
~cLuaState();
|
||||
|
||||
/// Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions
|
||||
/** Allows this object to be used in the same way as a lua_State *, for example in the LuaLib functions */
|
||||
operator lua_State * (void) { return m_LuaState; }
|
||||
|
||||
/// Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor
|
||||
/** Creates the m_LuaState, if not closed already. This state will be automatically closed in the destructor */
|
||||
void Create(void);
|
||||
|
||||
/// Closes the m_LuaState, if not closed already
|
||||
/** Closes the m_LuaState, if not closed already */
|
||||
void Close(void);
|
||||
|
||||
/// Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor
|
||||
/** Attaches the specified state. Operations will be carried out on this state, but it will not be closed in the destructor */
|
||||
void Attach(lua_State * a_State);
|
||||
|
||||
/// Detaches a previously attached state.
|
||||
/** Detaches a previously attached state. */
|
||||
void Detach(void);
|
||||
|
||||
/// Returns true if the m_LuaState is valid
|
||||
/** Returns true if the m_LuaState is valid */
|
||||
bool IsValid(void) const { return (m_LuaState != NULL); }
|
||||
|
||||
/** Loads the specified file
|
||||
@@ -147,7 +147,7 @@ public:
|
||||
*/
|
||||
bool LoadFile(const AString & a_FileName);
|
||||
|
||||
/// Returns true if a_FunctionName is a valid Lua function that can be called
|
||||
/** Returns true if a_FunctionName is a valid Lua function that can be called */
|
||||
bool HasFunction(const char * a_FunctionName);
|
||||
|
||||
// Push a value onto the stack
|
||||
@@ -182,7 +182,7 @@ public:
|
||||
void Push(cHopperEntity * a_Hopper);
|
||||
void Push(cBlockEntity * a_BlockEntity);
|
||||
|
||||
/// Call any 0-param 0-return Lua function in a single line:
|
||||
/** Call any 0-param 0-return Lua function in a single line: */
|
||||
template <typename FnT>
|
||||
bool Call(FnT a_FnName)
|
||||
{
|
||||
@@ -193,7 +193,7 @@ public:
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/// Call any 1-param 0-return Lua function in a single line:
|
||||
/** Call any 1-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT,
|
||||
typename ArgT1
|
||||
@@ -208,7 +208,7 @@ public:
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/// Call any 2-param 0-return Lua function in a single line:
|
||||
/** Call any 2-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2
|
||||
>
|
||||
@@ -223,7 +223,7 @@ public:
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/// Call any 3-param 0-return Lua function in a single line:
|
||||
/** Call any 3-param 0-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3
|
||||
>
|
||||
@@ -239,7 +239,7 @@ public:
|
||||
return CallFunction(0);
|
||||
}
|
||||
|
||||
/// Call any 0-param 1-return Lua function in a single line:
|
||||
/** Call any 0-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename RetT1
|
||||
>
|
||||
@@ -259,12 +259,13 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 1-param 1-return Lua function in a single line:
|
||||
/** Call any 1-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename RetT1
|
||||
>
|
||||
bool Call(FnT a_FnName, ArgT1 a_Arg1, const cRet & a_Mark, RetT1 & a_Ret1)
|
||||
{
|
||||
int InitialTop = lua_gettop(m_LuaState);
|
||||
UNUSED(a_Mark);
|
||||
if (!PushFunction(a_FnName))
|
||||
{
|
||||
@@ -277,10 +278,11 @@ public:
|
||||
}
|
||||
GetReturn(-1, a_Ret1);
|
||||
lua_pop(m_LuaState, 1);
|
||||
ASSERT(InitialTop == lua_gettop(m_LuaState));
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 2-param 1-return Lua function in a single line:
|
||||
/** Call any 2-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename RetT1
|
||||
>
|
||||
@@ -302,7 +304,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 3-param 1-return Lua function in a single line:
|
||||
/** Call any 3-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename RetT1
|
||||
>
|
||||
@@ -325,7 +327,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 4-param 1-return Lua function in a single line:
|
||||
/** Call any 4-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename RetT1
|
||||
>
|
||||
@@ -349,7 +351,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 5-param 1-return Lua function in a single line:
|
||||
/** Call any 5-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename RetT1
|
||||
>
|
||||
@@ -374,7 +376,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 6-param 1-return Lua function in a single line:
|
||||
/** Call any 6-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename RetT1
|
||||
@@ -401,7 +403,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 7-param 1-return Lua function in a single line:
|
||||
/** Call any 7-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename RetT1
|
||||
@@ -429,7 +431,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 8-param 1-return Lua function in a single line:
|
||||
/** Call any 8-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename RetT1
|
||||
@@ -458,7 +460,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 9-param 1-return Lua function in a single line:
|
||||
/** Call any 9-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename ArgT9, typename RetT1
|
||||
@@ -488,7 +490,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 10-param 1-return Lua function in a single line:
|
||||
/** Call any 10-param 1-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5, typename ArgT6,
|
||||
typename ArgT7, typename ArgT8, typename ArgT9, typename ArgT10, typename RetT1
|
||||
@@ -519,7 +521,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 1-param 2-return Lua function in a single line:
|
||||
/** Call any 1-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename RetT1, typename RetT2
|
||||
>
|
||||
@@ -541,7 +543,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 2-param 2-return Lua function in a single line:
|
||||
/** Call any 2-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename RetT1, typename RetT2
|
||||
>
|
||||
@@ -564,7 +566,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 3-param 2-return Lua function in a single line:
|
||||
/** Call any 3-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3,
|
||||
typename RetT1, typename RetT2
|
||||
@@ -589,7 +591,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 4-param 2-return Lua function in a single line:
|
||||
/** Call any 4-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4,
|
||||
typename RetT1, typename RetT2
|
||||
@@ -615,7 +617,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 5-param 2-return Lua function in a single line:
|
||||
/** Call any 5-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename RetT1, typename RetT2
|
||||
@@ -642,7 +644,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 6-param 2-return Lua function in a single line:
|
||||
/** Call any 6-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6,
|
||||
@@ -671,7 +673,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 7-param 2-return Lua function in a single line:
|
||||
/** Call any 7-param 2-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7,
|
||||
@@ -701,7 +703,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 7-param 3-return Lua function in a single line:
|
||||
/** Call any 7-param 3-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7,
|
||||
@@ -732,7 +734,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 8-param 3-return Lua function in a single line:
|
||||
/** Call any 8-param 3-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7, typename ArgT8,
|
||||
@@ -764,7 +766,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
/// Call any 9-param 5-return Lua function in a single line:
|
||||
/** Call any 9-param 5-return Lua function in a single line: */
|
||||
template<
|
||||
typename FnT, typename ArgT1, typename ArgT2, typename ArgT3, typename ArgT4, typename ArgT5,
|
||||
typename ArgT6, typename ArgT7, typename ArgT8, typename ArgT9,
|
||||
@@ -800,46 +802,71 @@ public:
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions
|
||||
/** Returns true if the specified parameters on the stack are of the specified usertable type; also logs warning if not. Used for static functions */
|
||||
bool CheckParamUserTable(int a_StartParam, const char * a_UserTable, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not. Used for regular functions
|
||||
/** Returns true if the specified parameters on the stack are of the specified usertype; also logs warning if not. Used for regular functions */
|
||||
bool CheckParamUserType(int a_StartParam, const char * a_UserType, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameters on the stack are tables; also logs warning if not
|
||||
/** Returns true if the specified parameters on the stack are tables; also logs warning if not */
|
||||
bool CheckParamTable(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameters on the stack are numbers; also logs warning if not
|
||||
/** Returns true if the specified parameters on the stack are numbers; also logs warning if not */
|
||||
bool CheckParamNumber(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameters on the stack are strings; also logs warning if not
|
||||
/** Returns true if the specified parameters on the stack are strings; also logs warning if not */
|
||||
bool CheckParamString(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameters on the stack are functions; also logs warning if not
|
||||
/** Returns true if the specified parameters on the stack are functions; also logs warning if not */
|
||||
bool CheckParamFunction(int a_StartParam, int a_EndParam = -1);
|
||||
|
||||
/// Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters)
|
||||
/** Returns true if the specified parameter on the stack is nil (indicating an end-of-parameters) */
|
||||
bool CheckParamEnd(int a_Param);
|
||||
|
||||
/// If the status is nonzero, prints the text on the top of Lua stack and returns true
|
||||
/** If the status is nonzero, prints the text on the top of Lua stack and returns true */
|
||||
bool ReportErrors(int status);
|
||||
|
||||
/// If the status is nonzero, prints the text on the top of Lua stack and returns true
|
||||
/** If the status is nonzero, prints the text on the top of Lua stack and returns true */
|
||||
static bool ReportErrors(lua_State * a_LuaState, int status);
|
||||
|
||||
/// Logs all items in the current stack trace to the server console
|
||||
/** Logs all items in the current stack trace to the server console */
|
||||
void LogStackTrace(void);
|
||||
|
||||
/// Logs all items in the current stack trace to the server console
|
||||
/** Logs all items in the current stack trace to the server console */
|
||||
static void LogStackTrace(lua_State * a_LuaState);
|
||||
|
||||
/// Returns the type of the item on the specified position in the stack
|
||||
/** Returns the type of the item on the specified position in the stack */
|
||||
AString GetTypeText(int a_StackPos);
|
||||
|
||||
/** Calls the function specified by its name, with arguments copied off the foreign state.
|
||||
If successful, keeps the return values on the stack and returns their number.
|
||||
If unsuccessful, returns a negative number and keeps the stack position unchanged. */
|
||||
int CallFunctionWithForeignParams(
|
||||
const AString & a_FunctionName,
|
||||
cLuaState & a_SrcLuaState,
|
||||
int a_SrcParamStart,
|
||||
int a_SrcParamEnd
|
||||
);
|
||||
|
||||
/** Copies objects on the stack from the specified state.
|
||||
Only numbers, bools, strings and userdatas are copied.
|
||||
If successful, returns the number of objects copied.
|
||||
If failed, returns a negative number and rewinds the stack position. */
|
||||
int CopyStackFrom(cLuaState & a_SrcLuaState, int a_SrcStart, int a_SrcEnd);
|
||||
|
||||
/** Reads the value at the specified stack position as a string and sets it to a_String. */
|
||||
void ToString(int a_StackPos, AString & a_String);
|
||||
|
||||
/** Logs all the elements' types on the API stack, with an optional header for the listing. */
|
||||
void LogStack(const char * a_Header);
|
||||
|
||||
/** Logs all the elements' types on the API stack, with an optional header for the listing. */
|
||||
static void LogStack(lua_State * a_LuaState, const char * a_Header = NULL);
|
||||
|
||||
protected:
|
||||
lua_State * m_LuaState;
|
||||
|
||||
/// If true, the state is owned by this object and will be auto-Closed. False => attached state
|
||||
/** If true, the state is owned by this object and will be auto-Closed. False => attached state */
|
||||
bool m_IsOwned;
|
||||
|
||||
/** The subsystem name is used for reporting errors to the console, it is either "plugin %s" or "LuaScript"
|
||||
@@ -847,10 +874,10 @@ protected:
|
||||
*/
|
||||
AString m_SubsystemName;
|
||||
|
||||
/// Name of the currently pushed function (for the Push / Call chain)
|
||||
/** Name of the currently pushed function (for the Push / Call chain) */
|
||||
AString m_CurrentFunctionName;
|
||||
|
||||
/// Number of arguments currently pushed (for the Push / Call chain)
|
||||
/** Number of arguments currently pushed (for the Push / Call chain) */
|
||||
int m_NumCurrentFunctionArgs;
|
||||
|
||||
|
||||
@@ -869,19 +896,19 @@ protected:
|
||||
*/
|
||||
bool PushFunction(const cTableRef & a_TableRef);
|
||||
|
||||
/// Pushes a usertype of the specified class type onto the stack
|
||||
/** Pushes a usertype of the specified class type onto the stack */
|
||||
void PushUserType(void * a_Object, const char * a_Type);
|
||||
|
||||
/// Retrieve value returned at a_StackPos, if it is a valid bool. If not, a_ReturnedVal is unchanged
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid bool. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, bool & a_ReturnedVal);
|
||||
|
||||
/// Retrieve value returned at a_StackPos, if it is a valid string. If not, a_ReturnedVal is unchanged
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid string. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, AString & a_ReturnedVal);
|
||||
|
||||
/// Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, int & a_ReturnedVal);
|
||||
|
||||
/// Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged
|
||||
/** Retrieve value returned at a_StackPos, if it is a valid number. If not, a_ReturnedVal is unchanged */
|
||||
void GetReturn(int a_StackPos, double & a_ReturnedVal);
|
||||
|
||||
/**
|
||||
|
||||
+97
-101
@@ -1540,6 +1540,85 @@ static int tolua_cPluginManager_BindConsoleCommand(lua_State * L)
|
||||
|
||||
|
||||
|
||||
static int tolua_cPluginManager_CallPlugin(lua_State * tolua_S)
|
||||
{
|
||||
/*
|
||||
Function signature:
|
||||
cPluginManager:CallPlugin("PluginName", "FunctionName", args...)
|
||||
*/
|
||||
|
||||
// Check the parameters:
|
||||
cLuaState L(tolua_S);
|
||||
if (
|
||||
!L.CheckParamUserTable(1, "cPluginManager") ||
|
||||
!L.CheckParamString(2, 3))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retrieve the plugin name and function name
|
||||
AString PluginName, FunctionName;
|
||||
L.ToString(2, PluginName);
|
||||
L.ToString(3, FunctionName);
|
||||
if (PluginName.empty() || FunctionName.empty())
|
||||
{
|
||||
LOGWARNING("cPluginManager:CallPlugin(): Invalid plugin name or function name");
|
||||
L.LogStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If requesting calling the current plugin, refuse:
|
||||
cPluginLua * ThisPlugin = GetLuaPlugin(L);
|
||||
if (ThisPlugin == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
if (ThisPlugin->GetName() == PluginName)
|
||||
{
|
||||
LOGWARNING("cPluginManager::CallPlugin(): Calling self is not implemented (why would it?)");
|
||||
L.LogStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Call the destination plugin using a plugin callback:
|
||||
class cCallback :
|
||||
public cPluginManager::cPluginCallback
|
||||
{
|
||||
public:
|
||||
int m_NumReturns;
|
||||
|
||||
cCallback(const AString & a_FunctionName, cLuaState & a_SrcLuaState) :
|
||||
m_FunctionName(a_FunctionName),
|
||||
m_SrcLuaState(a_SrcLuaState),
|
||||
m_NumReturns(0)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
const AString & m_FunctionName;
|
||||
cLuaState & m_SrcLuaState;
|
||||
|
||||
virtual bool Item(cPlugin * a_Plugin) override
|
||||
{
|
||||
m_NumReturns = ((cPluginLua *)a_Plugin)->CallFunctionFromForeignState(
|
||||
m_FunctionName, m_SrcLuaState, 4, lua_gettop(m_SrcLuaState)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
} Callback(FunctionName, L);
|
||||
if (!cPluginManager::Get()->DoWithPlugin(PluginName, Callback))
|
||||
{
|
||||
// TODO 2014_01_20 _X: This might be too much logging, plugins cannot know if other plugins are loaded (async)
|
||||
LOGWARNING("cPluginManager::CallPlugin: No such plugin name (\"%s\")", PluginName.c_str());
|
||||
L.LogStackTrace();
|
||||
return 0;
|
||||
}
|
||||
return Callback.m_NumReturns;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlayer_GetGroups(lua_State* tolua_S)
|
||||
{
|
||||
cPlayer* self = (cPlayer*) tolua_tousertype(tolua_S,1,0);
|
||||
@@ -1734,112 +1813,28 @@ static int tolua_cPluginLua_AddTab(lua_State* tolua_S)
|
||||
|
||||
|
||||
|
||||
// Perhaps use this as well for copying tables https://github.com/keplerproject/rings/pull/1
|
||||
static int copy_lua_values(lua_State * a_Source, lua_State * a_Destination, int i, int top)
|
||||
|
||||
static int tolua_cPlugin_Call(lua_State * tolua_S)
|
||||
{
|
||||
for(; i <= top; ++i )
|
||||
{
|
||||
int t = lua_type(a_Source, i);
|
||||
switch (t) {
|
||||
case LUA_TSTRING: /* strings */
|
||||
{
|
||||
const char * s = lua_tostring(a_Source, i);
|
||||
LOGD("%i push string: %s", i, s);
|
||||
tolua_pushstring(a_Destination, s);
|
||||
}
|
||||
break;
|
||||
case LUA_TBOOLEAN: /* booleans */
|
||||
{
|
||||
int b = tolua_toboolean(a_Source, i, false);
|
||||
LOGD("%i push bool: %i", i, b);
|
||||
tolua_pushboolean(a_Destination, b );
|
||||
}
|
||||
break;
|
||||
case LUA_TNUMBER: /* numbers */
|
||||
{
|
||||
lua_Number d = tolua_tonumber(a_Source, i, 0);
|
||||
LOGD("%i push number: %0.2f", i, d);
|
||||
tolua_pushnumber(a_Destination, d );
|
||||
}
|
||||
break;
|
||||
case LUA_TUSERDATA:
|
||||
{
|
||||
const char * type = 0;
|
||||
if (lua_getmetatable(a_Source,i))
|
||||
{
|
||||
lua_rawget(a_Source, LUA_REGISTRYINDEX);
|
||||
type = lua_tostring(a_Source, -1);
|
||||
lua_pop(a_Source, 1); // Pop.. something?! I don't knooow~~ T_T
|
||||
}
|
||||
|
||||
// don't need tolua_tousertype we already have the type
|
||||
void * ud = tolua_touserdata(a_Source, i, 0);
|
||||
LOGD("%i push usertype: %p of type '%s'", i, ud, type);
|
||||
if( type == 0 )
|
||||
{
|
||||
LOGERROR("Call(): Something went wrong when trying to get usertype name!");
|
||||
return 0;
|
||||
}
|
||||
tolua_pushusertype(a_Destination, ud, type);
|
||||
}
|
||||
break;
|
||||
default: /* other values */
|
||||
LOGERROR("Call(): Unsupported value: '%s'. Can only use numbers and strings!", lua_typename(a_Source, t));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
static int tolua_cPlugin_Call(lua_State* tolua_S)
|
||||
{
|
||||
cPluginLua * self = (cPluginLua *) tolua_tousertype(tolua_S, 1, 0);
|
||||
lua_State* targetState = self->GetLuaState();
|
||||
int targetTop = lua_gettop(targetState);
|
||||
|
||||
int top = lua_gettop(tolua_S);
|
||||
LOGD("total in stack: %i", top );
|
||||
|
||||
std::string funcName = tolua_tostring(tolua_S, 2, "");
|
||||
LOGD("Func name: %s", funcName.c_str() );
|
||||
|
||||
lua_getglobal(targetState, funcName.c_str());
|
||||
if(!lua_isfunction(targetState,-1))
|
||||
{
|
||||
LOGWARN("Error could not find function '%s' in plugin '%s'", funcName.c_str(), self->GetName().c_str() );
|
||||
lua_pop(targetState,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if( copy_lua_values(tolua_S, targetState, 3, top) == 0 ) // Start at 3 because 1 and 2 are the plugin and function name respectively
|
||||
{
|
||||
// something went wrong, exit
|
||||
return 0;
|
||||
}
|
||||
cLuaState L(tolua_S);
|
||||
|
||||
int s = lua_pcall(targetState, top - 2, LUA_MULTRET, 0);
|
||||
if (cLuaState::ReportErrors(targetState, s))
|
||||
// Log the obsoletion warning:
|
||||
LOGWARNING("cPlugin:Call() is obsolete and unsafe, use cPluginManager:CallPlugin() instead.");
|
||||
L.LogStackTrace();
|
||||
|
||||
// Retrieve the params: plugin and the function name to call
|
||||
cPluginLua * TargetPlugin = (cPluginLua *) tolua_tousertype(tolua_S, 1, 0);
|
||||
AString FunctionName = tolua_tostring(tolua_S, 2, "");
|
||||
|
||||
// Call the function:
|
||||
int NumReturns = TargetPlugin->CallFunctionFromForeignState(FunctionName, L, 3, lua_gettop(L));
|
||||
if (NumReturns < 0)
|
||||
{
|
||||
LOGWARN("Error while calling function '%s' in plugin '%s'", funcName.c_str(), self->GetName().c_str() );
|
||||
LOGWARNING("cPlugin::Call() failed to call destination function");
|
||||
L.LogStackTrace();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nresults = lua_gettop(targetState) - targetTop;
|
||||
LOGD("num results: %i", nresults);
|
||||
int ttop = lua_gettop(targetState);
|
||||
if( copy_lua_values(targetState, tolua_S, targetTop+1, ttop) == 0 ) // Start at targetTop+1 and I have no idea why xD
|
||||
{
|
||||
// something went wrong, exit
|
||||
return 0;
|
||||
}
|
||||
|
||||
lua_pop(targetState, nresults); // I have no idea what I'm doing, but it works
|
||||
|
||||
return nresults;
|
||||
return NumReturns;
|
||||
}
|
||||
|
||||
|
||||
@@ -2305,6 +2300,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
|
||||
tolua_function(tolua_S, "AddHook", tolua_cPluginManager_AddHook);
|
||||
tolua_function(tolua_S, "BindCommand", tolua_cPluginManager_BindCommand);
|
||||
tolua_function(tolua_S, "BindConsoleCommand", tolua_cPluginManager_BindConsoleCommand);
|
||||
tolua_function(tolua_S, "CallPlugin", tolua_cPluginManager_CallPlugin);
|
||||
tolua_function(tolua_S, "ForEachCommand", tolua_cPluginManager_ForEachCommand);
|
||||
tolua_function(tolua_S, "ForEachConsoleCommand", tolua_cPluginManager_ForEachConsoleCommand);
|
||||
tolua_function(tolua_S, "GetAllPlugins", tolua_cPluginManager_GetAllPlugins);
|
||||
|
||||
@@ -1469,6 +1469,40 @@ bool cPluginLua::AddHookRef(int a_HookType, int a_FnRefIdx)
|
||||
|
||||
|
||||
|
||||
int cPluginLua::CallFunctionFromForeignState(
|
||||
const AString & a_FunctionName,
|
||||
cLuaState & a_ForeignState,
|
||||
int a_ParamStart,
|
||||
int a_ParamEnd
|
||||
)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
||||
// Call the function:
|
||||
int NumReturns = m_LuaState.CallFunctionWithForeignParams(a_FunctionName, a_ForeignState, a_ParamStart, a_ParamEnd);
|
||||
if (NumReturns < 0)
|
||||
{
|
||||
// The call has failed, an error has already been output to the log, so just silently bail out with the same error
|
||||
return NumReturns;
|
||||
}
|
||||
|
||||
// Copy all the return values:
|
||||
int Top = lua_gettop(m_LuaState);
|
||||
int res = a_ForeignState.CopyStackFrom(m_LuaState, Top - NumReturns + 1, Top);
|
||||
|
||||
// Remove the return values off this stack:
|
||||
if (NumReturns > 0)
|
||||
{
|
||||
lua_pop(m_LuaState, NumReturns);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
AString cPluginLua::HandleWebRequest(const HTTPRequest * a_Request )
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
|
||||
+26
-16
@@ -105,7 +105,7 @@ public:
|
||||
|
||||
virtual void ClearConsoleCommands(void) override;
|
||||
|
||||
/// Returns true if the plugin contains the function for the specified hook type, using the old-style registration (#121)
|
||||
/** Returns true if the plugin contains the function for the specified hook type, using the old-style registration (#121) */
|
||||
bool CanAddOldStyleHook(int a_HookType);
|
||||
|
||||
// cWebPlugin override
|
||||
@@ -115,26 +115,26 @@ public:
|
||||
virtual AString HandleWebRequest(const HTTPRequest * a_Request ) override;
|
||||
bool AddWebTab(const AString & a_Title, lua_State * a_LuaState, int a_FunctionReference); // >> EXPORTED IN MANUALBINDINGS <<
|
||||
|
||||
/// Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap.
|
||||
/** Binds the command to call the function specified by a Lua function reference. Simply adds to CommandMap. */
|
||||
void BindCommand(const AString & a_Command, int a_FnRef);
|
||||
|
||||
/// Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap.
|
||||
/** Binds the console command to call the function specified by a Lua function reference. Simply adds to CommandMap. */
|
||||
void BindConsoleCommand(const AString & a_Command, int a_FnRef);
|
||||
|
||||
cLuaState & GetLuaState(void) { return m_LuaState; }
|
||||
|
||||
cCriticalSection & GetCriticalSection(void) { return m_CriticalSection; }
|
||||
|
||||
/// Removes a previously referenced object (luaL_unref())
|
||||
/** Removes a previously referenced object (luaL_unref()) */
|
||||
void Unreference(int a_LuaRef);
|
||||
|
||||
/// Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true
|
||||
/** Calls the plugin-specified "cLuaWindow closing" callback. Returns true only if the callback returned true */
|
||||
bool CallbackWindowClosing(int a_FnRef, cWindow & a_Window, cPlayer & a_Player, bool a_CanRefuse);
|
||||
|
||||
/// Calls the plugin-specified "cLuaWindow slot changed" callback.
|
||||
/** Calls the plugin-specified "cLuaWindow slot changed" callback. */
|
||||
void CallbackWindowSlotChanged(int a_FnRef, cWindow & a_Window, int a_SlotNum);
|
||||
|
||||
/// Returns the name of Lua function that should handle the specified hook type in the older (#121) API
|
||||
/** Returns the name of Lua function that should handle the specified hook type in the older (#121) API */
|
||||
static const char * GetHookFnName(int a_HookType);
|
||||
|
||||
/** Adds a Lua function to be called for the specified hook.
|
||||
@@ -143,37 +143,47 @@ public:
|
||||
*/
|
||||
bool AddHookRef(int a_HookType, int a_FnRefIdx);
|
||||
|
||||
/** Calls a function in this plugin's LuaState with parameters copied over from a_ForeignState.
|
||||
The values that the function returns are placed onto a_ForeignState.
|
||||
Returns the number of values returned, if successful, or negative number on failure. */
|
||||
int CallFunctionFromForeignState(
|
||||
const AString & a_FunctionName,
|
||||
cLuaState & a_ForeignState,
|
||||
int a_ParamStart,
|
||||
int a_ParamEnd
|
||||
);
|
||||
|
||||
// The following templates allow calls to arbitrary Lua functions residing in the plugin:
|
||||
|
||||
/// Call a Lua function with 0 args
|
||||
/** 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
|
||||
/** 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
|
||||
/** 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
|
||||
/** 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
|
||||
/** 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_Arg3)
|
||||
{
|
||||
cCSLock Lock(m_CriticalSection);
|
||||
@@ -181,13 +191,13 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Maps command name into Lua function reference
|
||||
/** Maps command name into Lua function reference */
|
||||
typedef std::map<AString, int> CommandMap;
|
||||
|
||||
/// Provides an array of Lua function references
|
||||
/** Provides an array of Lua function references */
|
||||
typedef std::vector<cLuaState::cRef *> cLuaRefs;
|
||||
|
||||
/// Maps hook types into arrays of Lua function references to call for each hook type
|
||||
/** Maps hook types into arrays of Lua function references to call for each hook type */
|
||||
typedef std::map<int, cLuaRefs> cHookMap;
|
||||
|
||||
cCriticalSection m_CriticalSection;
|
||||
@@ -198,7 +208,7 @@ protected:
|
||||
|
||||
cHookMap m_HookMap;
|
||||
|
||||
/// Releases all Lua references and closes the LuaState
|
||||
/** Releases all Lua references and closes the LuaState */
|
||||
void Close(void);
|
||||
} ; // tolua_export
|
||||
|
||||
|
||||
@@ -1736,6 +1736,21 @@ bool cPluginManager::IsValidHookType(int a_HookType)
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::DoWithPlugin(const AString & a_PluginName, cPluginCallback & a_Callback)
|
||||
{
|
||||
// TODO: Implement locking for plugins
|
||||
PluginMap::iterator itr = m_Plugins.find(a_PluginName);
|
||||
if (itr == m_Plugins.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return a_Callback.Item(itr->second);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cPluginManager::AddPlugin(cPlugin * a_Plugin)
|
||||
{
|
||||
m_Plugins[a_Plugin->GetDirectory()] = a_Plugin;
|
||||
|
||||
@@ -122,7 +122,7 @@ public: // tolua_export
|
||||
} ;
|
||||
// tolua_end
|
||||
|
||||
/// Used as a callback for enumerating bound commands
|
||||
/** Used as a callback for enumerating bound commands */
|
||||
class cCommandEnumCallback
|
||||
{
|
||||
public:
|
||||
@@ -132,7 +132,11 @@ public: // tolua_export
|
||||
virtual bool Command(const AString & a_Command, const cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString) = 0;
|
||||
} ;
|
||||
|
||||
/// Returns the instance of the Plugin Manager (there is only ever one)
|
||||
/** The interface used for enumerating and extern-calling plugins */
|
||||
typedef cItemCallback<cPlugin> cPluginCallback;
|
||||
|
||||
|
||||
/** Returns the instance of the Plugin Manager (there is only ever one) */
|
||||
static cPluginManager * Get(void); // tolua_export
|
||||
|
||||
typedef std::map< AString, cPlugin * > PluginMap;
|
||||
@@ -143,7 +147,7 @@ public: // tolua_export
|
||||
void FindPlugins(); // tolua_export
|
||||
void ReloadPlugins(); // tolua_export
|
||||
|
||||
/// Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add
|
||||
/** Adds the plugin to the list of plugins called for the specified hook type. Handles multiple adds as a single add */
|
||||
void AddHook(cPlugin * a_Plugin, int a_HookType);
|
||||
|
||||
unsigned int GetNumPlugins() const; // tolua_export
|
||||
@@ -206,46 +210,46 @@ public: // tolua_export
|
||||
bool DisablePlugin(const AString & a_PluginName); // tolua_export
|
||||
bool LoadPlugin (const AString & a_PluginName); // tolua_export
|
||||
|
||||
/// Removes all hooks the specified plugin has registered
|
||||
/** Removes all hooks the specified plugin has registered */
|
||||
void RemoveHooks(cPlugin * a_Plugin);
|
||||
|
||||
/// Removes the plugin from the internal structures and deletes its object.
|
||||
/** Removes the plugin from the internal structures and deletes its object. */
|
||||
void RemovePlugin(cPlugin * a_Plugin);
|
||||
|
||||
/// Removes all command bindings that the specified plugin has made
|
||||
/** Removes all command bindings that the specified plugin has made */
|
||||
void RemovePluginCommands(cPlugin * a_Plugin);
|
||||
|
||||
/// Binds a command to the specified plugin. Returns true if successful, false if command already bound.
|
||||
/** Binds a command to the specified plugin. Returns true if successful, false if command already bound. */
|
||||
bool BindCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_Permission, const AString & a_HelpString); // Exported in ManualBindings.cpp, without the a_Plugin param
|
||||
|
||||
/// Calls a_Callback for each bound command, returns true if all commands were enumerated
|
||||
/** Calls a_Callback for each bound command, returns true if all commands were enumerated */
|
||||
bool ForEachCommand(cCommandEnumCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Returns true if the command is in the command map
|
||||
/** Returns true if the command is in the command map */
|
||||
bool IsCommandBound(const AString & a_Command); // tolua_export
|
||||
|
||||
/// Returns the permission needed for the specified command; empty string if command not found
|
||||
/** Returns the permission needed for the specified command; empty string if command not found */
|
||||
AString GetCommandPermission(const AString & a_Command); // tolua_export
|
||||
|
||||
/// Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed.
|
||||
/** Executes the command, as if it was requested by a_Player. Checks permissions first. Returns true if executed. */
|
||||
bool ExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
|
||||
/// Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found)
|
||||
/** Executes the command, as if it was requested by a_Player. Permisssions are not checked. Returns true if executed (false if not found) */
|
||||
bool ForceExecuteCommand(cPlayer * a_Player, const AString & a_Command); // tolua_export
|
||||
|
||||
/// Removes all console command bindings that the specified plugin has made
|
||||
/** Removes all console command bindings that the specified plugin has made */
|
||||
void RemovePluginConsoleCommands(cPlugin * a_Plugin);
|
||||
|
||||
/// Binds a console command to the specified plugin. Returns true if successful, false if command already bound.
|
||||
/** Binds a console command to the specified plugin. Returns true if successful, false if command already bound. */
|
||||
bool BindConsoleCommand(const AString & a_Command, cPlugin * a_Plugin, const AString & a_HelpString); // Exported in ManualBindings.cpp, without the a_Plugin param
|
||||
|
||||
/// Calls a_Callback for each bound console command, returns true if all commands were enumerated
|
||||
/** Calls a_Callback for each bound console command, returns true if all commands were enumerated */
|
||||
bool ForEachConsoleCommand(cCommandEnumCallback & a_Callback); // Exported in ManualBindings.cpp
|
||||
|
||||
/// Returns true if the console command is in the command map
|
||||
/** Returns true if the console command is in the command map */
|
||||
bool IsConsoleCommandBound(const AString & a_Command); // tolua_export
|
||||
|
||||
/// Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback
|
||||
/** Executes the command split into a_Split, as if it was given on the console. Returns true if executed. Output is sent to the a_Output callback */
|
||||
bool ExecuteConsoleCommand(const AStringVector & a_Split, cCommandOutputCallback & a_Output);
|
||||
|
||||
/** Appends all commands beginning with a_Text (case-insensitive) into a_Results.
|
||||
@@ -253,9 +257,13 @@ public: // tolua_export
|
||||
*/
|
||||
void TabCompleteCommand(const AString & a_Text, AStringVector & a_Results, cPlayer * a_Player);
|
||||
|
||||
/// Returns true if the specified hook type is within the allowed range
|
||||
/** Returns true if the specified hook type is within the allowed range */
|
||||
static bool IsValidHookType(int a_HookType);
|
||||
|
||||
/** Calls the specified callback with the plugin object of the specified plugin.
|
||||
Returns false if plugin not found, and the value that the callback has returned otherwise. */
|
||||
bool DoWithPlugin(const AString & a_PluginName, cPluginCallback & a_Callback);
|
||||
|
||||
private:
|
||||
friend class cRoot;
|
||||
|
||||
@@ -281,22 +289,22 @@ private:
|
||||
cPluginManager();
|
||||
virtual ~cPluginManager();
|
||||
|
||||
/// Reloads all plugins, defaulting to settings.ini for settings location
|
||||
/** Reloads all plugins, defaulting to settings.ini for settings location */
|
||||
void ReloadPluginsNow(void);
|
||||
|
||||
/// Reloads all plugins with a cIniFile object expected to be initialised to settings.ini
|
||||
/** Reloads all plugins with a cIniFile object expected to be initialised to settings.ini */
|
||||
void ReloadPluginsNow(cIniFile & a_SettingsIni);
|
||||
|
||||
/// Unloads all plugins
|
||||
/** Unloads all plugins */
|
||||
void UnloadPluginsNow(void);
|
||||
|
||||
/// Handles writing default plugins if 'Plugins' key not found using a cIniFile object expected to be intialised to settings.ini
|
||||
/** Handles writing default plugins if 'Plugins' key not found using a cIniFile object expected to be intialised to settings.ini */
|
||||
void InsertDefaultPlugins(cIniFile & a_SettingsIni);
|
||||
|
||||
/// Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again.
|
||||
/** Adds the plugin into the internal list of plugins and initializes it. If initialization fails, the plugin is removed again. */
|
||||
bool AddPlugin(cPlugin * a_Plugin);
|
||||
|
||||
/// Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled.
|
||||
/** Tries to match a_Command to the internal table of commands, if a match is found, the corresponding plugin is called. Returns true if the command is handled. */
|
||||
bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions, bool & a_WasCommandForbidden);
|
||||
bool HandleCommand(cPlayer * a_Player, const AString & a_Command, bool a_ShouldCheckPermissions)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user