Merge pull request #369 from Ni3znajomy/forwards/value-by-reference
Values by reference in forwards
This commit is contained in:
commit
f3c58b7cd6
|
@ -59,7 +59,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
if (pDebugger)
|
if (pDebugger)
|
||||||
pDebugger->BeginExec();
|
pDebugger->BeginExec();
|
||||||
|
|
||||||
// handle strings & arrays
|
// handle strings & arrays & values by reference
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
@ -70,7 +70,7 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
cell *tmp;
|
cell *tmp;
|
||||||
if (!str)
|
if (!str)
|
||||||
str = "";
|
str = "";
|
||||||
amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
amx_Allot(amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
|
||||||
amx_SetStringOld(tmp, str, 0, 0);
|
amx_SetStringOld(tmp, str, 0, 0);
|
||||||
physAddrs[i] = tmp;
|
physAddrs[i] = tmp;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,24 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_CELL_BYREF || m_ParamTypes[i] == FP_FLOAT_BYREF)
|
||||||
|
{
|
||||||
|
cell *tmp;
|
||||||
|
amx_Allot(amx, 1, &realParams[i], &tmp);
|
||||||
|
physAddrs[i] = tmp;
|
||||||
|
|
||||||
|
if (m_ParamTypes[i] == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
memcpy(tmp, reinterpret_cast<cell *>(params[i]), sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(tmp, reinterpret_cast<REAL *>(params[i]), sizeof(REAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
realParams[i] = params[i];
|
realParams[i] = params[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,18 +144,18 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
if (pDebugger)
|
if (pDebugger)
|
||||||
pDebugger->EndExec();
|
pDebugger->EndExec();
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays & values by reference
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
{
|
{
|
||||||
if (m_ParamTypes[i] == FP_STRING)
|
if (m_ParamTypes[i] == FP_STRING)
|
||||||
{
|
{
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(amx, realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_STRINGEX)
|
else if (m_ParamTypes[i] == FP_STRINGEX)
|
||||||
{
|
{
|
||||||
// copy back
|
// copy back
|
||||||
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(amx, realParams[i]);
|
||||||
}
|
}
|
||||||
else if (m_ParamTypes[i] == FP_ARRAY)
|
else if (m_ParamTypes[i] == FP_ARRAY)
|
||||||
{
|
{
|
||||||
|
@ -156,7 +173,21 @@ cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
*data++ = static_cast<char>(*tmp++ & 0xFF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
amx_Release(iter->pPlugin->getAMX(), realParams[i]);
|
amx_Release(amx, realParams[i]);
|
||||||
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_CELL_BYREF || m_ParamTypes[i] == FP_FLOAT_BYREF)
|
||||||
|
{
|
||||||
|
//copy back
|
||||||
|
cell *tmp = physAddrs[i];
|
||||||
|
if (m_ParamTypes[i] == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<cell *>(params[i]), tmp, sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<REAL *>(params[i]), tmp, sizeof(REAL));
|
||||||
|
}
|
||||||
|
amx_Release(amx, realParams[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +267,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
if (pDebugger)
|
if (pDebugger)
|
||||||
pDebugger->BeginExec();
|
pDebugger->BeginExec();
|
||||||
|
|
||||||
// handle strings & arrays
|
// handle strings & arrays & values by reference
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
|
@ -266,7 +297,24 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
|
||||||
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_CELL_BYREF || m_ParamTypes[i] == FP_FLOAT_BYREF)
|
||||||
|
{
|
||||||
|
cell *tmp;
|
||||||
|
amx_Allot(m_Amx, 1, &realParams[i], &tmp);
|
||||||
|
physAddrs[i] = tmp;
|
||||||
|
|
||||||
|
if (m_ParamTypes[i] == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
memcpy(tmp, reinterpret_cast<cell *>(params[i]), sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(tmp, reinterpret_cast<REAL *>(params[i]), sizeof(REAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
realParams[i] = params[i];
|
realParams[i] = params[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -300,7 +348,7 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
|
|
||||||
m_Amx->error = AMX_ERR_NONE;
|
m_Amx->error = AMX_ERR_NONE;
|
||||||
|
|
||||||
// cleanup strings & arrays
|
// cleanup strings & arrays & values by reference
|
||||||
for (i = 0; i < m_NumParams; ++i)
|
for (i = 0; i < m_NumParams; ++i)
|
||||||
{
|
{
|
||||||
if (m_ParamTypes[i] == FP_STRING)
|
if (m_ParamTypes[i] == FP_STRING)
|
||||||
|
@ -331,6 +379,20 @@ cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
|
||||||
}
|
}
|
||||||
amx_Release(m_Amx, realParams[i]);
|
amx_Release(m_Amx, realParams[i]);
|
||||||
}
|
}
|
||||||
|
else if (m_ParamTypes[i] == FP_CELL_BYREF || m_ParamTypes[i] == FP_FLOAT_BYREF)
|
||||||
|
{
|
||||||
|
//copy back
|
||||||
|
cell *tmp = physAddrs[i];
|
||||||
|
if (m_ParamTypes[i] == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<cell *>(params[i]), tmp, sizeof(cell));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
memcpy(reinterpret_cast<REAL *>(params[i]), tmp, sizeof(REAL));
|
||||||
|
}
|
||||||
|
amx_Release(m_Amx, realParams[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_InExec = false;
|
m_InExec = false;
|
||||||
|
@ -683,13 +745,26 @@ cell executeForwards(int id, ...)
|
||||||
|
|
||||||
va_list argptr;
|
va_list argptr;
|
||||||
va_start(argptr, id);
|
va_start(argptr, id);
|
||||||
|
|
||||||
|
ForwardParam param_type;
|
||||||
|
|
||||||
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
for (int i = 0; i < paramsNum && i < FORWARD_MAX_PARAMS; ++i)
|
||||||
{
|
{
|
||||||
if (g_forwards.getParamType(id, i) == FP_FLOAT)
|
param_type = g_forwards.getParamType(id, i);
|
||||||
|
if (param_type == FP_FLOAT)
|
||||||
{
|
{
|
||||||
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
REAL tmp = (REAL)va_arg(argptr, double); // floats get converted to doubles
|
||||||
params[i] = *(cell*)&tmp;
|
params[i] = amx_ftoc(tmp);
|
||||||
|
}
|
||||||
|
else if(param_type == FP_FLOAT_BYREF)
|
||||||
|
{
|
||||||
|
REAL *tmp = reinterpret_cast<REAL *>(va_arg(argptr, double*));
|
||||||
|
params[i] = reinterpret_cast<cell>(tmp);
|
||||||
|
}
|
||||||
|
else if(param_type == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
cell *tmp = reinterpret_cast<cell *>(va_arg(argptr, cell*));
|
||||||
|
params[i] = reinterpret_cast<cell>(tmp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
params[i] = (cell)va_arg(argptr, cell);
|
params[i] = (cell)va_arg(argptr, cell);
|
||||||
|
|
|
@ -46,6 +46,8 @@ enum ForwardParam
|
||||||
FP_STRING, // string
|
FP_STRING, // string
|
||||||
FP_STRINGEX, // string; will be updated to the last function's value
|
FP_STRINGEX, // string; will be updated to the last function's value
|
||||||
FP_ARRAY, // array; use the return value of prepareArray.
|
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
|
// for prepareArray
|
||||||
|
|
|
@ -4155,9 +4155,13 @@ static cell AMX_NATIVE_CALL ExecuteForward(AMX *amx, cell *params)
|
||||||
LogError(amx, AMX_ERR_NATIVE, "Expected %d parameters, got %d", g_forwards.getParamsNum(id), count-2);
|
LogError(amx, AMX_ERR_NATIVE, "Expected %d parameters, got %d", g_forwards.getParamsNum(id), count-2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ForwardParam param_type;
|
||||||
|
|
||||||
for (cell i=3; i<=count; i++)
|
for (cell i=3; i<=count; i++)
|
||||||
{
|
{
|
||||||
if (g_forwards.getParamType(id, i-3) == FP_STRING)
|
param_type = g_forwards.getParamType(id, i-3);
|
||||||
|
if (param_type == FP_STRING)
|
||||||
{
|
{
|
||||||
char *tmp = get_amxstring(amx, params[i], 0, len);
|
char *tmp = get_amxstring(amx, params[i], 0, len);
|
||||||
cell num = len / sizeof(cell) + 1;
|
cell num = len / sizeof(cell) + 1;
|
||||||
|
@ -4168,7 +4172,14 @@ static cell AMX_NATIVE_CALL ExecuteForward(AMX *amx, cell *params)
|
||||||
}
|
}
|
||||||
strcpy((char *)allots[i-3].phys_addr, tmp);
|
strcpy((char *)allots[i-3].phys_addr, tmp);
|
||||||
ps[i-3] = (cell)allots[i-3].phys_addr;
|
ps[i-3] = (cell)allots[i-3].phys_addr;
|
||||||
} else {
|
}
|
||||||
|
else if (param_type == FP_CELL_BYREF)
|
||||||
|
{
|
||||||
|
cell *temp = get_amxaddr(amx, params[i]);
|
||||||
|
ps[i-3] = reinterpret_cast<cell>(temp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ps[i-3] = *get_amxaddr(amx, params[i]);
|
ps[i-3] = *get_amxaddr(amx, params[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -403,6 +403,7 @@ enum
|
||||||
#define FP_FLOAT 1
|
#define FP_FLOAT 1
|
||||||
#define FP_STRING 2
|
#define FP_STRING 2
|
||||||
#define FP_ARRAY 4
|
#define FP_ARRAY 4
|
||||||
|
#define FP_VAL_BYREF 5 //cell & float are handled in the same way
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @endsection
|
* @endsection
|
||||||
|
@ -450,4 +451,4 @@ enum HashType
|
||||||
Hash_Keccak_512 // Provides Keccak 512 bit hashing
|
Hash_Keccak_512 // Provides Keccak 512 bit hashing
|
||||||
};
|
};
|
||||||
|
|
||||||
#include <cstrike_const> // To keep backward compatibility
|
#include <cstrike_const> // To keep backward compatibility
|
||||||
|
|
61
plugins/testsuite/fwdreftest1.sma
Normal file
61
plugins/testsuite/fwdreftest1.sma
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <amxmodx>
|
||||||
|
|
||||||
|
new g_hMultiForward;
|
||||||
|
new g_hOneForward;
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("Forward Test (Reference) (1)", "1.0", "Ni3znajomy");
|
||||||
|
|
||||||
|
g_hMultiForward = CreateMultiForward("multi_forward_reference", ET_IGNORE, FP_VAL_BYREF, FP_VAL_BYREF);
|
||||||
|
g_hOneForward = CreateOneForward(find_plugin_byfile("fwdreftest2.amxx"), "one_forward_reference", FP_VAL_BYREF, FP_VAL_BYREF);
|
||||||
|
|
||||||
|
register_srvcmd("fwdref_multi_test", "cmdForwardRefMultiTest");
|
||||||
|
register_srvcmd("fwdref_one_test", "cmdForwardRefOneTest");
|
||||||
|
}
|
||||||
|
|
||||||
|
public cmdForwardRefMultiTest()
|
||||||
|
{
|
||||||
|
new sTestValue[10];
|
||||||
|
|
||||||
|
read_argv(1, sTestValue, charsmax(sTestValue));
|
||||||
|
new iTestValue1 = str_to_num(sTestValue);
|
||||||
|
|
||||||
|
read_argv(2, sTestValue, charsmax(sTestValue));
|
||||||
|
new Float:fTestValue2 = str_to_float(sTestValue);
|
||||||
|
|
||||||
|
server_print("PLUGIN1: MULTI FORWARD START: val1 = %i | val2 = %f", iTestValue1, fTestValue2);
|
||||||
|
new dump;
|
||||||
|
ExecuteForward(g_hMultiForward, dump, iTestValue1, fTestValue2);
|
||||||
|
server_print("PLUGIN1: MULTI FORWARD END: val1 = %i | val2 = %f", iTestValue1, fTestValue2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public cmdForwardRefOneTest()
|
||||||
|
{
|
||||||
|
new sTestValue[10];
|
||||||
|
|
||||||
|
read_argv(1, sTestValue, charsmax(sTestValue));
|
||||||
|
new iTestValue1 = str_to_num(sTestValue);
|
||||||
|
|
||||||
|
read_argv(2, sTestValue, charsmax(sTestValue));
|
||||||
|
new Float:fTestValue2 = str_to_float(sTestValue);
|
||||||
|
|
||||||
|
server_print("PLUGIN1: ONE FORWARD START: val1 = %i | val2 = %f", iTestValue1, fTestValue2);
|
||||||
|
new dump;
|
||||||
|
ExecuteForward(g_hOneForward, dump, iTestValue1, fTestValue2);
|
||||||
|
server_print("PLUGIN1: ONE FORWARD END: val1 = %i | val2 = %f", iTestValue1, fTestValue2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
55
plugins/testsuite/fwdreftest2.sma
Normal file
55
plugins/testsuite/fwdreftest2.sma
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
#include <amxmodx>
|
||||||
|
|
||||||
|
new g_iTestValue1 = 0
|
||||||
|
new Float:g_fTestValue2 = 0.0;
|
||||||
|
|
||||||
|
public plugin_init()
|
||||||
|
{
|
||||||
|
register_plugin("Forward Test (Reference) (2)", "1.0", "Ni3znajomy");
|
||||||
|
|
||||||
|
register_srvcmd("fwdref_set_test_values", "cmdSetTestValues");
|
||||||
|
}
|
||||||
|
|
||||||
|
public cmdSetTestValues()
|
||||||
|
{
|
||||||
|
new sTestValue[10];
|
||||||
|
|
||||||
|
read_argv(1, sTestValue, charsmax(sTestValue));
|
||||||
|
g_iTestValue1 = str_to_num(sTestValue);
|
||||||
|
|
||||||
|
read_argv(2, sTestValue, charsmax(sTestValue));
|
||||||
|
g_fTestValue2 = str_to_float(sTestValue);
|
||||||
|
|
||||||
|
server_print("PLUGIN2: TEST VALUES: val1 = %i | val2 = %f", g_iTestValue1, g_fTestValue2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public multi_forward_reference(&val1, &Float:val2)
|
||||||
|
{
|
||||||
|
server_print("PLUGIN2: MULTI FORWARD START: val1 = %i | val2 = %f", val1, val2);
|
||||||
|
|
||||||
|
val1 = g_iTestValue1;
|
||||||
|
val2 = g_fTestValue2;
|
||||||
|
|
||||||
|
server_print("PLUGIN2: MULTI FORWARD END: val1 = %i | val2 = %f", val1, val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public one_forward_reference(&val1, &Float:val2)
|
||||||
|
{
|
||||||
|
server_print("PLUGIN2: ONE FORWARD START: val1 = %i | val2 = %f", val1, val2);
|
||||||
|
|
||||||
|
val1 = g_iTestValue1;
|
||||||
|
val2 = g_fTestValue2;
|
||||||
|
|
||||||
|
server_print("PLUGIN2: ONE FORWARD END: val1 = %i | val2 = %f", val1, val2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -2087,6 +2087,8 @@ enum ForwardParam
|
||||||
FP_STRING, // string
|
FP_STRING, // string
|
||||||
FP_STRINGEX, // string; will be updated to the last function's value
|
FP_STRINGEX, // string; will be updated to the last function's value
|
||||||
FP_ARRAY, // array; use the return value of prepareArray.
|
FP_ARRAY, // array; use the return value of prepareArray.
|
||||||
|
FP_CELL_BYREF, // cell; pass by reference
|
||||||
|
FP_FLOAT_BYREF, // float; pass by reference
|
||||||
};
|
};
|
||||||
|
|
||||||
enum PlayerProp
|
enum PlayerProp
|
||||||
|
|
Loading…
Reference in New Issue
Block a user