improve performance by caching the index of the last component node
This commit is contained in:
parent
8e28a79e88
commit
dc83e09f43
4 changed files with 37 additions and 6 deletions
2
Makefile
2
Makefile
|
@ -13,7 +13,7 @@ OBJS=$(patsubst $(SRC)/%.c, $(OBJ)/%.o, $(SRCS))
|
|||
DEPS=$(OBJS:%.o=%.d)
|
||||
|
||||
|
||||
all: CFLAGS+=-fsanitize=address -Og -ggdb
|
||||
all: CFLAGS+=-Og -ggdb -DNDEBUG
|
||||
all: $(BUILD) $(BIN)
|
||||
|
||||
release: CFLAGS+=-O2 -flto=auto -DNDEBUG
|
||||
|
|
|
@ -130,13 +130,15 @@ int app_handle(struct UINode *node, void *data, int event_type, size_t d, void *
|
|||
|
||||
box_layout_new(buttons, UI_DIRECTION_VERTICAL);
|
||||
|
||||
for (int i = 0; i < 100; i++) {
|
||||
for (int i = 0; i < 10000; i++) {
|
||||
UINode *button = node_new(buttons, "button");
|
||||
state_background_node_new(button, UIPurple600, UIPurple700, UIPurple800, 6.0);
|
||||
text_node_new(button, state->font, UINeutral50, "button");
|
||||
dispatcher_new(button, UI_EVENT_UNPRESSED, INCREMENT_COUNT, state, app_handle);
|
||||
button->width_policy = UI_SIZE_POLICY_GROW;
|
||||
}
|
||||
|
||||
printf("%d\n", buttons->last_component_index);
|
||||
}
|
||||
|
||||
break;
|
||||
|
|
34
src/node.c
34
src/node.c
|
@ -28,14 +28,25 @@ int node_dispatch(UINode *node, enum UIEvent ev, size_t d, void *p)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int result = 0;
|
||||
int component_index = UI_NODE_LAST_COMPONENT_INDEX_NONE;
|
||||
for (int i = 0; i < node->nodes_count; i++) {
|
||||
if (node->last_component_index == UI_NODE_LAST_COMPONENT_INDEX_NONE || (node->last_component_index >= 0 && i > node->last_component_index)) {
|
||||
break;
|
||||
}
|
||||
if (node->nodes[i]->flags & UI_NODE_COMPONENT) {
|
||||
int result = node_dispatch(node->nodes[i], ev, d, p);
|
||||
if (result) return result;
|
||||
component_index = i;
|
||||
result = node_dispatch(node->nodes[i], ev, d, p);
|
||||
if (result) break;
|
||||
}
|
||||
}
|
||||
if (node->last_component_index < 0) {
|
||||
node->last_component_index = component_index;
|
||||
}
|
||||
if (result) return result;
|
||||
|
||||
if (node->handle) {
|
||||
int result = (node->handle)(node, ev, d, p);
|
||||
result = (node->handle)(node, ev, d, p);
|
||||
if (result) return result;
|
||||
}
|
||||
if (node->handle_proto) {
|
||||
|
@ -71,12 +82,20 @@ void node_init(UINode *node)
|
|||
node->height_policy = UI_SIZE_POLICY_DYNAMIC;
|
||||
node->handle = NULL;
|
||||
node->handle_proto = NULL;
|
||||
node->last_component_index = UI_NODE_LAST_COMPONENT_INDEX_NONE;
|
||||
}
|
||||
|
||||
void node_free(UINode *node)
|
||||
{
|
||||
if (!node) return;
|
||||
|
||||
// TODO: properly handle removing this node from its parent
|
||||
|
||||
// Invalidate component index cache
|
||||
if ((node->flags & UI_NODE_COMPONENT) && node->parent) {
|
||||
node->parent->last_component_index = UI_NODE_LAST_COMPONENT_INDEX_INVALIDATED;
|
||||
}
|
||||
|
||||
node_dispatch(node, UI_EVENT_DESTROY, 0, NULL);
|
||||
|
||||
for (int i = 0; i < node->nodes_count; i++) {
|
||||
|
@ -135,7 +154,14 @@ UINode *node_attach(UINode *parent, UINode *node)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
parent->nodes[parent->nodes_count++] = node;
|
||||
int index = parent->nodes_count++;
|
||||
parent->nodes[index] = node;
|
||||
|
||||
// Let's save the index of the last component so that we can exit the loop early
|
||||
// if there's no components left when we're in node_dispatch()
|
||||
if ((node->flags & UI_NODE_COMPONENT) && index > parent->last_component_index) {
|
||||
parent->last_component_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
|
|
|
@ -41,6 +41,8 @@ enum UIDirection {
|
|||
#define UI_NODE_RETAINS_PRESS (1 << 1)
|
||||
#define UI_NODE_DISABLED (1 << 2)
|
||||
|
||||
#define UI_NODE_LAST_COMPONENT_INDEX_INVALIDATED (-1)
|
||||
#define UI_NODE_LAST_COMPONENT_INDEX_NONE (-2)
|
||||
typedef struct UINode {
|
||||
const char *text;
|
||||
UIRect rect;
|
||||
|
@ -53,6 +55,7 @@ typedef struct UINode {
|
|||
uint32_t flags;
|
||||
enum UISizePolicy width_policy;
|
||||
enum UISizePolicy height_policy;
|
||||
int last_component_index;
|
||||
|
||||
int (*handle)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||
int (*handle_proto)(struct UINode *node, enum UIEvent ev, size_t d, void *p);
|
||||
|
|
Loading…
Reference in a new issue