Squashed commit of the following:
commit51a16fcec3
Author: jacekpoz <jacekpoz@proton.me> Date: Mon Sep 9 23:07:46 2024 +0200 mark all components to be updated during initialization commit7952918cdb
Author: jacekpoz <jacekpoz@proton.me> Date: Mon Sep 9 23:07:31 2024 +0200 clear caches before updating component commit40c2329b3c
Author: jacekpoz <jacekpoz@proton.me> Date: Mon Sep 9 22:25:22 2024 +0200 implement vertex and index caches hopefully these work and actually help with performance commitbe1ae4c531
Author: jacekpoz <jacekpoz@proton.me> Date: Mon Sep 9 21:11:52 2024 +0200 initial tree impl without any updating logic
This commit is contained in:
parent
8581e336d5
commit
1037eaaeff
4 changed files with 146 additions and 29 deletions
|
@ -28,10 +28,13 @@ typedef enum {
|
||||||
PTK_COMPONENT_TYPE_CLICKABLE = 4,
|
PTK_COMPONENT_TYPE_CLICKABLE = 4,
|
||||||
} PtkComponentType;
|
} PtkComponentType;
|
||||||
|
|
||||||
|
const char *ptk_component_type_to_str(PtkComponentType type);
|
||||||
|
|
||||||
PTK_LIST_DEFINE(PtkHandle);
|
PTK_LIST_DEFINE(PtkHandle);
|
||||||
|
|
||||||
#define PTK_COMPONENT_DEFINE(name, ...) \
|
#define PTK_COMPONENT_DEFINE(name, ...) \
|
||||||
typedef struct name {\
|
typedef struct name {\
|
||||||
|
uint64_t id;\
|
||||||
PtkComponentType type;\
|
PtkComponentType type;\
|
||||||
PtkHandle parent;\
|
PtkHandle parent;\
|
||||||
PTK_LIST(PtkHandle) children;\
|
PTK_LIST(PtkHandle) children;\
|
||||||
|
|
25
src/ptk.c
25
src/ptk.c
|
@ -142,13 +142,30 @@ bool ptk_init(const size_t width, const size_t height, const char *title, const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *ptk_component_type_to_str(PtkComponentType type) {
|
||||||
|
const char *res;
|
||||||
|
switch (type) {
|
||||||
|
case PTK_COMPONENT_TYPE_BOX: res = "box"; break;
|
||||||
|
case PTK_COMPONENT_TYPE_TRIANGLE: res = "triangle"; break;
|
||||||
|
case PTK_COMPONENT_TYPE_RECT: res = "rect"; break;
|
||||||
|
case PTK_COMPONENT_TYPE_ELLIPSE: res = "ellipse"; break;
|
||||||
|
case PTK_COMPONENT_TYPE_CLICKABLE: res = "clickable"; break;
|
||||||
|
default: res = "unknown"; break;
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t m_component_count = 0;
|
||||||
|
|
||||||
PtkHandle ptk_box(const size_t child_count, PtkHandle *children) {
|
PtkHandle ptk_box(const size_t child_count, PtkHandle *children) {
|
||||||
PtkComponent *ret = malloc(sizeof(PtkComponent));
|
PtkComponent *ret = malloc(sizeof(PtkComponent));
|
||||||
*ret = (PtkComponent){
|
*ret = (PtkComponent){
|
||||||
|
.id = m_component_count,
|
||||||
.type = PTK_COMPONENT_TYPE_BOX,
|
.type = PTK_COMPONENT_TYPE_BOX,
|
||||||
.children = PTK_LIST_NEW(PtkHandle, child_count),
|
.children = PTK_LIST_NEW(PtkHandle, child_count),
|
||||||
};
|
};
|
||||||
PTK_LIST_ADD_ALL_P(PtkHandle, ret->children, children, child_count);
|
PTK_LIST_ADD_ALL_P(PtkHandle, ret->children, children, child_count);
|
||||||
|
m_component_count += 1;
|
||||||
|
|
||||||
return (PtkHandle)ret;
|
return (PtkHandle)ret;
|
||||||
}
|
}
|
||||||
|
@ -156,10 +173,12 @@ PtkHandle ptk_box(const size_t child_count, PtkHandle *children) {
|
||||||
PtkHandle ptk_triangle(const PtkPos vertices[3], const PtkRGB color) {
|
PtkHandle ptk_triangle(const PtkPos vertices[3], const PtkRGB color) {
|
||||||
PtkTriangle *ret = malloc(sizeof(PtkTriangle));
|
PtkTriangle *ret = malloc(sizeof(PtkTriangle));
|
||||||
*ret = (PtkTriangle){
|
*ret = (PtkTriangle){
|
||||||
|
.id = m_component_count,
|
||||||
.type = PTK_COMPONENT_TYPE_TRIANGLE,
|
.type = PTK_COMPONENT_TYPE_TRIANGLE,
|
||||||
.color = color,
|
.color = color,
|
||||||
};
|
};
|
||||||
memcpy(ret->vertices, vertices, sizeof(PtkPos) * 3);
|
memcpy(ret->vertices, vertices, sizeof(PtkPos) * 3);
|
||||||
|
m_component_count += 1;
|
||||||
|
|
||||||
return (PtkHandle)ret;
|
return (PtkHandle)ret;
|
||||||
}
|
}
|
||||||
|
@ -167,11 +186,13 @@ PtkHandle ptk_triangle(const PtkPos vertices[3], const PtkRGB color) {
|
||||||
PtkHandle ptk_rect(const PtkPos top_left, const PtkSize size, const PtkRGB color) {
|
PtkHandle ptk_rect(const PtkPos top_left, const PtkSize size, const PtkRGB color) {
|
||||||
PtkRect *ret = malloc(sizeof(PtkRect));
|
PtkRect *ret = malloc(sizeof(PtkRect));
|
||||||
*ret = (PtkRect){
|
*ret = (PtkRect){
|
||||||
|
.id = m_component_count,
|
||||||
.type = PTK_COMPONENT_TYPE_RECT,
|
.type = PTK_COMPONENT_TYPE_RECT,
|
||||||
.top_left = top_left,
|
.top_left = top_left,
|
||||||
.size = size,
|
.size = size,
|
||||||
.color = color,
|
.color = color,
|
||||||
};
|
};
|
||||||
|
m_component_count += 1;
|
||||||
|
|
||||||
return (PtkHandle)ret;
|
return (PtkHandle)ret;
|
||||||
}
|
}
|
||||||
|
@ -183,11 +204,13 @@ PtkHandle ptk_square(const PtkPos top_left, const float size, const PtkRGB color
|
||||||
PtkHandle ptk_ellipse(const PtkPos center, const PtkSize radii, const PtkRGB color) {
|
PtkHandle ptk_ellipse(const PtkPos center, const PtkSize radii, const PtkRGB color) {
|
||||||
PtkEllipse *ret = malloc(sizeof(PtkEllipse));
|
PtkEllipse *ret = malloc(sizeof(PtkEllipse));
|
||||||
*ret = (PtkEllipse){
|
*ret = (PtkEllipse){
|
||||||
|
.id = m_component_count,
|
||||||
.type = PTK_COMPONENT_TYPE_ELLIPSE,
|
.type = PTK_COMPONENT_TYPE_ELLIPSE,
|
||||||
.center = center,
|
.center = center,
|
||||||
.radii = radii,
|
.radii = radii,
|
||||||
.color = color,
|
.color = color,
|
||||||
};
|
};
|
||||||
|
m_component_count += 1;
|
||||||
|
|
||||||
return (PtkHandle)ret;
|
return (PtkHandle)ret;
|
||||||
}
|
}
|
||||||
|
@ -199,11 +222,13 @@ PtkHandle ptk_circle(const PtkPos center, const float radius, const PtkRGB color
|
||||||
PtkHandle ptk_clickable(PtkHandle hitbox, const MouseButtonCallback on_press) {
|
PtkHandle ptk_clickable(PtkHandle hitbox, const MouseButtonCallback on_press) {
|
||||||
PtkClickable *ret = malloc(sizeof(PtkClickable));
|
PtkClickable *ret = malloc(sizeof(PtkClickable));
|
||||||
*ret = (PtkClickable){
|
*ret = (PtkClickable){
|
||||||
|
.id = m_component_count,
|
||||||
.type = PTK_COMPONENT_TYPE_CLICKABLE,
|
.type = PTK_COMPONENT_TYPE_CLICKABLE,
|
||||||
.children = PTK_LIST_NEW(PtkHandle, 1),
|
.children = PTK_LIST_NEW(PtkHandle, 1),
|
||||||
.on_press = on_press,
|
.on_press = on_press,
|
||||||
};
|
};
|
||||||
PTK_LIST_ADD(PtkHandle, ret->children, hitbox);
|
PTK_LIST_ADD(PtkHandle, ret->children, hitbox);
|
||||||
|
m_component_count += 1;
|
||||||
|
|
||||||
return (PtkHandle)ret;
|
return (PtkHandle)ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,14 @@
|
||||||
|
|
||||||
#define PTK_LIST_REMOVE_AT(T, list, index) _remove_at_PtkList((void *)list.data, &list.size, index, sizeof(T))
|
#define PTK_LIST_REMOVE_AT(T, list, index) _remove_at_PtkList((void *)list.data, &list.size, index, sizeof(T))
|
||||||
|
|
||||||
|
#define PTK_LIST_SET(T, list, index, elem) do {\
|
||||||
|
while (list.allocated <= index) {\
|
||||||
|
/* let's hope this doesn't fail !!! */\
|
||||||
|
_grow_PtkList((void *)&list.data, &list.allocated, sizeof(T));\
|
||||||
|
}\
|
||||||
|
list.data[index] = elem;\
|
||||||
|
} while (0)
|
||||||
|
|
||||||
bool _grow_PtkList(void **data, uint32_t *allocated, size_t element_size);
|
bool _grow_PtkList(void **data, uint32_t *allocated, size_t element_size);
|
||||||
bool _add_PtkList(void **data, uint32_t *size, uint32_t *allocated, void *elements, size_t element_count, size_t element_size);
|
bool _add_PtkList(void **data, uint32_t *size, uint32_t *allocated, void *elements, size_t element_count, size_t element_size);
|
||||||
bool _remove_PtkList(void *data, uint32_t *size, void *elements, size_t element_count, size_t element_size);
|
bool _remove_PtkList(void *data, uint32_t *size, void *elements, size_t element_count, size_t element_size);
|
||||||
|
|
|
@ -7,8 +7,25 @@
|
||||||
|
|
||||||
#include <GLFW/glfw3.h>
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
PTK_LIST_DEFINE(bool);
|
||||||
|
|
||||||
static PtkHandle m_root_component;
|
static PtkHandle m_root_component;
|
||||||
static PTK_LIST(PtkHandle) m_components;
|
// TODO: figure out a way to actually use bool here
|
||||||
|
// this happens because PTK_LIST_DEFINE and PTK_LIST_NEW
|
||||||
|
// use PTK_LIST themselves, bool gets put through the first
|
||||||
|
// and turned into _Bool which is then used as the actual
|
||||||
|
// type's name; using PTK_LIST directly only processes it once
|
||||||
|
// so we have to use _Bool here
|
||||||
|
static PTK_LIST(_Bool) m_update;
|
||||||
|
|
||||||
|
typedef PTK_LIST(Vertex) Vertices;
|
||||||
|
typedef PTK_LIST(uint32_t) Indices;
|
||||||
|
|
||||||
|
PTK_LIST_DEFINE(Vertices);
|
||||||
|
PTK_LIST_DEFINE(Indices);
|
||||||
|
|
||||||
|
PTK_LIST(Vertices) m_vertices_cache;
|
||||||
|
PTK_LIST(Indices) m_indices_cache;
|
||||||
|
|
||||||
PTK_LIST(Vertex) g_vertices;
|
PTK_LIST(Vertex) g_vertices;
|
||||||
PTK_LIST(uint32_t) g_indices;
|
PTK_LIST(uint32_t) g_indices;
|
||||||
|
@ -21,13 +38,19 @@ static const PtkVec2 uvs[] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
void vk_init_vertices(void) {
|
void vk_init_vertices(void) {
|
||||||
m_components = PTK_LIST_NEW(PtkHandle, 1);
|
m_update = PTK_LIST_NEW(bool, 1);
|
||||||
|
|
||||||
|
m_vertices_cache = PTK_LIST_NEW(Vertices, 1);
|
||||||
|
m_indices_cache = PTK_LIST_NEW(Indices, 1);
|
||||||
|
|
||||||
g_vertices = PTK_LIST_NEW(Vertex, 0);
|
g_vertices = PTK_LIST_NEW(Vertex, 0);
|
||||||
g_indices = PTK_LIST_NEW(uint32_t, 0);
|
g_indices = PTK_LIST_NEW(uint32_t, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void triangle(const PtkTriangle *triangle) {
|
void triangle(const PtkTriangle *triangle) {
|
||||||
|
PTK_LIST_SET(Vertices, m_vertices_cache, triangle->id, PTK_LIST_NEW(Vertex, 3));
|
||||||
|
PTK_LIST_SET(Indices, m_indices_cache, triangle->id, PTK_LIST_NEW(uint32_t, 3));
|
||||||
|
|
||||||
for (size_t i = 0; i < 3; ++i) {
|
for (size_t i = 0; i < 3; ++i) {
|
||||||
Vertex v = {
|
Vertex v = {
|
||||||
.pos = triangle->vertices[i],
|
.pos = triangle->vertices[i],
|
||||||
|
@ -39,10 +62,16 @@ void triangle(const PtkTriangle *triangle) {
|
||||||
uint32_t old_vertex_count = g_vertices.size;
|
uint32_t old_vertex_count = g_vertices.size;
|
||||||
PTK_LIST_ADD(Vertex, g_vertices, v);
|
PTK_LIST_ADD(Vertex, g_vertices, v);
|
||||||
PTK_LIST_ADD(uint32_t, g_indices, old_vertex_count);
|
PTK_LIST_ADD(uint32_t, g_indices, old_vertex_count);
|
||||||
|
|
||||||
|
PTK_LIST_ADD(Vertex, m_vertices_cache.data[triangle->id], v);
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[triangle->id], old_vertex_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void rect(const PtkRect *rect) {
|
void rect(const PtkRect *rect) {
|
||||||
|
PTK_LIST_SET(Vertices, m_vertices_cache, rect->id, PTK_LIST_NEW(Vertex, 4));
|
||||||
|
PTK_LIST_SET(Indices, m_indices_cache, rect->id, PTK_LIST_NEW(uint32_t, 6));
|
||||||
|
|
||||||
const float x = rect->top_left.x;
|
const float x = rect->top_left.x;
|
||||||
const float y = rect->top_left.y;
|
const float y = rect->top_left.y;
|
||||||
const float w = rect->size.w;
|
const float w = rect->size.w;
|
||||||
|
@ -97,6 +126,19 @@ void rect(const PtkRect *rect) {
|
||||||
PTK_LIST_ADD(uint32_t, g_indices, top_right_index);
|
PTK_LIST_ADD(uint32_t, g_indices, top_right_index);
|
||||||
PTK_LIST_ADD(uint32_t, g_indices, bottom_left_index);
|
PTK_LIST_ADD(uint32_t, g_indices, bottom_left_index);
|
||||||
PTK_LIST_ADD(uint32_t, g_indices, bottom_right_index);
|
PTK_LIST_ADD(uint32_t, g_indices, bottom_right_index);
|
||||||
|
|
||||||
|
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], top_right);
|
||||||
|
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], bottom_left);
|
||||||
|
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], top_left);
|
||||||
|
PTK_LIST_ADD(Vertex, m_vertices_cache.data[rect->id], bottom_right);
|
||||||
|
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_left_index);
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_right_index);
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_left_index);
|
||||||
|
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], top_right_index);
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_left_index);
|
||||||
|
PTK_LIST_ADD(uint32_t, m_indices_cache.data[rect->id], bottom_right_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ellipse(const PtkEllipse *ellipse) {
|
void ellipse(const PtkEllipse *ellipse) {
|
||||||
|
@ -117,19 +159,28 @@ void ellipse(const PtkEllipse *ellipse) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void component(PtkHandle c) {
|
void component(PtkHandle c) {
|
||||||
PTK_LIST_ADD(PtkHandle, m_components, c);
|
if (!m_update.data[c->id]) {
|
||||||
|
Vertices vcache = m_vertices_cache.data[c->id];
|
||||||
|
Indices icache = m_indices_cache.data[c->id];
|
||||||
|
PTK_LIST_ADD_ALL_P(Vertex, g_vertices, vcache.data, vcache.size);
|
||||||
|
PTK_LIST_ADD_ALL_P(uint32_t, g_indices, icache.data, icache.size);
|
||||||
|
} else {
|
||||||
|
PTK_LIST_SET(bool, m_update, c->id, false);
|
||||||
|
PTK_LIST_CLEAR(m_vertices_cache.data[c->id]);
|
||||||
|
PTK_LIST_CLEAR(m_indices_cache.data[c->id]);
|
||||||
|
|
||||||
switch (c->type) {
|
switch (c->type) {
|
||||||
case PTK_COMPONENT_TYPE_TRIANGLE: {
|
case PTK_COMPONENT_TYPE_TRIANGLE: {
|
||||||
triangle((PtkTriangle *)c);
|
triangle((PtkTriangle *)c);
|
||||||
} break;
|
} break;
|
||||||
case PTK_COMPONENT_TYPE_RECT: {
|
case PTK_COMPONENT_TYPE_RECT: {
|
||||||
rect((PtkRect *)c);
|
rect((PtkRect *)c);
|
||||||
} break;
|
} break;
|
||||||
case PTK_COMPONENT_TYPE_ELLIPSE: {
|
case PTK_COMPONENT_TYPE_ELLIPSE: {
|
||||||
ellipse((PtkEllipse *)c);
|
ellipse((PtkEllipse *)c);
|
||||||
} break;
|
} break;
|
||||||
default: break;
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
||||||
child->parent = c;
|
child->parent = c;
|
||||||
|
@ -137,13 +188,20 @@ void component(PtkHandle c) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void init_component(PtkHandle c) {
|
||||||
|
PTK_LIST_SET(bool, m_update, c->id, true);
|
||||||
|
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
||||||
|
init_component(child);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
void vk_init_components(PtkHandle root) {
|
void vk_init_components(PtkHandle root) {
|
||||||
m_root_component = root;
|
m_root_component = root;
|
||||||
|
init_component(root);
|
||||||
vk_update_components();
|
vk_update_components();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_update_components(void) {
|
void vk_update_components(void) {
|
||||||
PTK_LIST_CLEAR(m_components);
|
|
||||||
PTK_LIST_CLEAR(g_vertices);
|
PTK_LIST_CLEAR(g_vertices);
|
||||||
PTK_LIST_CLEAR(g_indices);
|
PTK_LIST_CLEAR(g_indices);
|
||||||
component(m_root_component);
|
component(m_root_component);
|
||||||
|
@ -202,31 +260,54 @@ bool intersects(const PtkHandle component, const PtkPos point) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void set_component_updated(PtkHandle c) {
|
||||||
|
PTK_LIST_SET(bool, m_update, c->id, true);
|
||||||
|
if (c->parent != PTK_NULL_HANDLE) {
|
||||||
|
set_component_updated(c->parent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void handle_mouse(PtkHandle c, const PtkPos cursor_pos, const int button, const int mods) {
|
||||||
|
if (c->type != PTK_COMPONENT_TYPE_CLICKABLE) {
|
||||||
|
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
||||||
|
handle_mouse(child, cursor_pos, button, mods);
|
||||||
|
})
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
PtkClickable *clickable = (PtkClickable *)c;
|
||||||
|
|
||||||
|
if (intersects((PtkHandle)clickable, cursor_pos)) {
|
||||||
|
clickable->on_press(clickable, button, mods);
|
||||||
|
// TODO: make some proper updating system
|
||||||
|
// currently if I just updated clickable it would mark
|
||||||
|
// its parents up to the root for an update
|
||||||
|
// but not its child - the actual hitbox; this is very ugly
|
||||||
|
// and should probably done in another way
|
||||||
|
set_component_updated(clickable->children.data[0]);
|
||||||
|
vk_update_components();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void vk_handle_mouse_button_input(const PtkPos cursor_pos, const int button, const int action, const int mods) {
|
void vk_handle_mouse_button_input(const PtkPos cursor_pos, const int button, const int action, const int mods) {
|
||||||
if (action == GLFW_RELEASE) {
|
if (action == GLFW_RELEASE) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTK_LIST_FOR_EACH(PtkHandle, m_components, current, {
|
handle_mouse(m_root_component, cursor_pos, button, mods);
|
||||||
if (current->type != PTK_COMPONENT_TYPE_CLICKABLE) {
|
}
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
PtkClickable *c = (PtkClickable *)current;
|
void cleanup_component(PtkHandle c) {
|
||||||
|
PTK_LIST_FOR_EACH(PtkHandle, c->children, child, {
|
||||||
if (intersects((PtkHandle)c, cursor_pos)) {
|
cleanup_component(child);
|
||||||
c->on_press(c, button, mods);
|
|
||||||
vk_update_components();
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
free(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vk_components_cleanup(void) {
|
void vk_components_cleanup(void) {
|
||||||
PTK_LIST_FOR_EACH(PtkHandle, m_components, c, {
|
cleanup_component(m_root_component);
|
||||||
free(c);
|
|
||||||
})
|
|
||||||
|
|
||||||
PTK_LIST_FREE(m_components);
|
|
||||||
PTK_LIST_FREE(g_vertices);
|
PTK_LIST_FREE(g_vertices);
|
||||||
PTK_LIST_FREE(g_indices);
|
PTK_LIST_FREE(g_indices);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue