diff --git a/core/smn_keyvalues.cpp b/core/smn_keyvalues.cpp index 8d018820a..c6eddc36a 100644 --- a/core/smn_keyvalues.cpp +++ b/core/smn_keyvalues.cpp @@ -669,9 +669,21 @@ static cell_t smn_KvRewind(IPluginContext *pCtx, const cell_t *params) return pCtx->ThrowNativeError("Invalid key value handle %x (error %d)", hndl, herr); } - while (pStk->pCurRoot.size() > 1) + // Older plugins do not have the clearHistory param + if (params[0] < 2 || params[2]) { - pStk->pCurRoot.pop(); + while (pStk->pCurRoot.size() > 1) + { + pStk->pCurRoot.pop(); + } + } + else + { + auto root = pStk->pCurRoot.begin(); + if (root != pStk->pCurRoot.end()) + { + pStk->pCurRoot.push(*root); + } } return 1; diff --git a/plugins/include/keyvalues.inc b/plugins/include/keyvalues.inc index 3906d45de..3ebda8c15 100644 --- a/plugins/include/keyvalues.inc +++ b/plugins/include/keyvalues.inc @@ -245,9 +245,9 @@ methodmap KeyValues < Handle public native bool SavePosition(); // Jumps back to the previous position. Returns false if there are no - // 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. - // This function pops one node off the internal traversal stack. + // previous positions (i.e., at the root node with an empty traversal stack). + // This should be called once for each successful Jump call, in order to return + // to the top node. This function pops one node off the internal traversal stack. // // @return True on success, false if there is no higher node. public native bool GoBack(); @@ -272,12 +272,14 @@ methodmap KeyValues < Handle // thus the state is as if KvGoBack() was called. public native int DeleteThis(); - // Sets the position back to the top node, emptying the entire node - // traversal history. This can be used instead of looping KvGoBack() - // if recursive iteration is not important. + // Sets the position back to the top node and clears the entire + // node traversal history (by default). This can be used instead of looping + // KvGoBack() if recursive iteration is not important. // // @param kv KeyValues Handle. - public native void Rewind(); + // @param clearHistory If true, the entire node traversal stack is cleared. + // If false, this will add to the traversal stack. + public native void Rewind(bool clearHistory=true); // Retrieves the current section name. // @@ -306,7 +308,7 @@ methodmap KeyValues < Handle // Returns the position in the jump stack; I.e. the number of calls // required for KvGoBack to return to the root node. If at the root node, - // 0 is returned. + // and the traversal stack is empty, 0 is returned. // // @return Number of non-root nodes in the jump stack. public native int NodesInStack(); @@ -558,9 +560,9 @@ native int KvDeleteThis(Handle kv); /** * Jumps back to the previous position. Returns false if there are no - * 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. - * This function pops one node off the internal traversal stack. + * previous positions (i.e., at the root node with an empty traversal stack). + * This should be called 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. * @return True on success, false if there is no higher node.