1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 12:28:22 +01:00

Finished the generic tree node data type

This commit is contained in:
dan
2001-01-18 16:59:15 +00:00
parent bb886be82e
commit 6a3b06e609
2 changed files with 187 additions and 97 deletions

View File

@@ -582,23 +582,37 @@ WMTreeNode* WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructo
WMTreeNode* WMInsertItemInTree(WMTreeNode *parent, int index, void *item); WMTreeNode* WMInsertItemInTree(WMTreeNode *parent, int index, void *item);
WMTreeNode* WMAddItemToTree(WMTreeNode *parent, void *item); #define WMAddItemToTree(parent, item) WMInsertItemInTree(parent, -1, item)
WMTreeNode* WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *node); WMTreeNode* WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *aNode);
WMTreeNode* WMAddNodeToTree(WMTreeNode *parent, WMTreeNode *node); #define WMAddNodeToTree(parent, aNode) WMInsertNodeInTree(parent, -1, aNode)
int WMGetTreeNodeDepth(WMTreeNode *node); void WMDestroyTreeNode(WMTreeNode *aNode);
void WMDestroyTreeNode(WMTreeNode *node); void WMDeleteLeafForTreeNode(WMTreeNode *aNode, int index);
void* WMGetDataForTreeNode(WMTreeNode *node); void WMRemoveLeafForTreeNode(WMTreeNode *aNode, void *leaf);
WMTreeNode* WMGetParentForTreeNode(WMTreeNode *node); void* WMReplaceDataForTreeNode(WMTreeNode *aNode, void *newData);
void WMSortLeavesForTreeNode(WMTreeNode *node, WMCompareDataProc *comparer); void* WMGetDataForTreeNode(WMTreeNode *aNode);
void WMSortTree(WMTreeNode *root, WMCompareDataProc *comparer); int WMGetTreeNodeDepth(WMTreeNode *aNode);
WMTreeNode* WMGetParentForTreeNode(WMTreeNode *aNode);
/* Sort only the leaves of the passed node */
void WMSortLeavesForTreeNode(WMTreeNode *aNode, WMCompareDataProc *comparer);
/* Sort all tree recursively starting from the passed node */
void WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer);
/* Returns the first node which matches node's data with cdata by 'match' */
WMTreeNode* WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata);
/* Returns first tree node that has data == cdata */
#define WMGetFirstInTree(aTree, cdata) WMFindInTree(atree, NULL, cdata)
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/

View File

