Files
wmaker/WINGs/tree.c
T

280 lines
4.8 KiB
C
Raw Normal View History

2001-01-11 02:35:21 +00:00
#include <string.h>
#include "WUtil.h"
typedef struct W_TreeNode {
void *data;
2001-01-11 02:59:32 +00:00
/*unsigned int uflags:16;*/
2001-01-11 02:35:21 +00:00
WMArray *leaves;
int depth;
struct W_TreeNode *parent;
WMFreeDataProc *destructor;
} W_TreeNode;
2001-01-18 16:59:15 +00:00
2001-01-11 02:35:21 +00:00
void
destroyNode(void *data)
{
2001-01-18 16:59:15 +00:00
WMTreeNode *aNode = (WMTreeNode*) data;
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
if (aNode->destructor) {
(*aNode->destructor)(aNode->data);
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
if (aNode->leaves) {
WMFreeArray(aNode->leaves);
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
wfree(aNode);
2001-01-11 02:35:21 +00:00
}
WMTreeNode*
WMCreateTreeNode(void *data)
{
return WMCreateTreeNodeWithDestructor(data, NULL);
}
WMTreeNode*
WMCreateTreeNodeWithDestructor(void *data, WMFreeDataProc *destructor)
{
2001-01-18 16:59:15 +00:00
WMTreeNode *aNode;
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
aNode = (WMTreeNode*) wmalloc(sizeof(W_TreeNode));
memset(aNode, 0, sizeof(W_TreeNode));
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
aNode->destructor = destructor;
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
aNode->data = data;
aNode->parent = NULL;
aNode->depth = 0;
aNode->leaves = NULL;
/*aNode->leaves = WMCreateArrayWithDestructor(1, destroyNode);*/
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
return aNode;
2001-01-11 02:35:21 +00:00
}
WMTreeNode*
WMInsertItemInTree(WMTreeNode *parent, int index, void *item)
{
2001-01-18 16:59:15 +00:00
WMTreeNode *aNode;
2001-01-11 02:35:21 +00:00
wassertrv(parent!=NULL, NULL);
2001-01-18 16:59:15 +00:00
aNode = WMCreateTreeNodeWithDestructor(item, parent->destructor);
aNode->parent = parent;
aNode->depth = parent->depth+1;
if (!parent->leaves) {
parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
}
if (index < 0) {
WMAddToArray(parent->leaves, aNode);
2001-01-11 02:35:21 +00:00
} else {
2001-01-18 16:59:15 +00:00
WMInsertInArray(parent->leaves, index, aNode);
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
return aNode;
2001-01-11 02:35:21 +00:00
}
static void
2001-01-18 16:59:15 +00:00
updateNodeDepth(WMTreeNode *aNode, int depth)
2001-01-11 02:35:21 +00:00
{
int i;
2001-01-18 16:59:15 +00:00
aNode->depth = depth;
if (aNode->leaves) {
for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
updateNodeDepth(WMGetFromArray(aNode->leaves, i), depth+1);
}
2001-01-11 02:35:21 +00:00
}
}
WMTreeNode*
2001-01-18 16:59:15 +00:00
WMInsertNodeInTree(WMTreeNode *parent, int index, WMTreeNode *aNode)
2001-01-11 02:35:21 +00:00
{
wassertrv(parent!=NULL, NULL);
2001-01-18 16:59:15 +00:00
wassertrv(aNode!=NULL, NULL);
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
aNode->parent = parent;
updateNodeDepth(aNode, parent->depth+1);
if (!parent->leaves) {
parent->leaves = WMCreateArrayWithDestructor(1, destroyNode);
}
if (index < 0) {
WMAddToArray(parent->leaves, aNode);
2001-01-11 02:35:21 +00:00
} else {
2001-01-18 16:59:15 +00:00
WMInsertInArray(parent->leaves, index, aNode);
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
return aNode;
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
void
WMDestroyTreeNode(WMTreeNode *aNode)
2001-01-11 02:35:21 +00:00
{
2001-01-18 16:59:15 +00:00
wassertr(aNode!=NULL);
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
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);
2001-01-11 02:35:21 +00:00
2001-01-18 16:59:15 +00:00
WMDeleteFromArray(aNode->leaves, index);
2001-01-11 02:35:21 +00:00
}
2001-01-18 16:59:15 +00:00
static int
sameData(void *item, void *data)
2001-01-11 02:35:21 +00:00
{
2001-01-18 16:59:15 +00:00
return (((WMTreeNode*)item)->data == data);
2001-01-11 02:35:21 +00:00
}
void
2001-01-18 16:59:15 +00:00
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*
WMReplaceDataForTreeNode(WMTreeNode *aNode, void *newData)
2001-01-11 02:35:21 +00:00
{
2001-01-18 16:59:15 +00:00
void *old;
wassertrv(aNode!=NULL, NULL);
old = aNode->data;
aNode->data = newData;
return old;
2001-01-11 02:35:21 +00:00
}
2001-01-11 02:59:32 +00:00
void*
2001-01-18 16:59:15 +00:00
WMGetDataForTreeNode(WMTreeNode *aNode)
2001-01-11 02:59:32 +00:00
{
2001-01-18 16:59:15 +00:00
return aNode->data;
}
int
WMGetTreeNodeDepth(WMTreeNode *aNode)
{
return aNode->depth;
2001-01-11 02:59:32 +00:00
}
WMTreeNode*
2001-01-18 16:59:15 +00:00
WMGetParentForTreeNode(WMTreeNode *aNode)
2001-01-11 02:59:32 +00:00
{
2001-01-18 16:59:15 +00:00
return aNode->parent;
2001-01-11 02:59:32 +00:00
}
void
2001-01-18 16:59:15 +00:00
WMSortLeavesForTreeNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
2001-01-11 02:59:32 +00:00
{
2001-01-18 16:59:15 +00:00
wassertr(aNode!=NULL);
2001-01-11 02:59:32 +00:00
2001-01-18 16:59:15 +00:00
if (aNode->leaves) {
WMSortArray(aNode->leaves, comparer);
}
2001-01-11 02:59:32 +00:00
}
static void
2001-01-18 16:59:15 +00:00
sortLeavesForNode(WMTreeNode *aNode, WMCompareDataProc *comparer)
2001-01-11 02:59:32 +00:00
{
int i;
2001-01-18 16:59:15 +00:00
if (!aNode->leaves)
return;
WMSortArray(aNode->leaves, comparer);
for (i=0; i<WMGetArrayItemCount(aNode->leaves); i++) {
sortLeavesForNode(WMGetFromArray(aNode->leaves, i), comparer);
2001-01-11 02:59:32 +00:00
}
}
void
2001-01-18 16:59:15 +00:00
WMSortTree(WMTreeNode *aNode, WMCompareDataProc *comparer)
{
wassertr(aNode!=NULL);
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)
2001-01-11 02:59:32 +00:00
{
2001-01-18 16:59:15 +00:00
wassertrv(aTree!=NULL, NULL);
2001-01-11 02:59:32 +00:00
2001-01-18 16:59:15 +00:00
return findNodeInTree(aTree, match, cdata);
2001-01-11 02:59:32 +00:00
}