forward关键字可用于声明forward函数。
forward函数需要1个主插件创建、执行转发器,由其它插件引用函数声明,实现函数定义。
转发器会按创建时设定的规则执行其他插件定义的公共函数。
#include <amxmodx>
// 声明两个变量用于储存转发器句柄
static gFH_HelloWorld_Pre;
static gFH_HelloWorld_Post;
public plugin_precache()
{
register_plugin("测试插件1", "1.0.0", "插件作者");
// 在某个合适时机创建转发器。通常应该在plugin_precache或plugin_init函数内创建
gFH_HelloWorld_Pre = CreateMultiForward("HelloWorld_Pre", ET_CONTINUE);
gFH_HelloWorld_Post = CreateMultiForward("HelloWorld_Post", ET_CONTINUE);
set_task(10.0, "Task");
}
public Task()
{
// 在某个合适的时机执行转发器,若有插件实现了forward函数定义,该函数就会被执行。
// 转发器需根据创建时设定的规则,发送参数给其它插件定义的函数,并得到其中一个函数的返回值。
// 若并没有插件实现forward函数的定义,则收不到返回值,res变量不会被改变。
new res;
ExecuteForward(gFH_HelloWorld_Pre, res);
server_print("[AMXX] Hello World !");
ExecuteForward(gFH_HelloWorld_Post, res);
}
public plugin_end()
{
// 当你认为再也不需要执行转发器了,可以将其销毁,释放内存。
// 若不销毁,转发器会持续占用内存,直到更换地图、关闭服务器或关闭游戏,会自动销毁。
// 退回游戏菜单并不会自动销毁。
DestroyForward(gFH_HelloWorld_Pre);
DestroyForward(gFH_HelloWorld_Post);
}
#if (defined(_testplugin_included))
#endinput
#endif
#define _testplugin_included
// 声明forward函数:该函数的定义会在打印"[AMXX] Hello World !"之前触发
forward HelloWorld_Pre();
// 声明forward函数:该函数的定义会在打印"[AMXX] Hello World !"之后触发
forward HelloWorld_Post();
#include <amxmodx>
#include <testplugin> // 假设主插件提供的是testplugin.inc文件,引用它
// 这是forward函数’plugin_precache’的定义语句
public plugin_precache()
{
register_plugin("测试插件2", "1.0.0", "插件作者");
}
// 这是forward函数’HelloWorld_Pre’的定义语句
public HelloWorld_Pre()
{
server_print("[AMXX] 现在是事件发生之前 !");
}
// 这是forward函数’HelloWorld_Post’的定义语句
public HelloWorld_Post()
{
server_print("[AMXX] 现在是事件发生之后 !");
}
forward函数的声明和定义都很简单,复杂的是CreateMultiForward和ExecuteForward函数。
因此用户需要自行阅读这两个函数和相关常量的注释。
/**
* 某些函数返回值用带有_标签的-1表示无效的对象句柄,而这个宏常量也是-1。
* 不要模仿这种做法,尽量用可设置标签的常量代替宏常量。
*/
#define INVALID_HANDLE -1
/**
* CreateMultiForward函数参数2的可选数值之一。
* 转发器不要接收其他插件送来的返回值。
*/
#define ET_IGNORE 0
/**
* CreateMultiForward函数参数2的可选数值之一。
* 若转发器收到大于等于PLUGIN_HANDLED的返回值,停止转发。
* 按照这个规则,先注册的插件有能力拦截后注册插件对forward函数的处理。
*/
#define ET_STOP 1
/**
* CreateMultiForward函数参数2的可选数值之一。
* 不接收小于PLUGIN_HANDLED的返回值。
* 接收大于或等于PLUGIN_HANDLED的返回值,但只保留最大值。
* 收到等于PLUGIN_HANDLED的返回值,停止转发。
*/
#define ET_STOP2 2
/**
* CreateMultiForward函数参数2的可选数值之一。
* 接收最大的返回值,不停止转发。
*/
#define ET_CONTINUE 3
/**
* CreateOneForward、CreateMultiForward函数中,可变参数的可选数值之一。
* 表示ExecuteForward函数中,相同编号的可变参数应该填写带有任意标签的单值表达式。
* forward和public函数声明中,必须声明第(可变参数编号-2)个参数,必须是按值传递的单值参数。
*/
#define FP_CELL 0
/**
* CreateOneForward、CreateMultiForward函数中,可变参数的可选数值之一。
* 表示ExecuteForward函数中,相同编号的可变参数应该填写带有Float标签的单值表达式。
* forward和public函数声明中,必须声明第(可变参数编号-2)个参数,标签为Float,必须是按值传递的单值参数。
*/
#define FP_FLOAT 1
/**
* CreateOneForward、CreateMultiForward函数中,可变参数的可选数值之一。
* 表示ExecuteForward函数中,相同编号的可变参数应该填写字符串或字符串字面量。
* forward和public函数声明中,必须声明第(可变参数编号-2)个参数,必须是一维数组,并添加const修饰。
*/
#define FP_STRING 2
/**
* CreateOneForward、CreateMultiForward函数中,可变参数的可选数值之一。
* 表示ExecuteForward函数中,相同编号的可变参数应该填写PrepareArray函数的返回值。
* forward和public函数声明中,必须声明第(可变参数编号-2)个参数,必须是一维数组,若PrepareArray的copyback参数为假,应添加const修饰。
*/
#define FP_ARRAY 4
/**
* CreateOneForward、CreateMultiForward函数中,可变参数的可选数值之一。
* 表示ExecuteForward函数中,相同编号的可变参数应该填写带有任意标签的变量。
* forward和public函数声明中,必须声明第(可变参数编号-2)个参数,必须是按引用传递的单值参数。
*/
#define FP_VAL_BYREF 5
/**
* 创建一个forward函数转发器。
*
* @param name 被转发、调用的函数名称(forward和public函数的名称)
* @param stop_type 如何处理public函数返回值,详情查阅amxconst.inc文件中名称以ET_开头的宏常量
* @param ... 可变参数:转发过程中每个被传递参数的类型,详情查阅amxconst.inc文件中名称以FP_开头的宏常量
*
* @return INVALID_HANDLE=创建失败,转发器句柄=创建成功
*/
native CreateMultiForward(const name[], stop_type, ...);
/**
* 将一个数组缓存到堆中,以便ExecuteForward函数传递给其它插件。
* FP_ARRAY类型的参数必须使用这个函数的返回值代替。
*
* @param array 被缓存的一维数组
* @param size 需缓存多少个元素
* @param copyback 若非0,允许将public函数对array副本的更改,复制给array和下一个public函数的array副本
*
* @return 数组句柄,用作ExecuteForward函数的可变参数
*/
native PrepareArray(const array[], size, copyback = 0);
/**
* 执行转发器,根据插件注册顺序调用forward函数对应的所有public函数。
*
* @param forward_handle 转发器句柄,来源于CreateOneForward或CreateMultiForward函数返回值
* @param ret 如果有public函数,按规则输出其中一个public函数的返回值
* @param ... 可变参数,类型和数量与CreateOneForward或CreateMultiForward函数的可变参数一一对应,
* 若要输入FP_ARRAY类型的参数,必须用PrepareArray函数的返回值代替
*
* @return 1=执行成功,其它=转发器句柄无效
* @error 执行与创建时可变参数数量不一致
*/
native ExecuteForward(forward_handle, &ret = 0, any:...);
/**
* 销毁转发器,释放内存。
*
* @param forward_handle 转发器句柄,来源于CreateOneForward或CreateMultiForward函数返回值
*
* @noreturn
*/
native DestroyForward(forward_handle);