Add RequestFrame() native (#412)
* Add RequestFrame() native * Change underlying container from CQueue to ke::Deque * CFrameAction: Fix PackageScript and MSVC project, wrap CFrameAction in AutoPtr
This commit is contained in:
parent
3a73e12550
commit
828e74e6c3
61
amxmodx/CFrameAction.h
Normal file
61
amxmodx/CFrameAction.h
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
#ifndef FRAMEACTION_H
|
||||||
|
#define FRAMEACTION_H
|
||||||
|
|
||||||
|
#include "amxmodx.h"
|
||||||
|
#include <amtl/am-deque.h>
|
||||||
|
#include <amtl/am-autoptr.h>
|
||||||
|
|
||||||
|
class CFrameActionMngr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
class CFrameAction
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFrameAction(int callbackForward, cell callbackData) :
|
||||||
|
m_callbackForward(callbackForward),
|
||||||
|
m_callbackData(callbackData)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~CFrameAction()
|
||||||
|
{
|
||||||
|
unregisterSPForward(m_callbackForward);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Execute()
|
||||||
|
{
|
||||||
|
executeForwards(m_callbackForward, m_callbackData);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
int m_callbackForward;
|
||||||
|
cell m_callbackData;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
void AddFrameAction(int callbackForward, cell callbackData)
|
||||||
|
{
|
||||||
|
m_requestedFrames.append(new CFrameAction(callbackForward, callbackData));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ExecuteFrameCallbacks()
|
||||||
|
{
|
||||||
|
// In case a frame callback requests another frame, newly added frames won't be executed this way
|
||||||
|
int callbacksToRun = m_requestedFrames.length();
|
||||||
|
while (callbacksToRun--)
|
||||||
|
{
|
||||||
|
ke::AutoPtr<CFrameAction> action = ke::Move(m_requestedFrames.front());
|
||||||
|
m_requestedFrames.popFront();
|
||||||
|
action->Execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ke::Deque<ke::AutoPtr<CFrameAction>> m_requestedFrames;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // FRAMEACTION_H
|
|
@ -4636,6 +4636,24 @@ static cell AMX_NATIVE_CALL AutoExecConfig(AMX *amx, cell *params)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//native RequestFrame(const callback[], any:data);
|
||||||
|
static cell AMX_NATIVE_CALL RequestFrame(AMX *amx, cell *params)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
const char *funcName = get_amxstring(amx, params[1], 0, len);
|
||||||
|
|
||||||
|
int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_DONE);
|
||||||
|
if (func < 0)
|
||||||
|
{
|
||||||
|
LogError(amx, AMX_ERR_NATIVE, "Function \"%s\" was not found", funcName);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_frameActionMngr.AddFrameAction(func, params[2]);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static cell AMX_NATIVE_CALL is_rukia_a_hag(AMX *amx, cell *params)
|
static cell AMX_NATIVE_CALL is_rukia_a_hag(AMX *amx, cell *params)
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -4834,6 +4852,7 @@ AMX_NATIVE_INFO amxmodx_Natives[] =
|
||||||
{"PrepareArray", PrepareArray},
|
{"PrepareArray", PrepareArray},
|
||||||
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
{"ShowSyncHudMsg", ShowSyncHudMsg},
|
||||||
{"AutoExecConfig", AutoExecConfig},
|
{"AutoExecConfig", AutoExecConfig},
|
||||||
|
{"RequestFrame", RequestFrame},
|
||||||
{"is_rukia_a_hag", is_rukia_a_hag},
|
{"is_rukia_a_hag", is_rukia_a_hag},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
|
@ -51,6 +51,7 @@
|
||||||
#include "amxxlog.h"
|
#include "amxxlog.h"
|
||||||
#include "CvarManager.h"
|
#include "CvarManager.h"
|
||||||
#include "CoreConfig.h"
|
#include "CoreConfig.h"
|
||||||
|
#include "CFrameAction.h"
|
||||||
#include <amxmodx_version.h>
|
#include <amxmodx_version.h>
|
||||||
#include <HLTypeConversion.h>
|
#include <HLTypeConversion.h>
|
||||||
|
|
||||||
|
@ -166,6 +167,7 @@ struct fakecmd_t
|
||||||
extern CLog g_log;
|
extern CLog g_log;
|
||||||
extern CPluginMngr g_plugins;
|
extern CPluginMngr g_plugins;
|
||||||
extern CTaskMngr g_tasksMngr;
|
extern CTaskMngr g_tasksMngr;
|
||||||
|
extern CFrameActionMngr g_frameActionMngr;
|
||||||
extern CPlayer g_players[33];
|
extern CPlayer g_players[33];
|
||||||
extern CPlayer* mPlayer;
|
extern CPlayer* mPlayer;
|
||||||
extern CmdMngr g_commands;
|
extern CmdMngr g_commands;
|
||||||
|
|
|
@ -71,6 +71,7 @@ CPlayer g_players[33];
|
||||||
CPlayer* mPlayer;
|
CPlayer* mPlayer;
|
||||||
CPluginMngr g_plugins;
|
CPluginMngr g_plugins;
|
||||||
CTaskMngr g_tasksMngr;
|
CTaskMngr g_tasksMngr;
|
||||||
|
CFrameActionMngr g_frameActionMngr;
|
||||||
CmdMngr g_commands;
|
CmdMngr g_commands;
|
||||||
CFlagManager FlagMan;
|
CFlagManager FlagMan;
|
||||||
EventsMngr g_events;
|
EventsMngr g_events;
|
||||||
|
@ -1217,6 +1218,8 @@ void C_StartFrame_Post(void)
|
||||||
}
|
}
|
||||||
#endif // MEMORY_TEST
|
#endif // MEMORY_TEST
|
||||||
|
|
||||||
|
g_frameActionMngr.ExecuteFrameCallbacks();
|
||||||
|
|
||||||
if (g_task_time > gpGlobals->time)
|
if (g_task_time > gpGlobals->time)
|
||||||
RETURN_META(MRES_IGNORED);
|
RETURN_META(MRES_IGNORED);
|
||||||
|
|
||||||
|
|
|
@ -376,6 +376,7 @@
|
||||||
<ClInclude Include="..\trie_natives.h" />
|
<ClInclude Include="..\trie_natives.h" />
|
||||||
<ClInclude Include="..\..\public\sdk\amxxmodule.h" />
|
<ClInclude Include="..\..\public\sdk\amxxmodule.h" />
|
||||||
<ClInclude Include="..\..\public\sdk\moduleconfig.h" />
|
<ClInclude Include="..\..\public\sdk\moduleconfig.h" />
|
||||||
|
<ClInclude Include="..\CFrameAction.h">
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\version.rc" />
|
<ResourceCompile Include="..\version.rc" />
|
||||||
|
|
|
@ -500,6 +500,9 @@
|
||||||
<ClInclude Include="..\CoreConfig.h">
|
<ClInclude Include="..\CoreConfig.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\CFrameAction.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="..\version.rc">
|
<ResourceCompile Include="..\version.rc">
|
||||||
|
|
|
@ -3290,5 +3290,18 @@ forward OnAutoConfigsBuffered();
|
||||||
*/
|
*/
|
||||||
native AutoExecConfig(bool:autoCreate = true, const name[] = "", const folder[] = "");
|
native AutoExecConfig(bool:autoCreate = true, const name[] = "", const folder[] = "");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a single use hook for the next frame.
|
||||||
|
*
|
||||||
|
* @param callback Function to be executed on the next frame.
|
||||||
|
* @param data Optional data to be passed to the callback function.
|
||||||
|
*
|
||||||
|
* @note Callback function prototype:
|
||||||
|
* public function(data)
|
||||||
|
*
|
||||||
|
* @noreturn
|
||||||
|
*/
|
||||||
|
native RequestFrame(const callback[], any:data = 0);
|
||||||
|
|
||||||
// Always keep this at the bottom of this file
|
// Always keep this at the bottom of this file
|
||||||
#include <message_stocks>
|
#include <message_stocks>
|
||||||
|
|
66
plugins/testsuite/request_frame_test.sma
Normal file
66
plugins/testsuite/request_frame_test.sma
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
#include <amxmodx>
|
||||||
|
#include <fakemeta>
|
||||||
|
|
||||||
|
/*
|
||||||
|
Expected console output:
|
||||||
|
|
||||||
|
Command_Test - Frame: X
|
||||||
|
FrameCallback1 - Frame: X + 1 Data: 100
|
||||||
|
FrameCallback2 - Frame: X + 2 Data: 200
|
||||||
|
FrameCallback3 - Frame: X + 2 Data: 300
|
||||||
|
FrameCallback4 - Frame: X + 3 Data: 400
|
||||||
|
FrameCallback4 - Frame: X + 3 Data: 500
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
new g_frameNumber = 0;
|
||||||
|
|
||||||
|
public plugin_precache()
|
||||||
|
{
|
||||||
|
register_forward(FM_StartFrame, "OnStartFrame", false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("RequestFrame() Test", "1.0.0", "KliPPy");
|
||||||
|
|
||||||
|
register_concmd("request_frame_test", "Command_Test");
|
||||||
|
}
|
||||||
|
|
||||||
|
public OnStartFrame()
|
||||||
|
{
|
||||||
|
g_frameNumber++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Command_Test()
|
||||||
|
{
|
||||||
|
console_print(0, "Command_Test - Frame: %d", g_frameNumber);
|
||||||
|
|
||||||
|
RequestFrame("FrameCallback1", 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrameCallback1(data)
|
||||||
|
{
|
||||||
|
console_print(0, "FrameCallback1 - Frame: %d Data: %d", g_frameNumber, data);
|
||||||
|
|
||||||
|
RequestFrame("FrameCallback2", 200);
|
||||||
|
RequestFrame("FrameCallback3", 300);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrameCallback2(data)
|
||||||
|
{
|
||||||
|
console_print(0, "FrameCallback2 - Frame: %d Data: %d", g_frameNumber, data);
|
||||||
|
RequestFrame("FrameCallback4", 400);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrameCallback3(data)
|
||||||
|
{
|
||||||
|
console_print(0, "FrameCallback3 - Frame: %d Data: %d", g_frameNumber, data);
|
||||||
|
RequestFrame("FrameCallback4", 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FrameCallback4(data)
|
||||||
|
{
|
||||||
|
console_print(0, "FrameCallback4 - Frame: %d Data: %d", g_frameNumber, data);
|
||||||
|
}
|
||||||
|
|
|
@ -267,6 +267,7 @@ scripting_files = [
|
||||||
'testsuite/textparse_test.sma',
|
'testsuite/textparse_test.sma',
|
||||||
'testsuite/textparse_test.cfg',
|
'testsuite/textparse_test.cfg',
|
||||||
'testsuite/textparse_test.ini',
|
'testsuite/textparse_test.ini',
|
||||||
|
'testsuite/request_frame_test.sma',
|
||||||
'include/amxconst.inc',
|
'include/amxconst.inc',
|
||||||
'include/amxmisc.inc',
|
'include/amxmisc.inc',
|
||||||
'include/amxmodx.inc',
|
'include/amxmodx.inc',
|
||||||
|
|
Loading…
Reference in New Issue
Block a user