Files
wmaker/WINGs/tree.c
T

232 lines
4.4 KiB
C
Raw Normal View History

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