small rewrite of how keyvalues iterator and get deleted. phew!
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40759
This commit is contained in:
parent
2f14014f3f
commit
3493467771
@ -389,7 +389,7 @@ static cell_t smn_KvJumpToKey(IPluginContext *pCtx, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t smn_KvJumpFirstSubKey(IPluginContext *pCtx, const cell_t *params)
|
static cell_t smn_KvGotoFirstSubKey(IPluginContext *pCtx, const cell_t *params)
|
||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
HandleError herr;
|
HandleError herr;
|
||||||
@ -406,7 +406,14 @@ static cell_t smn_KvJumpFirstSubKey(IPluginContext *pCtx, const cell_t *params)
|
|||||||
}
|
}
|
||||||
|
|
||||||
KeyValues *pSubKey = pStk->pCurRoot.front();
|
KeyValues *pSubKey = pStk->pCurRoot.front();
|
||||||
KeyValues *pFirstSubKey = pSubKey->GetFirstSubKey();
|
KeyValues *pFirstSubKey;
|
||||||
|
if (params[2])
|
||||||
|
{
|
||||||
|
pFirstSubKey = pSubKey->GetFirstTrueSubKey();
|
||||||
|
} else {
|
||||||
|
pFirstSubKey = pSubKey->GetFirstSubKey();
|
||||||
|
}
|
||||||
|
|
||||||
if (!pFirstSubKey)
|
if (!pFirstSubKey)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@ -416,6 +423,39 @@ static cell_t smn_KvJumpFirstSubKey(IPluginContext *pCtx, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t smn_KvGotoNextKey(IPluginContext *pCtx, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError herr;
|
||||||
|
HandleSecurity sec;
|
||||||
|
KeyValueStack *pStk;
|
||||||
|
|
||||||
|
sec.pOwner = NULL;
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
|
||||||
|
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues *pSubKey = pStk->pCurRoot.front();
|
||||||
|
if (params[2])
|
||||||
|
{
|
||||||
|
pSubKey = pSubKey->GetNextKey();
|
||||||
|
} else {
|
||||||
|
pSubKey = pSubKey->GetNextTrueSubKey();
|
||||||
|
}
|
||||||
|
if (!pSubKey)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
pStk->pCurRoot.pop();
|
||||||
|
pStk->pCurRoot.push(pSubKey);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
|
static cell_t smn_KvJumpNextSubKey(IPluginContext *pCtx, const cell_t *params)
|
||||||
{
|
{
|
||||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
@ -679,10 +719,35 @@ static cell_t smn_KvDeleteThis(IPluginContext *pContext, const cell_t *params)
|
|||||||
|
|
||||||
KeyValues *pValues = pStk->pCurRoot.front();
|
KeyValues *pValues = pStk->pCurRoot.front();
|
||||||
pStk->pCurRoot.pop();
|
pStk->pCurRoot.pop();
|
||||||
pStk->pCurRoot.front()->RemoveSubKey(pValues);
|
KeyValues *pRoot = pStk->pCurRoot.front();
|
||||||
pValues->deleteThis();
|
|
||||||
|
|
||||||
return 1;
|
/* We have to manually verify this since Valve sucks
|
||||||
|
* :TODO: make our own KeyValues.h file and make
|
||||||
|
* the sub stuff private so we can do this ourselves!
|
||||||
|
*/
|
||||||
|
KeyValues *sub = pRoot->GetFirstSubKey();
|
||||||
|
while (sub)
|
||||||
|
{
|
||||||
|
if (sub == pValues)
|
||||||
|
{
|
||||||
|
KeyValues *pNext = pValues->GetNextKey();
|
||||||
|
pRoot->RemoveSubKey(pValues);
|
||||||
|
pValues->deleteThis();
|
||||||
|
if (pNext)
|
||||||
|
{
|
||||||
|
pStk->pCurRoot.push(pNext);
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sub = sub->GetNextKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Push this back on :( */
|
||||||
|
pStk->pCurRoot.push(pValues);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
|
static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
|
||||||
@ -722,6 +787,33 @@ static cell_t smn_KvDeleteKey(IPluginContext *pContext, const cell_t *params)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static cell_t smn_KvSavePosition(IPluginContext *pContext, const cell_t *params)
|
||||||
|
{
|
||||||
|
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||||
|
HandleError herr;
|
||||||
|
HandleSecurity sec;
|
||||||
|
KeyValueStack *pStk;
|
||||||
|
|
||||||
|
sec.pOwner = NULL;
|
||||||
|
sec.pIdentity = g_pCoreIdent;
|
||||||
|
|
||||||
|
if ((herr=g_HandleSys.ReadHandle(hndl, g_KeyValueType, &sec, (void **)&pStk))
|
||||||
|
!= HandleError_None)
|
||||||
|
{
|
||||||
|
return pContext->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pStk->pCurRoot.size() < 2)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
KeyValues *pValues = pStk->pCurRoot.front();
|
||||||
|
pStk->pCurRoot.push(pValues);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static KeyValueNatives s_KeyValueNatives;
|
static KeyValueNatives s_KeyValueNatives;
|
||||||
|
|
||||||
REGISTER_NATIVES(keyvaluenatives)
|
REGISTER_NATIVES(keyvaluenatives)
|
||||||
@ -738,8 +830,10 @@ REGISTER_NATIVES(keyvaluenatives)
|
|||||||
{"KvGetUint64", smn_KvGetUint64},
|
{"KvGetUint64", smn_KvGetUint64},
|
||||||
{"CreateKeyValues", smn_CreateKeyValues},
|
{"CreateKeyValues", smn_CreateKeyValues},
|
||||||
{"KvJumpToKey", smn_KvJumpToKey},
|
{"KvJumpToKey", smn_KvJumpToKey},
|
||||||
{"KvJumpFirstSubKey", smn_KvJumpFirstSubKey},
|
{"KvGotoNextKey", smn_KvGotoNextKey},
|
||||||
{"KvJumpNextSubKey", smn_KvJumpNextSubKey},
|
{"KvJumpFirstSubKey", smn_KvGotoFirstSubKey}, /* BACKWARDS COMPAT SHIM */
|
||||||
|
{"KvGotoFirstSubKey", smn_KvGotoFirstSubKey},
|
||||||
|
{"KvJumpNextSubKey", smn_KvJumpNextSubKey}, /* BACKWARDS COMPAT SHIM */
|
||||||
{"KvGoBack", smn_KvGoBack},
|
{"KvGoBack", smn_KvGoBack},
|
||||||
{"KvRewind", smn_KvRewind},
|
{"KvRewind", smn_KvRewind},
|
||||||
{"KvGetSectionName", smn_KvGetSectionName},
|
{"KvGetSectionName", smn_KvGetSectionName},
|
||||||
@ -751,5 +845,6 @@ REGISTER_NATIVES(keyvaluenatives)
|
|||||||
{"KvDeleteThis", smn_KvDeleteThis},
|
{"KvDeleteThis", smn_KvDeleteThis},
|
||||||
{"KvDeleteKey", smn_KvDeleteKey},
|
{"KvDeleteKey", smn_KvDeleteKey},
|
||||||
{"KvNodesInStack", smn_KvNodesInStack},
|
{"KvNodesInStack", smn_KvNodesInStack},
|
||||||
|
{"KvSavePosition", smn_KvSavePosition},
|
||||||
{NULL, NULL}
|
{NULL, NULL}
|
||||||
};
|
};
|
||||||
|
@ -176,21 +176,37 @@ native bool:KvJumpToKey(Handle:kv, const String:key[], bool:create=false);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current position in the KeyValues tree to the first sub key.
|
* Sets the current position in the KeyValues tree to the first sub key.
|
||||||
|
* This native adds to the internal traversal stack.
|
||||||
*
|
*
|
||||||
* @param kv KeyValues Handle.
|
* @param kv KeyValues Handle.
|
||||||
|
* @param keyOnly If false, non-keys will be traversed (values).
|
||||||
* @return True on success, false if there was no first sub key.
|
* @return True on success, false if there was no first sub key.
|
||||||
* @error Invalid Handle.
|
* @error Invalid Handle.
|
||||||
*/
|
*/
|
||||||
native bool:KvJumpFirstSubKey(Handle:kv);
|
native bool:KvGotoFirstSubKey(Handle:kv, bool:keyOnly=true);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current position in the KeyValues tree to the next sub key.
|
* Sets the current position in the KeyValues tree to the next sub key.
|
||||||
|
* This native does NOT add to the internal traversal stack, and thus
|
||||||
|
* KvGoBack() is not needed for each successive call to this function.
|
||||||
*
|
*
|
||||||
* @param kv KeyValues Handle.
|
* @param kv KeyValues Handle.
|
||||||
|
* @param keyOnly If false, non-keys will be traversed (values).
|
||||||
* @return True on success, false if there was no next sub key.
|
* @return True on success, false if there was no next sub key.
|
||||||
* @error Invalid Handle.
|
* @error Invalid Handle.
|
||||||
*/
|
*/
|
||||||
native bool:KvJumpNextSubKey(Handle:kv);
|
native bool:KvGotoNextKey(Handle:kv, bool:keyOnly=true);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saves the current position in the traversal stack onto the traversal
|
||||||
|
* stack. This can be useful if you wish to use KvGotoNextKey() and
|
||||||
|
* have the previous key saved for backwards traversal.
|
||||||
|
*
|
||||||
|
* @param kv KeyValues Handle.
|
||||||
|
* @noreturn
|
||||||
|
* @error Invalid Handle.
|
||||||
|
*/
|
||||||
|
native KvSavePosition(Handle:kv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given key from the current position.
|
* Removes the given key from the current position.
|
||||||
@ -203,19 +219,27 @@ native bool:KvJumpNextSubKey(Handle:kv);
|
|||||||
native bool:KvDeleteKey(Handle:kv, const String:key[]);
|
native bool:KvDeleteKey(Handle:kv, const String:key[]);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the current sub-key and jumps back one position, using the previous
|
* Removes the current sub-key and attempts to set the position
|
||||||
* position as the search point. This will not work if used on the root node.
|
* to the sub-key after the removed one. If no such sub-key exists,
|
||||||
|
* the position will be the parent key in the traversal stack.
|
||||||
|
* Given the sub-key having position "N" in the traversal stack, the
|
||||||
|
* removal will always take place from position "N-1."
|
||||||
*
|
*
|
||||||
* @param kv KeyValues Handle.
|
* @param kv KeyValues Handle.
|
||||||
* @return True on success, false if there was no sub key.
|
* @return 1 if removal succeeded and there was another key.
|
||||||
|
* 0 if the current node was not contained in the
|
||||||
|
* previous node, or no previous node exists.
|
||||||
|
* -1 if removal succeeded and there were no more keys,
|
||||||
|
* thus the state is as if KvGoBack() was called.
|
||||||
* @error Invalid Handle.
|
* @error Invalid Handle.
|
||||||
*/
|
*/
|
||||||
native bool:KvDeleteThis(Handle:kv);
|
native KvDeleteThis(Handle:kv);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Jumps back to the previous position. Returns false if there are no
|
* Jumps back to the previous position. Returns false if there are no
|
||||||
* previous positions (i.e., at the root node). This should be called
|
* previous positions (i.e., at the root node). This should be called
|
||||||
* once for each successful Jump call, in order to return to the top node.
|
* once for each successful Jump call, in order to return to the top node.
|
||||||
|
* This function pops one node off the internal traversal stack.
|
||||||
*
|
*
|
||||||
* @param kv KeyValues Handle.
|
* @param kv KeyValues Handle.
|
||||||
* @return True on success, false if there is no higher node.
|
* @return True on success, false if there is no higher node.
|
||||||
|
Loading…
Reference in New Issue
Block a user