Compare commits
No commits in common. "99df8ad38d646137bcf871d93ef52f845491bd5a" and "94837ed410a93e3f5f55a192a7bd0d8c6dd6f032" have entirely different histories.
99df8ad38d
...
94837ed410
4
Makefile
4
Makefile
@ -7,10 +7,8 @@ all: ugui
|
|||||||
raylib/src/libraylib.a: raylib/src/Makefile
|
raylib/src/libraylib.a: raylib/src/Makefile
|
||||||
cd raylib/src; $(MAKE) PLATFORM=PLATFORM_DESKTOP
|
cd raylib/src; $(MAKE) PLATFORM=PLATFORM_DESKTOP
|
||||||
|
|
||||||
ugui: ugui.o vectree.o cache.o raylib/src/libraylib.a
|
ugui: ugui.o vectree.o raylib/src/libraylib.a
|
||||||
|
|
||||||
ugui.o: ugui.c ugui.h
|
ugui.o: ugui.c ugui.h
|
||||||
|
|
||||||
vectree.o: vectree.c ugui.h
|
vectree.o: vectree.c ugui.h
|
||||||
|
|
||||||
cache.o: cache.c ugui.h
|
|
||||||
|
23
cache.c
23
cache.c
@ -24,13 +24,13 @@
|
|||||||
|
|
||||||
#define HASH_MAXSIZE 4096
|
#define HASH_MAXSIZE 4096
|
||||||
|
|
||||||
// hash table (id -> cache index)
|
// hash table (id -> index)
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UgId id;
|
uint32_t id;
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
} IdElem;
|
} IdElem;
|
||||||
|
|
||||||
typedef struct _IdTable {
|
typedef struct {
|
||||||
uint32_t items, size, exp;
|
uint32_t items, size, exp;
|
||||||
IdElem bucket[];
|
IdElem bucket[];
|
||||||
} IdTable;
|
} IdTable;
|
||||||
@ -62,7 +62,7 @@ void table_destroy(IdTable *ht)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find and return the element by pointer
|
// Find and return the element by pointer
|
||||||
IdElem *table_search(IdTable *ht, UgId id)
|
IdElem *table_search(IdTable *ht, uint32_t id)
|
||||||
{
|
{
|
||||||
if (!ht) {
|
if (!ht) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -93,7 +93,7 @@ IdElem *table_insert(IdTable *ht, IdElem entry)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
IdElem *table_remove(IdTable *ht, UgId id)
|
IdElem *table_remove(IdTable *ht, uint32_t id)
|
||||||
{
|
{
|
||||||
if (!ht) {
|
if (!ht) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -119,6 +119,13 @@ IdElem *table_remove(IdTable *ht, UgId id)
|
|||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
IdTable *table;
|
||||||
|
UgElem *array;
|
||||||
|
uint64_t *present, *used;
|
||||||
|
int cycles;
|
||||||
|
} UgElemCache;
|
||||||
|
|
||||||
/* FIXME: check for allocation errors */
|
/* FIXME: check for allocation errors */
|
||||||
UgElemCache ug_cache_init(void)
|
UgElemCache ug_cache_init(void)
|
||||||
{
|
{
|
||||||
@ -141,7 +148,7 @@ void ug_cache_free(UgElemCache *cache)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
UgElem *ug_cache_search(UgElemCache *cache, UgId id)
|
const UgElem *ug_cache_search(UgElemCache *cache, uint32_t id)
|
||||||
{
|
{
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -183,7 +190,7 @@ int ug_cache_get_free_spot(UgElemCache *cache)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
UgElem *ug_cache_insert_at(UgElemCache *cache, const UgElem *g, uint32_t index)
|
const UgElem *ug_cache_insert_at(UgElemCache *cache, const UgElem *g, uint32_t index)
|
||||||
{
|
{
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -204,7 +211,7 @@ UgElem *ug_cache_insert_at(UgElemCache *cache, const UgElem *g, uint32_t index)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Insert an element in the cache
|
// Insert an element in the cache
|
||||||
UgElem *ug_cache_insert(UgElemCache *cache, const UgElem *g, uint32_t *index)
|
const UgElem *ug_cache_insert(UgElemCache *cache, const UgElem *g, int32_t *index)
|
||||||
{
|
{
|
||||||
*index = ug_cache_get_free_spot(cache);
|
*index = ug_cache_get_free_spot(cache);
|
||||||
return ug_cache_insert_at(cache, g, *index);
|
return ug_cache_insert_at(cache, g, *index);
|
||||||
|
287
ugui.c
287
ugui.c
@ -1,5 +1,3 @@
|
|||||||
#define _DEFAULT_SOURCE
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -8,185 +6,30 @@
|
|||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
#include "ugui.h"
|
#include "ugui.h"
|
||||||
|
|
||||||
typedef struct _UgCmd {
|
|
||||||
enum {
|
|
||||||
CMD_RECT = 0,
|
|
||||||
} type;
|
|
||||||
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
int32_t x, y, w, h;
|
|
||||||
uint8_t color[4]; // rgba, [0] = r
|
|
||||||
} rect;
|
|
||||||
};
|
|
||||||
} UgCmd;
|
|
||||||
|
|
||||||
typedef struct _UgStack {
|
|
||||||
int size, count;
|
|
||||||
UgCmd *stack;
|
|
||||||
} UgStack;
|
|
||||||
|
|
||||||
int ug_stack_init(UgStack *stack, uint32_t size);
|
|
||||||
int ug_stack_free(UgStack *stack);
|
|
||||||
int ug_stack_push(UgStack *stack, UgCmd *cmd);
|
|
||||||
int ug_stack_pop(UgStack *stack, UgCmd *cmd);
|
|
||||||
|
|
||||||
int ug_stack_init(UgStack *stack, uint32_t size)
|
|
||||||
{
|
|
||||||
if (stack == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack->size = size;
|
|
||||||
stack->count = 0;
|
|
||||||
stack->stack = calloc(size, sizeof(UgCmd));
|
|
||||||
|
|
||||||
if (stack->stack == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ug_stack_free(UgStack *stack)
|
|
||||||
{
|
|
||||||
if (stack != NULL && stack->stack != NULL) {
|
|
||||||
free(stack->stack);
|
|
||||||
stack->size = 0;
|
|
||||||
stack->count = 0;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define STACK_STEP 10
|
|
||||||
|
|
||||||
int ug_stack_push(UgStack *stack, UgCmd *cmd)
|
|
||||||
{
|
|
||||||
if (stack == NULL || cmd == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack->count >= stack->size) {
|
|
||||||
// UgCmd *tmp = reallocarray(stack->stack, stack->size +
|
|
||||||
// STACK_STEP, sizeof(UgCmd)); if (tmp == NULL) { return -1;
|
|
||||||
// }
|
|
||||||
// stack->stack = tmp;
|
|
||||||
// stack->size += STACK_STEP;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
stack->stack[stack->count++] = *cmd;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ug_stack_pop(UgStack *stack, UgCmd *cmd)
|
|
||||||
{
|
|
||||||
if (stack == NULL || cmd == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (stack->count <= 0) {
|
|
||||||
// UgCmd *tmp = reallocarray(stack->stack, stack->size +
|
|
||||||
// STACK_STEP, sizeof(UgCmd)); if (tmp == NULL) { return -1;
|
|
||||||
// }
|
|
||||||
// stack->stack = tmp;
|
|
||||||
// stack->size += STACK_STEP;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
*cmd = stack->stack[--stack->count];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct _UgCtx {
|
|
||||||
enum {
|
|
||||||
row = 0,
|
|
||||||
column,
|
|
||||||
floating,
|
|
||||||
} layout;
|
|
||||||
|
|
||||||
UgTree tree;
|
|
||||||
UgElemCache cache;
|
|
||||||
UgStack stack;
|
|
||||||
|
|
||||||
struct {
|
|
||||||
int width, height;
|
|
||||||
} size;
|
|
||||||
|
|
||||||
int div_using; // tree node indicating the current active div
|
|
||||||
};
|
|
||||||
|
|
||||||
int ug_div_begin(UgCtx *ctx, const char *name, UgRect div);
|
|
||||||
int ug_div_end(UgCtx *ctx);
|
|
||||||
int ug_input_window_size(UgCtx *ctx, int width, int height);
|
|
||||||
UgId djb2(const char *str);
|
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
UgCtx ctx;
|
UgCtx ctx;
|
||||||
ug_init(&ctx);
|
ug_init(&ctx);
|
||||||
|
|
||||||
int width = 800, height = 450;
|
InitWindow(800, 450, "Ugui Test");
|
||||||
SetConfigFlags(FLAG_WINDOW_RESIZABLE);
|
|
||||||
InitWindow(width, height, "Ugui Test");
|
|
||||||
ug_input_window_size(&ctx, width, height);
|
|
||||||
|
|
||||||
// Main loop
|
// Main loop
|
||||||
while (!WindowShouldClose()) {
|
while (!WindowShouldClose()) {
|
||||||
|
ug_begin_frame(&ctx);
|
||||||
// UI handling
|
|
||||||
ug_frame_begin(&ctx);
|
|
||||||
|
|
||||||
if (IsWindowResized()) {
|
|
||||||
width = GetScreenWidth();
|
|
||||||
height = GetScreenHeight();
|
|
||||||
ug_input_window_size(&ctx, width, height);
|
|
||||||
}
|
|
||||||
|
|
||||||
// main div, fill the whole window
|
|
||||||
#define DIV_FILL (UgRect) {.x = 0, .y = 0, .w = -1, .h = -1}
|
|
||||||
ug_div_begin(&ctx, "main", DIV_FILL);
|
|
||||||
ug_div_end(&ctx);
|
|
||||||
|
|
||||||
ug_frame_end(&ctx);
|
|
||||||
|
|
||||||
// drawing
|
// drawing
|
||||||
BeginDrawing();
|
BeginDrawing();
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
|
DrawText(
|
||||||
Rectangle r;
|
"Congrats! You created your first window!",
|
||||||
Color c;
|
190,
|
||||||
for (UgCmd cmd; ug_stack_pop(&ctx.stack, &cmd) >= 0;) {
|
200,
|
||||||
switch (cmd.type) {
|
20,
|
||||||
case CMD_RECT:
|
LIGHTGRAY
|
||||||
printf(
|
);
|
||||||
"rect x=%d y=%d w=%d h=%d\n",
|
|
||||||
cmd.rect.x,
|
|
||||||
cmd.rect.y,
|
|
||||||
cmd.rect.w,
|
|
||||||
cmd.rect.h
|
|
||||||
);
|
|
||||||
c = (Color) {
|
|
||||||
.r = cmd.rect.color[0],
|
|
||||||
.g = cmd.rect.color[1],
|
|
||||||
.b = cmd.rect.color[2],
|
|
||||||
.a = cmd.rect.color[3],
|
|
||||||
};
|
|
||||||
DrawRectangle(
|
|
||||||
cmd.rect.x, cmd.rect.y, cmd.rect.w, cmd.rect.h, c
|
|
||||||
);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("Unknown cmd type: %d\n", cmd.type);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EndDrawing();
|
EndDrawing();
|
||||||
|
|
||||||
WaitTime(0.2);
|
ug_end_frame(&ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
CloseWindow();
|
CloseWindow();
|
||||||
@ -195,21 +38,13 @@ int main(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAX_ELEMS 128
|
|
||||||
#define MAX_CMDS 256
|
|
||||||
|
|
||||||
int ug_init(UgCtx *ctx)
|
int ug_init(UgCtx *ctx)
|
||||||
{
|
{
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
ug_tree_init(&ctx->tree, MAX_ELEMS);
|
ug_tree_init(&ctx->tree, 10);
|
||||||
ug_stack_init(&ctx->stack, MAX_CMDS);
|
|
||||||
|
|
||||||
ctx->cache = ug_cache_init();
|
|
||||||
ctx->layout = row;
|
|
||||||
ctx->div_using = 0;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -221,106 +56,6 @@ int ug_destroy(UgCtx *ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ug_tree_destroy(&ctx->tree);
|
ug_tree_destroy(&ctx->tree);
|
||||||
ug_cache_free(&ctx->cache);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ug_frame_begin(UgCtx *ctx) { return 0; }
|
|
||||||
|
|
||||||
int ug_frame_end(UgCtx *ctx) { return 0; }
|
|
||||||
|
|
||||||
int ug_input_window_size(UgCtx *ctx, int width, int height)
|
|
||||||
{
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (width >= 0) {
|
|
||||||
ctx->size.width = width;
|
|
||||||
}
|
|
||||||
if (height >= 0) {
|
|
||||||
ctx->size.height = height;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
UgId djb2(const char *str)
|
|
||||||
{
|
|
||||||
uint64_t hash = 5381;
|
|
||||||
uint32_t c;
|
|
||||||
|
|
||||||
while ((c = (str++)[0]) != 0) {
|
|
||||||
hash = ((hash << 5) + hash) + c;
|
|
||||||
} /* hash * 33 + c */
|
|
||||||
|
|
||||||
return hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ug_div_begin(UgCtx *ctx, const char *name, UgRect div)
|
|
||||||
{
|
|
||||||
if (ctx == NULL || name == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UgId id = djb2(name);
|
|
||||||
|
|
||||||
// add the element if it does not exist
|
|
||||||
UgElem *c_elem = ug_cache_search(&ctx->cache, id);
|
|
||||||
if (c_elem == NULL) {
|
|
||||||
UgElem elem = {
|
|
||||||
.id = id,
|
|
||||||
.type = ETYPE_DIV,
|
|
||||||
.rec = (UgRect) {
|
|
||||||
.x = div.x,
|
|
||||||
.y = div.y,
|
|
||||||
.w = div.w >= 0 ? div.w : ctx->size.width,
|
|
||||||
.h = div.h >= 0 ? div.h : ctx->size.height,
|
|
||||||
}};
|
|
||||||
uint32_t c_idx;
|
|
||||||
c_elem = ug_cache_insert(&ctx->cache, &elem, &c_idx);
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: why save the id in the tree and not something more direct like
|
|
||||||
// the element pointer or the index into the cache vector?
|
|
||||||
int div_node = ug_tree_add(&ctx->tree, c_elem->id, ctx->div_using);
|
|
||||||
if (div_node < 0) {
|
|
||||||
// do something
|
|
||||||
printf("Error adding to tree\n");
|
|
||||||
}
|
|
||||||
ctx->div_using = div_node;
|
|
||||||
|
|
||||||
// printf(
|
|
||||||
// "elem.rect: x=%d x=%d w=%d h=%d\n",
|
|
||||||
// c_elem->rec.x,
|
|
||||||
// c_elem->rec.y,
|
|
||||||
// c_elem->rec.w,
|
|
||||||
// c_elem->rec.h
|
|
||||||
// );
|
|
||||||
UgCmd cmd = {
|
|
||||||
.type = CMD_RECT,
|
|
||||||
.rect =
|
|
||||||
{
|
|
||||||
.x = c_elem->rec.x,
|
|
||||||
.y = c_elem->rec.y,
|
|
||||||
.w = c_elem->rec.w,
|
|
||||||
.h = c_elem->rec.h,
|
|
||||||
.color = {0xff, 0x00, 0x00, 0xff}, // red
|
|
||||||
},
|
|
||||||
};
|
|
||||||
ug_stack_push(&ctx->stack, &cmd);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ug_div_end(UgCtx *ctx)
|
|
||||||
{
|
|
||||||
// the div_using returns to the parent of the current one
|
|
||||||
ctx->div_using = ug_tree_parentof(&ctx->tree, ctx->div_using);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
32
ugui.h
32
ugui.h
@ -15,15 +15,16 @@ typedef struct {
|
|||||||
uint8_t r, g, b, a;
|
uint8_t r, g, b, a;
|
||||||
} UgColor;
|
} UgColor;
|
||||||
|
|
||||||
typedef uint64_t UgId;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ETYPE_NONE = 0,
|
ETYPE_NONE = 0,
|
||||||
ETYPE_DIV,
|
ETYPE_BUTTON,
|
||||||
|
ETYPE_TEXT,
|
||||||
|
ETYPE_SCROLL,
|
||||||
|
ETYPE_SLIDER,
|
||||||
} UgElemType;
|
} UgElemType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
UgId id;
|
uint64_t id;
|
||||||
UgRect rec;
|
UgRect rec;
|
||||||
union {
|
union {
|
||||||
uint32_t type_int;
|
uint32_t type_int;
|
||||||
@ -36,42 +37,27 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int size, elements;
|
int size, elements;
|
||||||
UgId *vector; // vector of element ids
|
uint32_t *vector; // vector of element ids
|
||||||
int *refs, *ordered_refs;
|
int *refs, *ordered_refs;
|
||||||
} UgTree;
|
} UgTree;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
struct _IdTable *table;
|
UgTree tree;
|
||||||
UgElem *array;
|
} UgCtx;
|
||||||
uint64_t *present, *used;
|
|
||||||
int cycles;
|
|
||||||
} UgElemCache;
|
|
||||||
|
|
||||||
typedef struct _UgCtx UgCtx;
|
|
||||||
|
|
||||||
// tree implementation
|
// tree implementation
|
||||||
int ug_tree_init(UgTree *tree, unsigned int size);
|
int ug_tree_init(UgTree *tree, unsigned int size);
|
||||||
int ug_tree_pack(UgTree *tree);
|
int ug_tree_pack(UgTree *tree);
|
||||||
int ug_tree_resize(UgTree *tree, unsigned int newsize);
|
int ug_tree_resize(UgTree *tree, unsigned int newsize);
|
||||||
int ug_tree_add(UgTree *tree, UgId elem, int parent);
|
int ug_tree_add(UgTree *tree, uint32_t elem, int parent);
|
||||||
int ug_tree_prune(UgTree *tree, int ref);
|
int ug_tree_prune(UgTree *tree, int ref);
|
||||||
int ug_tree_subtree_size(UgTree *tree, int ref);
|
int ug_tree_subtree_size(UgTree *tree, int ref);
|
||||||
int ug_tree_children_it(UgTree *tree, int parent, int *cursor);
|
int ug_tree_children_it(UgTree *tree, int parent, int *cursor);
|
||||||
int ug_tree_level_order_it(UgTree *tree, int ref, int *cursor);
|
int ug_tree_level_order_it(UgTree *tree, int ref, int *cursor);
|
||||||
int ug_tree_parentof(UgTree *tree, int node);
|
|
||||||
int ug_tree_destroy(UgTree *tree);
|
int ug_tree_destroy(UgTree *tree);
|
||||||
|
|
||||||
// cache implementation
|
|
||||||
UgElemCache ug_cache_init(void);
|
|
||||||
void ug_cache_free(UgElemCache *cache);
|
|
||||||
UgElem *ug_cache_search(UgElemCache *cache, UgId id);
|
|
||||||
UgElem *ug_cache_insert(UgElemCache *cache, const UgElem *g, uint32_t *index);
|
|
||||||
|
|
||||||
|
|
||||||
int ug_init(UgCtx *ctx);
|
int ug_init(UgCtx *ctx);
|
||||||
int ug_destroy(UgCtx *ctx);
|
int ug_destroy(UgCtx *ctx);
|
||||||
int ug_frame_begin(UgCtx *ctx);
|
|
||||||
int ug_frame_end(UgCtx *ctx);
|
|
||||||
|
|
||||||
#endif // _UGUI_H
|
#endif // _UGUI_H
|
||||||
|
|
||||||
|
28
vectree.c
28
vectree.c
@ -12,7 +12,7 @@ int ug_tree_init(UgTree *tree, unsigned int size)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
tree->vector = malloc(sizeof(UgId) * size);
|
tree->vector = malloc(sizeof(UgElem) * size);
|
||||||
if (tree->vector == NULL) {
|
if (tree->vector == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -24,7 +24,7 @@ int ug_tree_init(UgTree *tree, unsigned int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ordered refs are used in the iterators
|
// ordered refs are used in the iterators
|
||||||
tree->ordered_refs = malloc(sizeof(int) * (size + 1));
|
tree->ordered_refs = malloc(sizeof(int) * size);
|
||||||
if (tree->ordered_refs == NULL) {
|
if (tree->ordered_refs == NULL) {
|
||||||
free(tree->vector);
|
free(tree->vector);
|
||||||
free(tree->refs);
|
free(tree->refs);
|
||||||
@ -37,7 +37,7 @@ int ug_tree_init(UgTree *tree, unsigned int size)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// fill vector with zeroes
|
// fill vector with zeroes
|
||||||
memset(tree->vector, 0, size * sizeof(UgId));
|
memset(tree->vector, 0, size * sizeof(UgElem));
|
||||||
|
|
||||||
tree->size = size;
|
tree->size = size;
|
||||||
tree->elements = 0;
|
tree->elements = 0;
|
||||||
@ -118,7 +118,7 @@ int ug_tree_resize(UgTree *tree, unsigned int newsize)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
UgId *newvec = realloc(tree->vector, newsize * sizeof(UgId));
|
uint32_t *newvec = realloc(tree->vector, newsize * sizeof(uint32_t));
|
||||||
if (newvec == NULL) {
|
if (newvec == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -128,7 +128,7 @@ int ug_tree_resize(UgTree *tree, unsigned int newsize)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int *neworrefs = realloc(tree->ordered_refs, (newsize + 1)* sizeof(int));
|
int *neworrefs = realloc(tree->ordered_refs, newsize * sizeof(int));
|
||||||
if (neworrefs == NULL) {
|
if (neworrefs == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -149,7 +149,7 @@ int ug_tree_resize(UgTree *tree, unsigned int newsize)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add an element to the tree, return it's ref
|
// add an element to the tree, return it's ref
|
||||||
int ug_tree_add(UgTree *tree, UgId elem, int parent)
|
int ug_tree_add(UgTree *tree, uint32_t elem, int parent)
|
||||||
{
|
{
|
||||||
if (tree == NULL) {
|
if (tree == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
@ -209,10 +209,9 @@ int ug_tree_prune(UgTree *tree, int ref)
|
|||||||
|
|
||||||
tree->vector[ref] = 0;
|
tree->vector[ref] = 0;
|
||||||
tree->refs[ref] = -1;
|
tree->refs[ref] = -1;
|
||||||
tree->elements--;
|
|
||||||
|
|
||||||
int count = 1;
|
int count = 1;
|
||||||
for (int i = 0; tree->elements > 0 && i < tree->size; i++) {
|
for (int i = 0; i < tree->size; i++) {
|
||||||
if (tree->refs[i] == ref) {
|
if (tree->refs[i] == ref) {
|
||||||
count += ug_tree_prune(tree, i);
|
count += ug_tree_prune(tree, i);
|
||||||
}
|
}
|
||||||
@ -296,7 +295,7 @@ int ug_tree_level_order_it(UgTree *tree, int ref, int *cursor)
|
|||||||
|
|
||||||
// TODO: this could also be done when adding or removing elements
|
// TODO: this could also be done when adding or removing elements
|
||||||
// first call, create a ref array ordered like we desire
|
// first call, create a ref array ordered like we desire
|
||||||
if (*cursor == -1) {
|
if (queue == NULL) {
|
||||||
*cursor = 0;
|
*cursor = 0;
|
||||||
for (int i = 0; i < tree->size; i++) {
|
for (int i = 0; i < tree->size; i++) {
|
||||||
queue[i] = -1;
|
queue[i] = -1;
|
||||||
@ -318,8 +317,6 @@ int ug_tree_level_order_it(UgTree *tree, int ref, int *cursor)
|
|||||||
ref = queue[off];
|
ref = queue[off];
|
||||||
|
|
||||||
} while (IS_VALID_REF(tree, ref));
|
} while (IS_VALID_REF(tree, ref));
|
||||||
// This line is why tree->ordered_refs has to be size+1
|
|
||||||
queue[off+1] = -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PRINT_ARR(queue, tree->size);
|
// PRINT_ARR(queue, tree->size);
|
||||||
@ -336,12 +333,3 @@ int ug_tree_level_order_it(UgTree *tree, int ref, int *cursor)
|
|||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ug_tree_parentof(UgTree *tree, int node)
|
|
||||||
{
|
|
||||||
if (tree == NULL || !IS_VALID_REF(tree, node) ||
|
|
||||||
!REF_IS_PRESENT(tree, node)) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return tree->refs[node];
|
|
||||||
}
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user