1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-23 06:38:05 +01:00

WINGs: tree enhancements

- add WMFindInTreeWithDepthLimit, which is like WMFindInTree, but
  does not descend down more than a set limit.

- add WMTreeWalk, which will walk a WMTreeNode, running a callback
  function on each node.

Signed-off-by: Tamas TEVESZ <ice@extreme.hu>
This commit is contained in:
Tamas TEVESZ
2010-10-07 23:46:43 +02:00
committed by Carlos R. Mafra
parent 9a2732a4c3
commit 210bcec4de
2 changed files with 47 additions and 15 deletions

View File

@@ -117,6 +117,7 @@ typedef void WMInputProc(int fd, int mask, void *clientData);
typedef int WMCompareDataProc(const void *item1, const void *item2); typedef int WMCompareDataProc(const void *item1, const void *item2);
typedef void WMTreeWalkProc(WMTreeNode *aNode, void *data);
typedef void WMFreeDataProc(void *data); typedef void WMFreeDataProc(void *data);
@@ -642,9 +643,16 @@ void WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer);
/* Returns the first node which matches node's data with cdata by 'match' */ /* Returns the first node which matches node's data with cdata by 'match' */
WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata); WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata);
/* Returns the first node where node's data matches cdata by 'match' and node is
* at most `limit' depths down from `aTree'. */
WMTreeNode *WMFindInTreeWithDepthLimit(WMTreeNode * aTree, WMMatchDataProc * match, void *cdata, int limit);
/* Returns first tree node that has data == cdata */ /* Returns first tree node that has data == cdata */
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(aTree, NULL, cdata) #define WMGetFirstInTree(aTree, cdata) WMFindInTree(aTree, NULL, cdata)
/* Walk every node of aNode with `walk' */
void WMTreeWalk(WMTreeNode *aNode, WMTreeWalkProc * walk, void *data, Bool DepthFirst);
/* ---[ WINGs/data.c ]---------------------------------------------------- */ /* ---[ WINGs/data.c ]---------------------------------------------------- */

View File

@@ -196,29 +196,24 @@ void WMSortTree(WMTreeNode * aNode, WMCompareDataProc * comparer)
sortLeavesForNode(aNode, comparer); sortLeavesForNode(aNode, comparer);
} }
static WMTreeNode *findNodeInTree(WMTreeNode * aNode, WMMatchDataProc * match, void *cdata) static WMTreeNode *findNodeInTree(WMTreeNode * aNode, WMMatchDataProc * match, void *cdata, int limit)
{ {
if (match == NULL) { if (match == NULL && aNode->data == cdata)
if (aNode->data == cdata) {
return aNode; return aNode;
} else if ((*match) (aNode->data, cdata))
} else {
if ((*match) (aNode->data, cdata)) {
return aNode; return aNode;
}
}
if (aNode->leaves) { if (aNode->leaves && limit != 0) {
WMTreeNode *leaf; WMTreeNode *leaf;
int i; int i;
for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) { for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) {
leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i), match, cdata); leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i),
if (leaf) { match, cdata, limit > 0 ? limit - 1 : limit);
if (leaf)
return leaf; return leaf;
} }
} }
}
return NULL; return NULL;
} }
@@ -227,5 +222,34 @@ WMTreeNode *WMFindInTree(WMTreeNode * aTree, WMMatchDataProc * match, void *cdat
{ {
wassertrv(aTree != NULL, NULL); wassertrv(aTree != NULL, NULL);
return findNodeInTree(aTree, match, cdata); return findNodeInTree(aTree, match, cdata, -1);
}
WMTreeNode *WMFindInTreeWithDepthLimit(WMTreeNode * aTree, WMMatchDataProc * match, void *cdata, int limit)
{
wassertrv(aTree != NULL, NULL);
wassertrv(limit >= 0, NULL);
return findNodeInTree(aTree, match, cdata, limit);
}
void WMTreeWalk(WMTreeNode * aNode, WMTreeWalkProc * walk, void *data, Bool DepthFirst)
{
int i;
WMTreeNode *leaf;
wassertr(aNode != NULL);
if (DepthFirst)
(*walk)(aNode, data);
if (aNode->leaves) {
for (i = 0; i < WMGetArrayItemCount(aNode->leaves); i++) {
leaf = (WMTreeNode *)WMGetFromArray(aNode->leaves, i);
WMTreeWalk(leaf, walk, data, DepthFirst);
}
}
if (!DepthFirst)
(*walk)(aNode, data);
} }