amxmodx/amxmodx/CForward.h
2016-04-05 18:51:18 +02:00

227 lines
5.8 KiB
C++
Executable File

// vim: set ts=4 sw=4 tw=99 noet:
//
// AMX Mod X, based on AMX Mod by Aleksander Naszko ("OLO").
// Copyright (C) The AMX Mod X Development Team.
//
// This software is licensed under the GNU General Public License, version 3 or higher.
// Additional exceptions apply. For full license details, see LICENSE.txt or visit:
// https://alliedmods.net/amxmodx-license
/*
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
#define FORWARD_H
#include <stdarg.h>
#include "sh_stack.h"
const int FORWARD_MAX_PARAMS = 32;
enum ForwardExecType
{
ET_IGNORE = 0, // Ignore return vaue
ET_STOP, // Stop on PLUGIN_HANDLED
ET_STOP2, // Stop on PLUGIN_HANDLED, continue on other values, return biggest return value
ET_CONTINUE, // Continue; return biggest return value
};
enum ForwardParam
{
FP_DONE = -1, // specify this as the last argument
// only tells the function that there are no more arguments
FP_CELL, // normal cell
FP_FLOAT, // float; used as normal cell though
FP_STRING, // string
FP_STRINGEX, // string; will be updated to the last function's value
FP_ARRAY, // array; use the return value of prepareArray.
FP_CELL_BYREF, // cell; pass by reference
FP_FLOAT_BYREF, // float; pass by reference
};
// for prepareArray
enum ForwardArrayElemType
{
Type_Cell = 0,
Type_Char
};
struct ForwardPreparedArray
{
void *ptr;
ForwardArrayElemType type;
unsigned int size;
bool copyBack;
};
// Normal forward
class CForward
{
const char *m_FuncName;
ForwardExecType m_ExecType;
int m_NumParams;
ke::AString m_Name;
struct AMXForward
{
CPluginMngr::CPlugin *pPlugin;
int func;
};
typedef ke::Vector<AMXForward> AMXForwardList;
AMXForwardList m_Funcs;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
public:
CForward(const char *name, ForwardExecType et, int numParams, const ForwardParam * paramTypes);
CForward() {} // leaves everything unitialized'
cell execute(cell *params, ForwardPreparedArray *preparedArrays);
int getParamsNum() const
{
return m_NumParams;
}
int getFuncsNum() const
{
return m_Funcs.length();
}
const char *getFuncName() const
{
return m_Name.chars();
}
ForwardParam getParamType(int paramId) const
{
if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE;
return m_ParamTypes[paramId];
}
};
// Single plugin forward
class CSPForward
{
friend class CForwardMngr;
int m_NumParams;
ForwardParam m_ParamTypes[FORWARD_MAX_PARAMS];
AMX *m_Amx;
int m_Func;
bool m_HasFunc;
ke::AString m_Name;
bool m_InExec;
bool m_ToDelete;
public:
bool isFree;
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;
}
const char *getFuncName() const
{
return m_Name.chars();
}
ForwardParam getParamType(int paramId) const
{
if (paramId < 0 || paramId >= m_NumParams)
return FP_DONE;
return m_ParamTypes[paramId];
}
};
class CForwardMngr
{
typedef ke::Vector<CForward*> ForwardVec;
typedef ke::Vector<CSPForward*> SPForwardVec;
typedef CStack<int> FreeSPVec; // Free SP 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
int m_TmpArraysNum;
public:
CForwardMngr()
{ m_TmpArraysNum = 0; }
~CForwardMngr() {}
// Interface
// Register normal forward
int registerForward(const char *funcName, ForwardExecType et, int numParams, const ForwardParam *paramTypes);
// 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);
int duplicateSPForward(int id);
int isSameSPForward(int id1, int id2);
// execute forward
cell executeForwards(int id, cell *params);
void clear(); // delete all forwards
bool isIdValid(int id) const; // check whether forward id is valid
bool isSPForward(int id) const; // check whether forward is single plugin
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
const char *getFuncName(int id) const; // get the function name
ForwardParam getParamType(int id, int paramId) const;
cell prepareArray(void *ptr, unsigned int size, ForwardArrayElemType type, bool copyBack); // prepare array
};
// (un)register forward
int registerForward(const char *funcName, ForwardExecType et, ...);
int registerForwardC(const char *funcName, ForwardExecType et, cell *list, size_t num);
int registerSPForwardByName(AMX *amx, const char *funcName, ...);
int registerSPForwardByNameC(AMX *amx, const char *funcName, cell *list, size_t num);
int registerSPForward(AMX *amx, int func, ...);
void unregisterSPForward(int id);
// execute forwards
cell executeForwards(int id, ...);
// prepare array
cell prepareCellArray(cell *ptr, unsigned int size, bool copyBack = false);
cell prepareCharArray(char *ptr, unsigned int size, bool copyBack = false);
#endif //FORWARD_H