Merge pull request #240 from Nextra/kvd

Improve handling of KeyValueData
This commit is contained in:
Vincent Herbet 2015-05-05 12:01:29 +02:00
commit 39cc240a4e
7 changed files with 109 additions and 27 deletions

View File

@ -72,12 +72,14 @@ static cell AMX_NATIVE_CALL dllfunc(AMX *amx,cell *params)
index=cRet[0]; index=cRet[0];
CHECK_ENTITY(index); CHECK_ENTITY(index);
cRet = MF_GetAmxAddr(amx, params[3]); cRet = MF_GetAmxAddr(amx, params[3]);
KVD_Wrapper *kvdw;
KeyValueData *kvd;
if (*cRet == 0) if (*cRet == 0)
kvdw = &g_kvd_glb; kvd = &(g_kvd_glb.kvd);
else else
kvdw = reinterpret_cast<KVD_Wrapper *>(*cRet); kvd = reinterpret_cast<KeyValueData *>(*cRet);
gpGamedllFuncs->dllapi_table->pfnKeyValue(INDEXENT2(index), kvdw->kvd);
gpGamedllFuncs->dllapi_table->pfnKeyValue(INDEXENT2(index), kvd);
return 1; return 1;
} }

View File

@ -29,13 +29,16 @@ void OnAmxxAttach()
MF_AddNatives(glb_natives); MF_AddNatives(glb_natives);
MF_AddNatives(ext2_natives); MF_AddNatives(ext2_natives);
MF_AddNatives(misc_natives); MF_AddNatives(misc_natives);
g_kvd_2.szClassName = ""; g_kvd_glb.kvd.szClassName = const_cast<char *>(g_kvd_glb.cls.chars());
g_kvd_2.szKeyName = ""; g_kvd_glb.kvd.szKeyName = const_cast<char *>(g_kvd_glb.key.chars());
g_kvd_2.szValue = ""; g_kvd_glb.kvd.szValue = const_cast<char *>(g_kvd_glb.val.chars());
g_kvd_glb.kvd = &g_kvd_2; g_kvd_glb.kvd.fHandled = 0;
} }
extern CStack<TraceResult *> g_FreeTRs; extern CStack<TraceResult *> g_FreeTRs;
extern ke::Vector<KVD_Wrapper *> g_KVDWs;
extern ke::Vector<KVD_Wrapper *> g_FreeKVDWs;
void OnAmxxDetach() void OnAmxxDetach()
{ {
while (!g_FreeTRs.empty()) while (!g_FreeTRs.empty())
@ -43,6 +46,12 @@ void OnAmxxDetach()
delete g_FreeTRs.front(); delete g_FreeTRs.front();
g_FreeTRs.pop(); g_FreeTRs.pop();
} }
while (!g_KVDWs.empty())
delete g_KVDWs.popCopy();
while (!g_FreeKVDWs.empty())
delete g_FreeKVDWs.popCopy();
} }
int GetHullBounds(int hullnumber, float *mins, float *maxs); int GetHullBounds(int hullnumber, float *mins, float *maxs);

View File

