mirror of
https://github.com/alliedmodders/amxmodx.git
synced 2024-12-25 06:15:37 +03:00
added SinglePlugin forwards
This commit is contained in:
parent
7c4324b963
commit
e9e4b380cb
@ -53,14 +53,14 @@ CForward::CForward(const char *name, ForwardExecType et, int numParams, const Fo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
{
|
{
|
||||||
cell realParams[FORWARD_MAX_PARAMS];
|
cell realParams[FORWARD_MAX_PARAMS];
|
||||||
cell *physAddrs[FORWARD_MAX_PARAMS];
|
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||||
|
|
||||||
const int STRINGEX_MAXLENGTH = 128;
|
const int STRINGEX_MAXLENGTH = 128;
|
||||||
|
|
||||||
int globRetVal = 0;
|
cell globRetVal = 0;
|
||||||
|
|
||||||
for (CList<AMXForward>::iterator iter = m_Funcs.begin(); iter; ++iter)
|
for (CList<AMXForward>::iterator iter = m_Funcs.begin(); iter; ++iter)
|
||||||
{
|
{
|
||||||
@ -159,28 +159,179 @@ int CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
|||||||
return globRetVal;
|
return globRetVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CSPForward::Set(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
|
{
|
||||||
|
m_Func = func;
|
||||||
|
m_Amx = amx;
|
||||||
|
m_NumParams = numParams;
|
||||||
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||||
|
m_HasFunc = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CSPForward::Set(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
|
{
|
||||||
|
m_Amx = amx;
|
||||||
|
m_NumParams = numParams;
|
||||||
|
memcpy((void *)m_ParamTypes, paramTypes, numParams * sizeof(ForwardParam));
|
||||||
|
m_HasFunc = (amx_FindPublic(amx, funcName, &m_Func) == AMX_ERR_NONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
|
{
|
||||||
|
const int STRINGEX_MAXLENGTH = 128;
|
||||||
|
|
||||||
|
cell realParams[FORWARD_MAX_PARAMS];
|
||||||
|
cell *physAddrs[FORWARD_MAX_PARAMS];
|
||||||
|
|
||||||
|
if (!m_HasFunc)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
|
||||||
|
if (!pPlugin->isExecutable(m_Func))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// handle strings & arrays
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
{
|
||||||
|
if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
|
||||||
|
{
|
||||||
|
cell *tmp;
|
||||||
|
amx_Allot(m_Amx,
|
||||||
|
(m_ParamTypes[i] == FP_STRING) ? strlen(reinterpret_cast<const char*>(params[i]))+1 : STRINGEX_MAXLENGTH,
|
||||||
|
&realParams[i], &tmp);
|
||||||
|
amx_SetString(tmp, (const char *)(params[i]), 0, 0);
|
||||||
|
physAddrs[i] = tmp;
|
||||||
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
{
|
||||||
|
cell *tmp;
|
||||||
|
amx_Allot(m_Amx, preparedArrays[params[i]].size,
|
||||||
|
&realParams[i], &tmp);
|
||||||
|
physAddrs[i] = tmp;
|
||||||
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
|
{
|
||||||
|
memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
realParams[i] = params[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec
|
||||||
|
cell retVal;
|
||||||
|
amx_Execv(m_Amx, &retVal, m_Func, m_NumParams, realParams);
|
||||||
|
|
||||||
|
// cleanup strings & arrays
|
||||||
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
{
|
||||||
|
if (m_ParamTypes[i] == FP_STRING)
|
||||||
|
{
|
||||||
|
amx_Release(m_Amx, realParams[i]);
|
||||||
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
|
{
|
||||||
|
// copy back
|
||||||
|
amx_GetString(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||||
|
amx_Release(m_Amx, realParams[i]);
|
||||||
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
|
{
|
||||||
|
// copy back
|
||||||
|
cell *tmp = physAddrs[i];
|
||||||
|
if (preparedArrays[params[i]].type == Type_Cell)
|
||||||
|
{
|
||||||
|
memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *data = (char*)preparedArrays[params[i]].ptr;
|
||||||
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
|
}
|
||||||
|
amx_Release(m_Amx, realParams[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
int CForwardMngr::registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam * paramTypes)
|
||||||
{
|
{
|
||||||
int retVal = m_Forwards.size();
|
int retVal = m_Forwards.size() << 1;
|
||||||
m_Forwards.push_back(new CForward(funcName, et, numParams, paramTypes));
|
m_Forwards.push_back(new CForward(funcName, et, numParams, paramTypes));
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int CForwardMngr::registerSPForward(int func, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
|
{
|
||||||
|
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||||
|
CSPForward *pForward;
|
||||||
|
if (m_FreeSPForwards.size())
|
||||||
|
{
|
||||||
|
pForward = m_SPForwards[m_FreeSPForwards.back()];
|
||||||
|
m_FreeSPForwards.pop_back();
|
||||||
|
pForward->Set(func, amx, numParams, paramTypes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pForward = new CSPForward();
|
||||||
|
if (!pForward)
|
||||||
|
return -1;
|
||||||
|
pForward->Set(func, amx, numParams, paramTypes);
|
||||||
|
m_SPForwards.push_back(pForward);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
int CForwardMngr::registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam *paramTypes)
|
||||||
|
{
|
||||||
|
int retVal = (m_SPForwards.size() << 1) | 1;
|
||||||
|
CSPForward *pForward;
|
||||||
|
if (m_FreeSPForwards.size())
|
||||||
|
{
|
||||||
|
pForward = m_SPForwards[m_FreeSPForwards.back()];
|
||||||
|
m_FreeSPForwards.pop_back();
|
||||||
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pForward = new CSPForward();
|
||||||
|
if (!pForward)
|
||||||
|
return -1;
|
||||||
|
pForward->Set(funcName, amx, numParams, paramTypes);
|
||||||
|
m_SPForwards.push_back(pForward);
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
|
||||||
bool CForwardMngr::isIdValid(int id) const
|
bool CForwardMngr::isIdValid(int id) const
|
||||||
{
|
{
|
||||||
return (id >= 0) && (static_cast<size_t>(id) < m_Forwards.size());
|
return (id >= 0) && ((id & 1) ?
|
||||||
|
(static_cast<size_t>(id >> 1) < m_SPForwards.size()) :
|
||||||
|
(static_cast<size_t>(id >> 1) < m_Forwards.size()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int CForwardMngr::executeForwards(int id, cell *params)
|
cell CForwardMngr::executeForwards(int id, cell *params)
|
||||||
{
|
{
|
||||||
int retVal = m_Forwards[id]->execute(params, m_TmpArrays);
|
int retVal = (id & 1) ? m_SPForwards[id >> 1]->execute(params, m_TmpArrays) :
|
||||||
|
m_Forwards[id >> 1]->execute(params, m_TmpArrays);
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int CForwardMngr::getParamsNum(int id) const
|
int CForwardMngr::getParamsNum(int id) const
|
||||||
{
|
{
|
||||||
return m_Forwards[id]->getParamsNum();
|
return (id & 1) ? m_SPForwards[id >> 1]->getParamsNum() :
|
||||||
|
m_Forwards[id >> 1]->getParamsNum();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CForwardMngr::clear()
|
void CForwardMngr::clear()
|
||||||
@ -189,10 +340,28 @@ void CForwardMngr::clear()
|
|||||||
{
|
{
|
||||||
delete (*iter);
|
delete (*iter);
|
||||||
}
|
}
|
||||||
|
SPForwardVec::iterator spIter;
|
||||||
|
for (spIter = m_SPForwards.begin(); spIter != m_SPForwards.end(); ++spIter)
|
||||||
|
{
|
||||||
|
delete (*spIter);
|
||||||
|
}
|
||||||
|
|
||||||
m_Forwards.clear();
|
m_Forwards.clear();
|
||||||
|
m_SPForwards.clear();
|
||||||
|
m_FreeSPForwards.clear();
|
||||||
m_TmpArraysNum = 0;
|
m_TmpArraysNum = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CForwardMngr::isSPForward(int id) const
|
||||||
|
{
|
||||||
|
return ((id & 1) == 0) ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CForwardMngr::unregisterSPForward(int id)
|
||||||
|
{
|
||||||
|
m_FreeSPForwards.push_back(id);
|
||||||
|
}
|
||||||
|
|
||||||
int registerForward(const char *funcName, ForwardExecType et, ...)
|
int registerForward(const char *funcName, ForwardExecType et, ...)
|
||||||
{
|
{
|
||||||
int curParam = 0;
|
int curParam = 0;
|
||||||
@ -214,7 +383,49 @@ int registerForward(const char *funcName, ForwardExecType et, ...)
|
|||||||
return g_forwards.registerForward(funcName, et, curParam, params);
|
return g_forwards.registerForward(funcName, et, curParam, params);
|
||||||
}
|
}
|
||||||
|
|
||||||
int executeForwards(int id, ...)
|
int registerSPForwardByName(AMX *amx, const char *funcName, ...)
|
||||||
|
{
|
||||||
|
int curParam = 0;
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, funcName);
|
||||||
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||||
|
ForwardParam tmp;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (curParam == FORWARD_MAX_PARAMS)
|
||||||
|
break;
|
||||||
|
tmp = (ForwardParam)va_arg(argptr, int);
|
||||||
|
if (tmp == FP_DONE)
|
||||||
|
break;
|
||||||
|
params[curParam] = tmp;
|
||||||
|
++curParam;
|
||||||
|
}
|
||||||
|
va_end(argptr);
|
||||||
|
return g_forwards.registerSPForward(funcName, amx, curParam, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
int registerSPForward(AMX *amx, int func, ...)
|
||||||
|
{
|
||||||
|
int curParam = 0;
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr, func);
|
||||||
|
ForwardParam params[FORWARD_MAX_PARAMS];
|
||||||
|
ForwardParam tmp;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (curParam == FORWARD_MAX_PARAMS)
|
||||||
|
break;
|
||||||
|
tmp = (ForwardParam)va_arg(argptr, int);
|
||||||
|
if (tmp == FP_DONE)
|
||||||
|
break;
|
||||||
|
params[curParam] = tmp;
|
||||||
|
++curParam;
|
||||||
|
}
|
||||||
|
va_end(argptr);
|
||||||
|
return g_forwards.registerSPForward(func, amx, curParam, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
cell executeForwards(int id, ...)
|
||||||
{
|
{
|
||||||
if (!g_forwards.isIdValid(id))
|
if (!g_forwards.isIdValid(id))
|
||||||
return -1;
|
return -1;
|
||||||
@ -253,3 +464,8 @@ cell prepareCharArray(char *ptr, unsigned int size)
|
|||||||
{
|
{
|
||||||
return g_forwards.prepareArray((void*)ptr, size, Type_Char);
|
return g_forwards.prepareArray((void*)ptr, size, Type_Char);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void unregisterSPForward(int id)
|
||||||
|
{
|
||||||
|
g_forwards.unregisterSPForward(id);
|
||||||
|
}
|
@ -29,13 +29,23 @@
|
|||||||
* version.
|
* version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
CForward.h
|
||||||
|
forwards
|
||||||
|
1) normal forwards: called in all plugins
|
||||||
|
2) single plugin (sp) forwards: called in one plugin
|
||||||
|
|
||||||
|
The SP Forwards are handled differently because they are expected to be created / deleted
|
||||||
|
often, but the "normal" forwards are expected to be initialized at start up.
|
||||||
|
|
||||||
|
Note about forward ids:
|
||||||
|
for normal forwards: <index to vector> << 1
|
||||||
|
for sp forwards: (<index to vector> << 1) | 1
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef FORWARD_H
|
#ifndef FORWARD_H
|
||||||
#define FORWARD_H
|
#define FORWARD_H
|
||||||
|
|
||||||
// *****************************************************
|
|
||||||
// class CmdMngr
|
|
||||||
// *****************************************************
|
|
||||||
|
|
||||||
const int FORWARD_MAX_PARAMS = 16;
|
const int FORWARD_MAX_PARAMS = 16;
|
||||||
|
|
||||||
enum ForwardExecType
|
enum ForwardExecType
|
||||||
@ -57,6 +67,7 @@ enum ForwardParam
|
|||||||
FP_ARRAY, // array; use the return value of prepareArray.
|
FP_ARRAY, // array; use the return value of prepareArray.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// for prepareArray
|
||||||
enum ForwardArrayElemType
|
enum ForwardArrayElemType
|
||||||
{
|
{
|
||||||
Type_Cell = 0,
|
Type_Cell = 0,
|
||||||
@ -65,12 +76,12 @@ enum ForwardArrayElemType
|
|||||||
|
|
||||||
struct ForwardPreparedArray
|
struct ForwardPreparedArray
|
||||||
{
|
{
|
||||||
|
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ForwardArrayElemType type;
|
ForwardArrayElemType type;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Normal forward
|
||||||
class CForward
|
class CForward
|
||||||
{
|
{
|
||||||
const char *m_FuncName;
|
const char *m_FuncName;
|
||||||
@ -88,17 +99,53 @@ public:
|
|||||||
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
|
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
|
||||||
CForward()
|
CForward()
|
||||||
{ } // leaves everything unitialized
|
{ } // leaves everything unitialized
|
||||||
int execute(cell *params, ForwardPreparedArray *preparedArrays);
|
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||||
int getParamsNum() const
|
int getParamsNum() const
|
||||||
{
|
{
|
||||||
return m_NumParams;
|
return m_NumParams;
|
||||||
}
|
}
|
||||||
|
int getFuncsNum() const
|
||||||
|
{
|
||||||
|
return m_Funcs.size();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Single plugin forward
|
||||||
|
class CSPForward
|
||||||
|
{
|
||||||
|
const char *m_FuncName;
|
||||||
|
int m_NumParams;
|
||||||
|
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
|
||||||
|
AMX *m_Amx;
|
||||||
|
int m_Func;
|
||||||
|
bool m_HasFunc;
|
||||||
|
public:
|
||||||
|
CSPForward() { m_HasFunc = false; }
|
||||||
|
void Set(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
void Set(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
|
||||||
|
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
|
||||||
|
int getParamsNum() const
|
||||||
|
{
|
||||||
|
return m_NumParams;
|
||||||
|
}
|
||||||
|
int getFuncsNum() const
|
||||||
|
{
|
||||||
|
return (m_HasFunc) ? 1 : 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class CForwardMngr
|
class CForwardMngr
|
||||||
{
|
{
|
||||||
typedef CVector<CForward*> ForwardVec;
|
typedef CVector<CForward*> ForwardVec;
|
||||||
|
typedef CVector<CSPForward*> SPForwardVec;
|
||||||
|
typedef CVector<int> FreeSPVec; // Free SP Forwards
|
||||||
|
|
||||||
ForwardVec m_Forwards;
|
ForwardVec m_Forwards;
|
||||||
|
|
||||||
|
SPForwardVec m_SPForwards;
|
||||||
|
FreeSPVec m_FreeSPForwards; // so we don't have to free memory
|
||||||
|
|
||||||
ForwardPreparedArray m_TmpArrays[FORWARD_MAX_PARAMS]; // used by prepareArray
|
ForwardPreparedArray m_TmpArrays[FORWARD_MAX_PARAMS]; // used by prepareArray
|
||||||
int m_TmpArraysNum;
|
int m_TmpArraysNum;
|
||||||
public:
|
public:
|
||||||
@ -109,18 +156,31 @@ public:
|
|||||||
{ }
|
{ }
|
||||||
|
|
||||||
// Interface
|
// Interface
|
||||||
|
// Register normal forward
|
||||||
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
|
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
|
||||||
int executeForwards(int id, cell *params);
|
// Register single plugin forward
|
||||||
|
int registerSPForward(const char *funcName, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
int registerSPForward(int func, AMX *amx, int numParams, const ForwardParam * paramTypes);
|
||||||
|
// Unregister single plugin forward
|
||||||
|
void unregisterSPForward(int id);
|
||||||
|
// execute forward
|
||||||
|
cell executeForwards(int id, cell *params);
|
||||||
void clear(); // delete all forwards
|
void clear(); // delete all forwards
|
||||||
bool isIdValid(int id) const;
|
bool isIdValid(int id) const; // check whether forward id is valid
|
||||||
int getParamsNum(int id) const;
|
bool isSPForward(int id) const; // check whether forward is single plugin
|
||||||
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type);
|
int getParamsNum(int id) const; // get num of params of a forward
|
||||||
|
int getFuncsNum(int id) const; // get num of found functions of a forward
|
||||||
|
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type); // prepare array
|
||||||
};
|
};
|
||||||
|
|
||||||
// register forward
|
// (un)register forward
|
||||||
int registerForward(const char *funcName, ForwardExecType et, ...);
|
int registerForward(const char *funcName, ForwardExecType et, ...);
|
||||||
|
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
|
||||||
|
int registerSPForward(AMX *amx, int func, ...);
|
||||||
|
void unregisterSPForward(int id);
|
||||||
|
|
||||||
// execute forwards
|
// execute forwards
|
||||||
int executeForwards(int id, ...);
|
cell executeForwards(int id, ...);
|
||||||
// prepare array
|
// prepare array
|
||||||
cell prepareCellArray(cell *ptr, unsigned int size);
|
cell prepareCellArray(cell *ptr, unsigned int size);
|
||||||
cell prepareCharArray(char *ptr, unsigned int size);
|
cell prepareCharArray(char *ptr, unsigned int size);
|
||||||
|
Loading…
Reference in New Issue
Block a user