Add generic dynamic array type
This commit is contained in:
parent
89e548eca8
commit
7769f5fd58
6 changed files with 94 additions and 79 deletions
|
|
@ -2,49 +2,29 @@
|
|||
|
||||
struct kubo_context *kubo_context_init() {
|
||||
struct kubo_context *context = malloc(sizeof(struct kubo_context));
|
||||
if (!context) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
context->num_walls_alloc = KUBO_CONTEXT_NUM_WALLS_ALLOC;
|
||||
context->walls =
|
||||
malloc(sizeof(struct kubo_wall) * context->num_walls_alloc);
|
||||
kubo_wall_arr_init(&context->walls);
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void kubo_context_cleanup(struct kubo_context *context) {
|
||||
free(context->walls);
|
||||
kubo_wall_arr_free(&context->walls);
|
||||
free(context);
|
||||
}
|
||||
|
||||
bool kubo_context_add_wall(struct kubo_context *context,
|
||||
struct kubo_wall *wall) {
|
||||
|
||||
struct kubo_wall **new_walls;
|
||||
|
||||
if (context->num_walls == context->num_walls_alloc - 1) {
|
||||
|
||||
context->num_walls_alloc *= 2;
|
||||
|
||||
new_walls = realloc(context->walls, sizeof(struct kubo_wall *) *
|
||||
context->num_walls_alloc);
|
||||
|
||||
if (!new_walls)
|
||||
return false;
|
||||
|
||||
context->walls = new_walls;
|
||||
}
|
||||
|
||||
context->walls[context->num_walls++] = wall;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context) {
|
||||
|
||||
if (context->num_walls > 0) {
|
||||
switch (context->walls[context->num_walls - 1]->state) {
|
||||
if (context->walls.count > 0) {
|
||||
struct kubo_wall *last_wall =
|
||||
kubo_wall_arr_get(&context->walls, context->walls.count - 1);
|
||||
switch (last_wall->state) {
|
||||
case KUBO_WALL_INIT:
|
||||
case KUBO_WALL_DRAWING:
|
||||
return context->walls[context->num_walls - 1];
|
||||
return last_wall;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -52,7 +32,7 @@ struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context) {
|
|||
}
|
||||
|
||||
struct kubo_wall *wall = kubo_wall_init();
|
||||
kubo_context_add_wall(context, wall);
|
||||
kubo_wall_arr_add(&context->walls, wall);
|
||||
|
||||
return wall;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,24 +5,19 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kubo_dynarray.h"
|
||||
#include "kubo_wall.h"
|
||||
|
||||
#define KUBO_CONTEXT_NUM_WALLS_ALLOC 4
|
||||
KUBO_DYNARRAY_REGISTER(kubo_wall_arr, struct kubo_wall *);
|
||||
|
||||
struct kubo_context {
|
||||
bool exit_pending;
|
||||
|
||||
struct kubo_wall **walls;
|
||||
unsigned int num_walls;
|
||||
unsigned int num_walls_alloc;
|
||||
struct kubo_wall_arr walls;
|
||||
};
|
||||
|
||||
struct kubo_context *kubo_context_init();
|
||||
void kubo_context_cleanup(struct kubo_context *context);
|
||||
|
||||
bool kubo_context_add_wall(struct kubo_context *context,
|
||||
struct kubo_wall *wall);
|
||||
|
||||
struct kubo_wall *kubo_context_get_pending_wall(struct kubo_context *context);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
50
kubo_dynarray.h
Normal file
50
kubo_dynarray.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
#ifndef KUBO_DYNARRAY_H
|
||||
#define KUBO_DYNARRAY_H
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define KUBO_DRYNARRAY_DEFAULT_CAP 4
|
||||
|
||||
#define KUBO_DYNARRAY_REGISTER(name, type) \
|
||||
struct name { \
|
||||
type *data; \
|
||||
size_t count; \
|
||||
size_t capacity; \
|
||||
}; \
|
||||
\
|
||||
static inline void name##_init(struct name *arr) { \
|
||||
arr->count = 0; \
|
||||
arr->capacity = KUBO_DRYNARRAY_DEFAULT_CAP; \
|
||||
arr->data = malloc(sizeof(type) * arr->capacity); \
|
||||
} \
|
||||
\
|
||||
static inline void name##_free(struct name *arr) { free(arr->data); } \
|
||||
\
|
||||
static inline bool name##_reserve(struct name *arr, size_t new_cap) { \
|
||||
if (arr->capacity >= new_cap) \
|
||||
return true; \
|
||||
type *new_data = realloc(arr->data, sizeof(type) * new_cap); \
|
||||
if (!new_data) \
|
||||
return false; \
|
||||
arr->data = new_data; \
|
||||
arr->capacity = new_cap; \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline bool name##_add(struct name *arr, type new_val) { \
|
||||
if (arr->count == arr->capacity - 1) { \
|
||||
if (!name##_reserve(arr, arr->capacity * 2)) { \
|
||||
return false; \
|
||||
} \
|
||||
} \
|
||||
arr->data[arr->count++] = new_val; \
|
||||
return true; \
|
||||
} \
|
||||
\
|
||||
static inline type name##_get(struct name *arr, size_t index) { \
|
||||
assert(index < arr->count); \
|
||||
return arr->data[index]; \
|
||||
}
|
||||
|
||||
#endif
|
||||
33
kubo_wall.c
33
kubo_wall.c
|
|
@ -6,37 +6,22 @@ struct kubo_wall *kubo_wall_init() {
|
|||
if (!wall)
|
||||
return NULL;
|
||||
|
||||
wall->num_vertices_alloc = KUBO_WALL_INIT_VERTICES;
|
||||
wall->vertices = malloc(sizeof(Vector2) * wall->num_vertices_alloc);
|
||||
wall->num_vertices = 0;
|
||||
wall->state = KUBO_WALL_INIT;
|
||||
|
||||
kubo_vector2_arr_init(&wall->vertices);
|
||||
|
||||
return wall;
|
||||
}
|
||||
|
||||
void kubo_wall_cleanup(struct kubo_wall *wall) {
|
||||
free(wall->vertices);
|
||||
kubo_vector2_arr_free(&wall->vertices);
|
||||
free(wall);
|
||||
}
|
||||
|
||||
bool kubo_wall_append(struct kubo_wall *wall, Vector2 vertex) {
|
||||
|
||||
Vector2 *new_vertices;
|
||||
|
||||
if (wall->num_vertices == wall->num_vertices_alloc - 1) {
|
||||
|
||||
wall->num_vertices_alloc *= 2;
|
||||
|
||||
new_vertices =
|
||||
realloc(wall->vertices, sizeof(Vector2) * wall->num_vertices_alloc);
|
||||
|
||||
if (!new_vertices)
|
||||
return false;
|
||||
|
||||
wall->vertices = new_vertices;
|
||||
}
|
||||
|
||||
wall->vertices[wall->num_vertices++] = vertex;
|
||||
|
||||
return true;
|
||||
bool kubo_wall_add_vertex(struct kubo_wall *wall, Vector2 vec) {
|
||||
return kubo_vector2_arr_add(&wall->vertices, vec);
|
||||
}
|
||||
|
||||
Vector2 kubo_wall_get_vertex(struct kubo_wall *wall, size_t index) {
|
||||
return kubo_vector2_arr_get(&wall->vertices, index);
|
||||
}
|
||||
|
|
|
|||
13
kubo_wall.h
13
kubo_wall.h
|
|
@ -4,6 +4,8 @@
|
|||
#include <stdlib.h>
|
||||
#include <raylib.h>
|
||||
|
||||
#include "kubo_dynarray.h"
|
||||
|
||||
#define KUBO_WALL_INIT_VERTICES 4
|
||||
|
||||
enum kubo_wall_state {
|
||||
|
|
@ -12,17 +14,18 @@ enum kubo_wall_state {
|
|||
KUBO_WALL_DONE
|
||||
};
|
||||
|
||||
struct kubo_wall {
|
||||
Vector2 *vertices;
|
||||
unsigned int num_vertices;
|
||||
unsigned int num_vertices_alloc;
|
||||
KUBO_DYNARRAY_REGISTER(kubo_vector2_arr, Vector2)
|
||||
|
||||
struct kubo_wall {
|
||||
struct kubo_vector2_arr vertices;
|
||||
enum kubo_wall_state state;
|
||||
};
|
||||
|
||||
struct kubo_wall *kubo_wall_init();
|
||||
void kubo_wall_cleanup(struct kubo_wall *wall);
|
||||
|
||||
bool kubo_wall_append(struct kubo_wall *wall, Vector2 vertex);
|
||||
bool kubo_wall_add_vertex(struct kubo_wall *wall, Vector2 vec);
|
||||
Vector2 kubo_wall_get_vertex(struct kubo_wall *wall, size_t index);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -34,15 +34,17 @@ void kubo_window_render(struct kubo_context *context) {
|
|||
DrawSplineLinear(points, 2, 10.f, BLACK);
|
||||
}
|
||||
|
||||
for (int i = 0; i < context->num_walls; i++) {
|
||||
DrawSplineLinear(context->walls[i]->vertices,
|
||||
context->walls[i]->num_vertices, 10.f, BLACK);
|
||||
if (context->walls[i]->state == KUBO_WALL_STARTED) {
|
||||
Vector2 mouse_pos = GetMousePosition();
|
||||
Vector2 points[] = {
|
||||
context->walls[i]
|
||||
->vertices[context->walls[i]->num_vertices - 1],
|
||||
mouse_pos};
|
||||
for (int i = 0; i < context->walls.count; i++) {
|
||||
struct kubo_wall *wall = kubo_wall_arr_get(&context->walls, i);
|
||||
assert(wall != NULL);
|
||||
|
||||
DrawSplineLinear(wall->vertices.data, wall->vertices.count, 10.f,
|
||||
BLACK);
|
||||
|
||||
if (wall->state == KUBO_WALL_DRAWING) {
|
||||
Vector2 mouse = GetMousePosition();
|
||||
Vector2 points[] = {wall->vertices.data[wall->vertices.count - 1],
|
||||
mouse};
|
||||
DrawSplineLinear(points, 2, 10.f, BLACK);
|
||||
}
|
||||
}
|
||||
|
|
@ -59,8 +61,8 @@ void kubo_window_input(struct kubo_context *context) {
|
|||
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) {
|
||||
Vector2 new_pos = GetMousePosition();
|
||||
kubo_wall_append(current_wall, new_pos);
|
||||
current_wall->state = KUBO_WALL_STARTED;
|
||||
kubo_wall_add_vertex(current_wall, new_pos);
|
||||
current_wall->state = KUBO_WALL_DRAWING;
|
||||
} else if (IsMouseButtonPressed(MOUSE_BUTTON_RIGHT)) {
|
||||
current_wall->state = KUBO_WALL_DONE;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue