Merge pull request #267 from Arkshine/feature/unregister_event

Add enable/disable_event() native (bug 6360)
This commit is contained in:
Vincent Herbet 2015-07-21 00:00:28 +02:00
commit c6a3290c4f
4 changed files with 127 additions and 26 deletions

View File

@ -14,6 +14,8 @@
// class ClEvent // class ClEvent
// ***************************************************** // *****************************************************
Handle<EventHook> EventHandles;
EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags) EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
{ {
m_Plugin = plugin; m_Plugin = plugin;
@ -47,6 +49,7 @@ EventsMngr::ClEvent::ClEvent(CPluginMngr::CPlugin* plugin, int func, int flags)
m_Stamp = 0.0f; m_Stamp = 0.0f;
m_Done = false; m_Done = false;
m_State = FSTATE_ACTIVE;
m_Conditions = NULL; m_Conditions = NULL;
} }
@ -188,20 +191,31 @@ void EventsMngr::ClEvent::registerFilter(char *filter)
m_Conditions = tmpCond; m_Conditions = tmpCond;
} }
EventsMngr::ClEvent* EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid) void EventsMngr::ClEvent::setForwardState(ForwardState state)
{ {
// validate parameter m_State = state;
if (msgid < 0 || msgid >= MAX_AMX_REG_MSG) }
return NULL;
ClEvent *event = new ClEvent(plugin, func, flags);
int EventsMngr::registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid)
{
if (msgid < 0 || msgid >= MAX_AMX_REG_MSG)
{
return 0;
}
auto event = new ClEvent(plugin, func, flags);
int handle = EventHandles.create(event);
if (!event) if (!handle)
return NULL; {
return 0;
}
m_Events[msgid].put(event); m_Events[msgid].put(event);
return event; return handle;
} }
void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index) void EventsMngr::parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index)
@ -454,7 +468,10 @@ void EventsMngr::executeEvents()
(*iter).m_Stamp = (float)*m_Timer; (*iter).m_Stamp = (float)*m_Timer;
executeForwards((*iter).m_Func, static_cast<cell>(m_ReadVault ? m_ReadVault[0].iValue : 0)); if ((*iter).m_State == FSTATE_ACTIVE)
{
executeForwards((*iter).m_Func, static_cast<cell>(m_ReadVault ? m_ReadVault[0].iValue : 0));
}
} }
// Restore old read data, either resetting to default or to previous event data // Restore old read data, either resetting to default or to previous event data
@ -530,7 +547,9 @@ void EventsMngr::clearEvents(void)
{ {
m_Events[i].clear(); m_Events[i].clear();
} }
EventHandles.clear();
// delete parsevault // delete parsevault
if (m_ParseVault) if (m_ParseVault)
{ {

View File

@ -10,6 +10,8 @@
#ifndef __CEVENTS_H__ #ifndef __CEVENTS_H__
#define __CEVENTS_H__ #define __CEVENTS_H__
#include "natives_handles.h"
#define MAX_AMX_REG_MSG MAX_REG_MSGS + 16 #define MAX_AMX_REG_MSG MAX_REG_MSGS + 16
enum enum
@ -24,6 +26,12 @@ enum
// class EventsMngr // class EventsMngr
// ***************************************************** // *****************************************************
enum ForwardState
{
FSTATE_ACTIVE,
FSTATE_STOP
};
class EventsMngr class EventsMngr
{ {
enum MsgParamType enum MsgParamType
@ -63,6 +71,7 @@ public:
float m_Stamp; // for 'once' flag float m_Stamp; // for 'once' flag
bool m_Done; bool m_Done;
ForwardState m_State;
// conditions // conditions
struct cond_t struct cond_t
@ -87,6 +96,7 @@ public:
inline CPluginMngr::CPlugin* getPlugin(); inline CPluginMngr::CPlugin* getPlugin();
inline int getFunction(); inline int getFunction();
void registerFilter(char* filter); // add a condition void registerFilter(char* filter); // add a condition
void setForwardState(ForwardState value);
}; };
private: private:
@ -125,8 +135,8 @@ public:
// Interface // Interface
ClEvent* registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid); int registerEvent(CPluginMngr::CPlugin* plugin, int func, int flags, int msgid);
void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index); void parserInit(int msg_type, float* timer, CPlayer* pPlayer, int index);
void parseValue(int iValue); void parseValue(int iValue);
void parseValue(float fValue); void parseValue(float fValue);
@ -142,4 +152,12 @@ public:
int getCurrentMsgType(); int getCurrentMsgType();
}; };
struct EventHook
{
EventHook(EventsMngr::ClEvent *event) : m_event(event) {}
EventsMngr::ClEvent *m_event;
};
extern Handle<EventHook> EventHandles;
#endif //__CEVENTS_H__ #endif //__CEVENTS_H__

View File

@ -19,6 +19,7 @@
#include "nongpl_matches.h" #include "nongpl_matches.h"
#include "format.h" #include "format.h"
#include <amxmodx_version.h> #include <amxmodx_version.h>
#include "CEvent.h"
extern CFlagManager FlagMan; extern CFlagManager FlagMan;
ke::Vector<CAdminData *> DynamicAdmins; ke::Vector<CAdminData *> DynamicAdmins;
@ -1722,26 +1723,28 @@ static cell AMX_NATIVE_CALL get_concmdsnum(AMX *amx, cell *params) /* 1 param */
return g_commands.getCmdNum(CMD_ConsoleCommand, params[1]); return g_commands.getCmdNum(CMD_ConsoleCommand, params[1]);
} }
static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) /* 2 param */ // native register_event(const event[], const function[], const flags[], const cond[] = "", ...);
static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params)
{ {
CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx); CPluginMngr::CPlugin* plugin = g_plugins.findPluginFast(amx);
int len, pos, iFunction; int len, eventId, forwardId;
char* sTemp = get_amxstring(amx, params[1], 0, len); const char* eventName = get_amxstring(amx, params[1], 0, len);
if ((pos = g_events.getEventId(sTemp)) == 0) if ((eventId = g_events.getEventId(eventName)) == 0)
{ {
LogError(amx, AMX_ERR_NATIVE, "Invalid event (name \"%s\") (plugin \"%s\")", sTemp, plugin->getName()); LogError(amx, AMX_ERR_NATIVE, "Invalid event (name \"%s\") (plugin \"%s\")", eventName, plugin->getName());
return 0; return 0;
} }
sTemp = get_amxstring(amx, params[2], 0, len); const char* callback = get_amxstring(amx, params[2], 0, len);
iFunction = registerSPForwardByName(amx, sTemp, FP_CELL, FP_DONE);
forwardId = registerSPForwardByName(amx, callback, FP_CELL, FP_DONE);
if (iFunction == -1) if (forwardId == -1)
{ {
LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", sTemp); LogError(amx, AMX_ERR_NOTFOUND, "Function \"%s\" was not found", callback);
return 0; return 0;
} }
@ -1749,15 +1752,53 @@ static cell AMX_NATIVE_CALL register_event(AMX *amx, cell *params) /* 2 param */
int flags = 0; int flags = 0;
if (numparam > 2) if (numparam > 2)
{
flags = UTIL_ReadFlags(get_amxstring(amx, params[3], 0, len)); flags = UTIL_ReadFlags(get_amxstring(amx, params[3], 0, len));
}
EventsMngr::ClEvent* a = g_events.registerEvent(plugin, iFunction, flags, pos); int handle = g_events.registerEvent(plugin, forwardId, flags, eventId);
if (a == 0) if (!handle)
{
return 0; return 0;
}
auto event = EventHandles.lookup(handle)->m_event;
for (int i = 4; i <= numparam; ++i) for (int i = 4; i <= numparam; ++i)
a->registerFilter(get_amxstring(amx, params[i], 0, len)); {
event->registerFilter(get_amxstring(amx, params[i], 0, len));
}
return handle;
}
static cell AMX_NATIVE_CALL enable_event(AMX *amx, cell *params)
{
auto handle = EventHandles.lookup(params[1]);
if (!handle)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid event handle %d", params[1]);
return 0;
}
handle->m_event->setForwardState(FSTATE_ACTIVE);
return 1;
}
static cell AMX_NATIVE_CALL disable_event(AMX *amx, cell *params)
{
auto handle = EventHandles.lookup(params[1]);
if (!handle)
{
LogError(amx, AMX_ERR_NATIVE, "Invalid event handle: %d", params[1]);
return 0;
}
handle->m_event->setForwardState(FSTATE_STOP);
return 1; return 1;
} }
@ -4589,6 +4630,8 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
{"register_concmd", register_concmd}, {"register_concmd", register_concmd},
{"register_dictionary", register_dictionary}, {"register_dictionary", register_dictionary},
{"register_event", register_event}, {"register_event", register_event},
{"enable_event", enable_event},
{"disable_event", disable_event},
{"register_logevent", register_logevent}, {"register_logevent", register_logevent},
{"register_menucmd", register_menucmd}, {"register_menucmd", register_menucmd},
{"register_menuid", register_menuid}, {"register_menuid", register_menuid},

View File

@ -464,6 +464,8 @@ native console_cmd(id, const cmd[], any:...);
* @note Due to a long-standing bug that would break compatibility with older * @note Due to a long-standing bug that would break compatibility with older
* plugins, the client id should be checked for alive/dead state if using * plugins, the client id should be checked for alive/dead state if using
* flags "d" or "e". * flags "d" or "e".
* @note If multiple conditions are specified for a single parameter, only one
* of them has to hold true for the event function to be called.
* *
* @param event Name of event that should be hooked * @param event Name of event that should be hooked
* @param function Name of callback function * @param function Name of callback function
@ -488,13 +490,32 @@ native console_cmd(id, const cmd[], any:...);
* The argument is compared to the specified value accordingly * The argument is compared to the specified value accordingly
* @param ... Any number of additional conditions * @param ... Any number of additional conditions
* *
* @return 1 on successfully registering event * @return Event handle
* 0 on failure
* @error If an invalid event name or callback function is provided, * @error If an invalid event name or callback function is provided,
* an error will be thrown. * an error will be thrown.
*/ */
native register_event(const event[], const function[], const flags[], const cond[] = "", ...); native register_event(const event[], const function[], const flags[], const cond[] = "", ...);
/**
* Enables a function hook of a game event which has been previously registered with register_event().
*
* @param handle Value returned from register_event()
*
* @noreturn
* @error If an invalid handle is provided, an error will be thrown.
*/
native enable_event(handle);
/**
* Disables a function hook of a game event which has been previously registered with register_event().
*
* @param handle Value returned from register_event()
*
* @noreturn
* @error If an invalid handle is provided, an error will be thrown.
*/
native disable_event(handle);
/** /**
* Registers a function to be called on a given log event. * Registers a function to be called on a given log event.
* *