@@ -22,18 +22,19 @@ typedef struct W_TreeNode {
void void
destroyNode(void *data) destroyNode(void *data)
{ {
WMTreeNode *node = (WMTreeNode*) data; WMTreeNode *aNode = (WMTreeNode*) data;
if (node->destructor) { if (aNode->destructor) {
(*node->destructor)(node->data); (*aNode->destructor)(aNode->data);
} }
if (node->leaves) { if (aNode->leaves) {
WMFreeArray(node->leaves); WMFreeArray(aNode->leaves);
} }
wfree(node); wfree(aNode);
} }
@@ -47,157 +48,232 @@ WMCreateTreeNode(void *data)
WMTreeNode* WMTreeNode*
WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructor) WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructor)
{ {
WMTreeNode *node; WMTreeNode *aNode;
node = (WMTreeNode*) wmalloc(sizeof(W_TreeNode)); aNode = (WMTreeNode*) wmalloc(sizeof(W_TreeNode));
memset(node, 0, sizeof(W_TreeNode)); memset(aNode, 0, sizeof(W_TreeNode));
node->destructor = destructor; aNode->destructor = destructor;
node->data = data; aNode->data = data;
node->parent = NULL; aNode->parent = NULL;
node->depth = 0; aNode->depth = 0;
node->leaves = WMCreateArrayWithDestructor(1, destroyNode); aNode->leaves = NULL;
/*aNode->leaves = WMCreateArrayWithDestructor(1, destroyNode);*/
return node; return aNode;
} }
WMTreeNode* WMTreeNode*
WMInsertItemInTree(WMTreeNode *parent, int index, void *item) WMInsertItemInTree(WMTreeNode *parent, int index, void *item)
{ {
WMTreeNode *node; WMTreeNode *aNode;
wassertrv(parent!=NULL, NULL); wassertrv(parent!=NULL, NULL);
node = WMCreateTreeNodeWithDestructor(item, parent->destructor); aNode = WMCreateTreeNodeWithDestructor(item, parent->destructor);
node->parent = parent; aNode->parent = parent;
node->depth = parent->depth+1; aNode->depth = parent->depth+1;
if (index < 0 || index > WMGetArrayItemCount(parent->leaves)) { if (!parent->leaves) {
WMAddToArray(parent->leaves, node); parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
}
if (index < 0) {
WMAddToArray(parent->leaves, aNode);
} else { } else {
WMInsertInArray(parent->leaves, index, node); WMInsertInArray(parent->leaves, index, aNode);
} }
return node; return aNode;
}
WMTreeNode*
WMAddItemToTree(WMTreeNode *parent, void *item)
{
WMTreeNode *node;
wassertrv(parent!=NULL, NULL);
node = WMCreateTreeNodeWithDestructor(item, parent->destructor);
node->parent = parent;
node->depth = parent->depth+1;
WMAddToArray(parent->leaves, node);
return node;
} }
static void static void
updateNodeDepth(WMTreeNode *node, int depth) updateNodeDepth(WMTreeNode *aNode, int depth)
{ {
int i; int i;
node->depth = depth; aNode->depth = depth;
for (i=0; i<WMGetArrayItemCount(node->leaves); i++) {
updateNodeDepth(WMGetFromArray(node->leaves, i), depth+1); if (aNode->leaves) {
for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
updateNodeDepth(WMGetFromArray(aNode->leaves, i), depth+1);
}
} }
} }
WMTreeNode* WMTreeNode*
WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *node) WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *aNode)
{ {
wassertrv(parent!=NULL, NULL); wassertrv(parent!=NULL, NULL);
wassertrv(node!=NULL, NULL); wassertrv(aNode!=NULL, NULL);
node->parent = parent; aNode->parent = parent;
updateNodeDepth(node, parent->depth+1); updateNodeDepth(aNode, parent->depth+1);
if (index < 0 || index > WMGetArrayItemCount(parent->leaves)) { if (!parent->leaves) {
WMAddToArray(parent->leaves, node); parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
}
if (index < 0) {
WMAddToArray(parent->leaves, aNode);
} else { } else {
WMInsertInArray(parent->leaves, index, node); WMInsertInArray(parent->leaves, index, aNode);
} }
return node; return aNode;
}
WMTreeNode*
WMAddNodeToTree(WMTreeNode *parent, WMTreeNode *node)
{
wassertrv(parent!=NULL, NULL);
wassertrv(node!=NULL, NULL);
node->parent = parent;
updateNodeDepth(node, parent->depth+1);
WMAddToArray(parent->leaves, node);
return node;
}
int
WMGetTreeNodeDepth(WMTreeNode *node)
{
return node->depth;
} }
void void
WMDestroyTreeNode(WMTreeNode *node) WMDestroyTreeNode(WMTreeNode *aNode)
{ {
destroyNode(node); wassertr(aNode!=NULL);
if (aNode->parent && aNode->parent->leaves) {
WMRemoveFromArray(aNode->parent->leaves, aNode);
} else {
destroyNode(aNode);
}
}
void
WMDeleteLeafForTreeNode(WMTreeNode *aNode, int index)
{
wassertr(aNode!=NULL);
wassertr(aNode->leaves!=NULL);
WMDeleteFromArray(aNode->leaves, index);
}
static int
sameData(void *item, void *data)
{
return (((WMTreeNode*)item)->data == data);
}
void
WMRemoveLeafForTreeNode(WMTreeNode *aNode, void *leaf)
{
int index;
wassertr(aNode!=NULL);
wassertr(aNode->leaves!=NULL);
index = WMFindInArray(aNode->leaves, sameData, leaf);
if (index != WANotFound) {
WMDeleteFromArray(aNode->leaves, index);
}
} }
void* void*
WMGetDataForTreeNode(WMTreeNode *node) WMReplaceDataForTreeNode(WMTreeNode *aNode, void *newData)
{ {
return node->data; void *old;
wassertrv(aNode!=NULL, NULL);
old = aNode->data;
aNode->data = newData;
return old;
}
void*
WMGetDataForTreeNode(WMTreeNode *aNode)
{
return aNode->data;
}
int
WMGetTreeNodeDepth(WMTreeNode *aNode)
{
return aNode->depth;
} }
WMTreeNode* WMTreeNode*
WMGetParentForTreeNode(WMTreeNode *node) WMGetParentForTreeNode(WMTreeNode *aNode)
{ {
return node->parent; return aNode->parent;
} }
void void
WMSortLeavesForTreeNode(WMTreeNode *node, WMCompareDataProc *comparer) WMSortLeavesForTreeNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
{ {
wassertr(node!=NULL); wassertr(aNode!=NULL);
WMSortArray(node->leaves, comparer); if (aNode->leaves) {
WMSortArray(aNode->leaves, comparer);
}
} }
static void static void
sortLeavesForNode(WMTreeNode *node, WMCompareDataProc *comparer) sortLeavesForNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
{ {
int i; int i;
WMSortArray(node->leaves, comparer); if (!aNode->leaves)
for (i=0; i<WMGetArrayItemCount(node->leaves); i++) { return;
sortLeavesForNode(WMGetFromArray(node->leaves, i), comparer);
WMSortArray(aNode->leaves, comparer);
for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
sortLeavesForNode(WMGetFromArray(aNode->leaves, i), comparer);
} }
} }
void void
WMSortTree(WMTreeNode *root, WMCompareDataProc *comparer) WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer)
{ {
wassertr(root!=NULL); wassertr(aNode!=NULL);
sortLeavesForNode(root, comparer); sortLeavesForNode(aNode, comparer);
}
static WMTreeNode*
findNodeInTree(WMTreeNode *aNode, WMMatchDataProc *match, void *cdata)
{
if (match==NULL) {
if (aNode->data == cdata) {
return aNode;
}
} else {
if ((*match)(aNode->data, cdata)) {
return aNode;
}
}
if (aNode->leaves) {
WMTreeNode *leaf;
int i;
for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
leaf = findNodeInTree(WMGetFromArray(aNode->leaves, i), match, cdata);
if (leaf) {
return leaf;
}
}
}
return NULL;
}
WMTreeNode*
WMFindInTree(WMTreeNode *aTree, WMMatchDataProc *match, void *cdata)
{
wassertrv(aTree!=NULL, NULL);
return findNodeInTree(aTree, match, cdata);
} }