Merge pull request #240 from Nextra/kvd
Improve handling of KeyValueData
This commit is contained in:
		@@ -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;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user