@ -20,7 +20,6 @@ extern TraceResult *gfm_tr;
//these also don't fit in here but gaben does not care. GABEN DOES NOT CARE!!! //these also don't fit in here but gaben does not care. GABEN DOES NOT CARE!!!
extern TraceResult g_tr_2; extern TraceResult g_tr_2;
extern KeyValueData g_kvd_2;
extern clientdata_t g_cd_glb; extern clientdata_t g_cd_glb;
extern clientdata_t *g_cd_hook; extern clientdata_t *g_cd_hook;
extern entity_state_t g_es_glb; extern entity_state_t g_es_glb;
@ -30,14 +29,13 @@ extern usercmd_t *g_uc_hook;
struct KVD_Wrapper struct KVD_Wrapper
{ {
KeyValueData *kvd; KeyValueData kvd;
ke::AString cls; ke::AString cls;
ke::AString key; ke::AString key;
ke::AString val; ke::AString val;
}; };
extern KVD_Wrapper g_kvd_glb; extern KVD_Wrapper g_kvd_glb;
extern KVD_Wrapper g_kvd_hook;
enum enum
{ {

View File

@ -15,9 +15,12 @@
#include "sh_stack.h" #include "sh_stack.h"
TraceResult g_tr_2; TraceResult g_tr_2;
KeyValueData g_kvd_2;
KVD_Wrapper g_kvd_glb; KVD_Wrapper g_kvd_glb;
KVD_Wrapper g_kvd_ext;
ke::Vector<KVD_Wrapper *>g_KVDWs;
ke::Vector<KVD_Wrapper *>g_FreeKVDWs;
clientdata_t g_cd_glb; clientdata_t g_cd_glb;
entity_state_t g_es_glb; entity_state_t g_es_glb;
@ -206,13 +209,11 @@ static cell AMX_NATIVE_CALL get_tr2(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL get_kvd(AMX *amx, cell *params) static cell AMX_NATIVE_CALL get_kvd(AMX *amx, cell *params)
{ {
KVD_Wrapper *kvdw;
KeyValueData *kvd; KeyValueData *kvd;
if (params[1] == 0) if (params[1] == 0)
kvdw = &g_kvd_glb; kvd = &(g_kvd_glb.kvd);
else else
kvdw = reinterpret_cast<KVD_Wrapper *>(params[1]); kvd = reinterpret_cast<KeyValueData *>(params[1]);
kvd = kvdw->kvd;
switch (params[2]) switch (params[2])
{ {
@ -263,13 +264,26 @@ static cell AMX_NATIVE_CALL get_kvd(AMX *amx, cell *params)
static cell AMX_NATIVE_CALL set_kvd(AMX *amx, cell *params) static cell AMX_NATIVE_CALL set_kvd(AMX *amx, cell *params)
{ {
KVD_Wrapper *kvdw; KVD_Wrapper *kvdw = nullptr;
KeyValueData *kvd; KeyValueData *kvd = nullptr;
if (params[1] == 0)
KVD_Wrapper *tmpw = reinterpret_cast<KVD_Wrapper *>(params[1]);
if (params[1] == 0 || tmpw == &g_kvd_glb) {
kvdw = &g_kvd_glb; kvdw = &g_kvd_glb;
else kvd = &(kvdw->kvd);
kvdw = reinterpret_cast<KVD_Wrapper *>(params[1]); } else {
kvd = kvdw->kvd; for (size_t i = 0; i < g_KVDWs.length(); ++i) {
if (g_KVDWs[i] == tmpw) {
kvdw = tmpw;
kvd = &(kvdw->kvd);
}
}
if (kvdw == nullptr) {
kvdw = &g_kvd_ext;
kvd = reinterpret_cast<KeyValueData *>(tmpw);
}
}
if (*params / sizeof(cell) < 3) if (*params / sizeof(cell) < 3)
{ {
@ -1257,12 +1271,55 @@ static cell AMX_NATIVE_CALL free_tr2(AMX *amx, cell *params)
return 1; return 1;
} }
static cell AMX_NATIVE_CALL create_kvd(AMX *amx, cell *params)
{
KVD_Wrapper *kvdw;
if (g_FreeKVDWs.empty()) {
kvdw = new KVD_Wrapper;
} else {
kvdw = g_FreeKVDWs.popCopy();
}
kvdw->cls = "";
kvdw->kvd.szClassName = const_cast<char*>(kvdw->cls.chars());
kvdw->key = "";
kvdw->kvd.szKeyName = const_cast<char*>(kvdw->key.chars());
kvdw->val = "";
kvdw->kvd.szValue = const_cast<char*>(kvdw->val.chars());
kvdw->kvd.fHandled = 0;
g_KVDWs.append(kvdw);
return reinterpret_cast<cell>(kvdw);
}
static cell AMX_NATIVE_CALL free_kvd(AMX *amx, cell *params) {
if (params[1] == 0) {
return 0;
}
KVD_Wrapper *kvdw = reinterpret_cast<KVD_Wrapper *>(params[1]);
for (size_t i = 0; i < g_KVDWs.length(); ++i) {
if (g_KVDWs[i] == kvdw) {
g_KVDWs.remove(i);
g_FreeKVDWs.append(kvdw);
return 1;
}
}
return 0;
}
AMX_NATIVE_INFO ext2_natives[] = AMX_NATIVE_INFO ext2_natives[] =
{ {
{"create_tr2", create_tr2}, {"create_tr2", create_tr2},
{"free_tr2", free_tr2}, {"free_tr2", free_tr2},
{"get_tr2", get_tr2}, {"get_tr2", get_tr2},
{"set_tr2", set_tr2}, {"set_tr2", set_tr2},
{"create_kvd", create_kvd},
{"free_kvd", free_kvd},
{"get_kvd", get_kvd}, {"get_kvd", get_kvd},
{"set_kvd", set_kvd}, {"set_kvd", set_kvd},
{"get_cd", get_cd}, {"get_cd", get_cd},

View File

@ -262,15 +262,13 @@ typedef struct KeyValueData_s
*/ */
void KeyValue(edict_t* entity, KeyValueData* data) void KeyValue(edict_t* entity, KeyValueData* data)
{ {
g_kvd_hook.kvd = data; FM_ENG_HANDLE(FM_KeyValue, (Engine[FM_KeyValue].at(i), (cell)ENTINDEX(entity), (cell)(data)));
FM_ENG_HANDLE(FM_KeyValue, (Engine[FM_KeyValue].at(i), (cell)ENTINDEX(entity), (cell)(&g_kvd_hook)));
RETURN_META(mswi(lastFmRes)); RETURN_META(mswi(lastFmRes));
} }
void KeyValue_post(edict_t* entity, KeyValueData* data) void KeyValue_post(edict_t* entity, KeyValueData* data)
{ {
g_kvd_hook.kvd = data; FM_ENG_HANDLE_POST(FM_KeyValue, (EnginePost[FM_KeyValue].at(i), (cell)ENTINDEX(entity), (cell)(data)));
FM_ENG_HANDLE_POST(FM_KeyValue, (EnginePost[FM_KeyValue].at(i), (cell)ENTINDEX(entity), (cell)(&g_kvd_hook)));
RETURN_META(MRES_IGNORED); RETURN_META(MRES_IGNORED);
} }

View File

@ -473,6 +473,24 @@ native get_kvd(kvd_handle, KeyValueData:member, any:...);
// keyvalues structure rather than changing the internal engine strings. // keyvalues structure rather than changing the internal engine strings.
native set_kvd(kvd_handle, KeyValueData:member, any:...); native set_kvd(kvd_handle, KeyValueData:member, any:...);
/**
* Creates a KeyValueData handle.
*
* @note Handles should be freed using free_kvd().
*
* @return New KeyValueData handle
*/
native create_kvd();
/**
* Frees a KeyValueData handle.
*
* @param kvd_handle KeyValueData handle
*
* @noreturn
*/
native free_kvd(kvd_handle);
// These functions are used with the clientdata data structure (FM_UpdateClientData) // These functions are used with the clientdata data structure (FM_UpdateClientData)
// Get: 0 extra params - Return integer; 1 extra param - by ref float or vector; 2 extra params - string and length // Get: 0 extra params - Return integer; 1 extra param - by ref float or vector; 2 extra params - string and length
// Set: Use anything // Set: Use anything

View File

@ -70,7 +70,7 @@ enum Ham
/** /**
* Description: Typically this is similar to an engine keyvalue call. * Description: Typically this is similar to an engine keyvalue call.
* Use the kvd natives from fakemeta to handle the kvd_handle passed. * Use the kvd natives from fakemeta to handle the kvd_handle passed.
* NOTE: Do not pass handle 0 to this! Use get_kvd_handle(0) from fakemeta instead! * NOTE: Do not pass handle 0 to this! Use create_kvd() from fakemeta instead!
* Forward params: function(this, kvd_handle); * Forward params: function(this, kvd_handle);
* Return type: None. * Return type: None.
* Execute params: ExecuteHam(Ham_Keyvalue, this, kvd_handle); * Execute params: ExecuteHam(Ham_Keyvalue, this, kvd_handle);