[RELEASE] u22-v03
This version is submitted to U22 breau.
This commit is contained in:
17
core/loground/CMakeLists.txt
Normal file
17
core/loground/CMakeLists.txt
Normal file
@@ -0,0 +1,17 @@
|
||||
add_library(loground
|
||||
base.c
|
||||
island.c
|
||||
misc.c
|
||||
pool.c
|
||||
)
|
||||
target_link_libraries(loground
|
||||
msgpackc
|
||||
|
||||
math
|
||||
memory
|
||||
mpkutil
|
||||
|
||||
locommon
|
||||
loentity
|
||||
loshader
|
||||
)
|
228
core/loground/base.c
Normal file
228
core/loground/base.c
Normal file
@@ -0,0 +1,228 @@
|
||||
#include "./base.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
#include "util/mpkutil/get.h"
|
||||
#include "util/mpkutil/pack.h"
|
||||
|
||||
#include "core/locommon/msgpack.h"
|
||||
#include "core/locommon/position.h"
|
||||
#include "core/loentity/entity.h"
|
||||
#include "core/loentity/ground.h"
|
||||
#include "core/loshader/ground.h"
|
||||
|
||||
#include "./island.h"
|
||||
#include "./misc.h"
|
||||
|
||||
#define LOGROUND_BASE_PARAM_TO_PACK_EACH_(PROC, PROC_str, PROC_type) do { \
|
||||
PROC_str ("subclass", "ground"); \
|
||||
PROC_type ("type", type); \
|
||||
PROC ("id", super.super.id); \
|
||||
PROC ("pos", super.super.pos); \
|
||||
PROC ("size", super.size); \
|
||||
} while (0)
|
||||
#define LOGROUND_BASE_PARAM_TO_PACK_COUNT 5
|
||||
|
||||
static void loground_base_delete_(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
loground_base_t* base = (typeof(base)) entity;
|
||||
if (!base->used) return;
|
||||
|
||||
base->used = false;
|
||||
|
||||
# define each_(NAME, name) do { \
|
||||
if (base->type == LOGROUND_TYPE_##NAME) { \
|
||||
loground_##name##_tear_down(base); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
assert(false);
|
||||
|
||||
# undef each_
|
||||
}
|
||||
|
||||
static void loground_base_die_(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
}
|
||||
|
||||
static bool loground_base_update_(loentity_t* entity) {
|
||||
assert(entity != NULL);
|
||||
|
||||
loground_base_t* base = (typeof(base)) entity;
|
||||
base->cache = (typeof(base->cache)) {0};
|
||||
|
||||
# define each_(NAME, name) do { \
|
||||
if (base->type == LOGROUND_TYPE_##NAME) { \
|
||||
return loground_##name##_update(base); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
return false;
|
||||
|
||||
# undef each_
|
||||
}
|
||||
|
||||
static void loground_base_draw_(
|
||||
loentity_t* entity, const locommon_position_t* basepos) {
|
||||
assert(entity != NULL);
|
||||
assert(locommon_position_valid(basepos));
|
||||
|
||||
loground_base_t* base = (typeof(base)) entity;
|
||||
|
||||
vec2_t p;
|
||||
locommon_position_sub(&p, &base->super.super.pos, basepos);
|
||||
vec2_addeq(&base->cache.instance.pos, &p);
|
||||
|
||||
loshader_ground_drawer_add_instance(base->drawer, &base->cache.instance);
|
||||
}
|
||||
|
||||
static void loground_base_pack_(
|
||||
const loentity_t* entity, msgpack_packer* packer) {
|
||||
assert(entity != NULL);
|
||||
assert(packer != NULL);
|
||||
|
||||
const loground_base_t* base = (typeof(base)) entity;
|
||||
|
||||
msgpack_pack_map(packer, LOGROUND_BASE_PARAM_TO_PACK_COUNT+1);
|
||||
|
||||
# define pack_(name, var) do { \
|
||||
mpkutil_pack_str(packer, name); \
|
||||
LOCOMMON_MSGPACK_PACK_ANY(packer, &base->var); \
|
||||
} while (0)
|
||||
# define pack_str_(name, str) do { \
|
||||
mpkutil_pack_str(packer, name); \
|
||||
mpkutil_pack_str(packer, str); \
|
||||
} while (0)
|
||||
# define pack_type_(name, var) do { \
|
||||
mpkutil_pack_str(packer, name); \
|
||||
mpkutil_pack_str(packer, loground_type_stringify(base->var)); \
|
||||
} while (0)
|
||||
|
||||
|
||||
LOGROUND_BASE_PARAM_TO_PACK_EACH_(pack_, pack_str_, pack_type_);
|
||||
|
||||
# undef pack_type_
|
||||
# undef pack_str_
|
||||
# undef pack_
|
||||
|
||||
# define each_(NAME, name) do { \
|
||||
if (base->type == LOGROUND_TYPE_##NAME) { \
|
||||
loground_##name##_pack_data(base, packer); \
|
||||
return; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
mpkutil_pack_str(packer, "data");
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
assert(false);
|
||||
|
||||
# undef each_
|
||||
}
|
||||
|
||||
void loground_base_initialize(
|
||||
loground_base_t* base, loshader_ground_drawer_t* drawer) {
|
||||
assert(base != NULL);
|
||||
assert(drawer != NULL);
|
||||
|
||||
*base = (typeof(*base)) {
|
||||
.super = {
|
||||
.super = {
|
||||
.vtable = {
|
||||
.delete = loground_base_delete_,
|
||||
.die = loground_base_die_,
|
||||
.update = loground_base_update_,
|
||||
.draw = loground_base_draw_,
|
||||
.pack = loground_base_pack_,
|
||||
},
|
||||
.subclass = LOENTITY_SUBCLASS_GROUND,
|
||||
},
|
||||
},
|
||||
.drawer = drawer,
|
||||
};
|
||||
}
|
||||
|
||||
void loground_base_reinitialize(loground_base_t* base, loentity_id_t id) {
|
||||
assert(base != NULL);
|
||||
|
||||
# define reset_(name, var) do { \
|
||||
base->var = (typeof(base->var)) {0}; \
|
||||
} while (0)
|
||||
# define reset_str_(name, str)
|
||||
|
||||
LOGROUND_BASE_PARAM_TO_PACK_EACH_(reset_, reset_str_, reset_);
|
||||
|
||||
# undef reset_str_
|
||||
# undef reset_
|
||||
|
||||
base->super.super.id = id;
|
||||
}
|
||||
|
||||
void loground_base_deinitialize(loground_base_t* base) {
|
||||
assert(base != NULL);
|
||||
|
||||
loground_base_delete_(&base->super.super);
|
||||
}
|
||||
|
||||
bool loground_base_unpack(loground_base_t* base, const msgpack_object *obj) {
|
||||
assert(base != NULL);
|
||||
assert(obj != NULL);
|
||||
|
||||
loground_base_reinitialize(base, 0);
|
||||
/* id will be overwritten below */
|
||||
|
||||
const char* v;
|
||||
size_t vlen;
|
||||
|
||||
const msgpack_object_map* root = mpkutil_get_map(obj);
|
||||
|
||||
# define item_(v) mpkutil_get_map_item_by_str(root, v)
|
||||
|
||||
# define unpack_(name, var) do { \
|
||||
if (!LOCOMMON_MSGPACK_UNPACK_ANY(item_(name), &base->var)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
# define unpack_type_(name, var) do { \
|
||||
if (!mpkutil_get_str(item_(name), &v, &vlen) || \
|
||||
!loground_type_unstringify(&base->var, v, vlen)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
# define unpack_str_(name, str) do { \
|
||||
if (!mpkutil_get_str(item_(name), &v, &vlen) || \
|
||||
!(strncmp(v, str, vlen) == 0 && str[vlen] == 0)) { \
|
||||
return NULL; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_BASE_PARAM_TO_PACK_EACH_(unpack_, unpack_str_, unpack_type_);
|
||||
|
||||
# undef unpack_str_
|
||||
# undef unpack_type_
|
||||
# undef unpack_
|
||||
|
||||
const msgpack_object* data = item_("data");
|
||||
# define each_(NAME, name) do { \
|
||||
if (base->type == LOGROUND_TYPE_##NAME) { \
|
||||
return loground_##name##_unpack_data(base, data); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
return false;
|
||||
|
||||
# undef each_
|
||||
|
||||
# undef item_
|
||||
}
|
54
core/loground/base.h
Normal file
54
core/loground/base.h
Normal file
@@ -0,0 +1,54 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "core/loentity/entity.h"
|
||||
#include "core/loentity/ground.h"
|
||||
#include "core/loshader/ground.h"
|
||||
|
||||
#include "./misc.h"
|
||||
|
||||
typedef struct {
|
||||
loentity_ground_t super;
|
||||
bool used;
|
||||
|
||||
/* injected deps */
|
||||
loshader_ground_drawer_t* drawer;
|
||||
|
||||
/* params not to be packed */
|
||||
struct {
|
||||
loshader_ground_drawer_instance_t instance;
|
||||
} cache;
|
||||
|
||||
/* params to be packed (includes id, pos, and size) */
|
||||
loground_type_t type;
|
||||
|
||||
# define LOGROUND_BASE_DATA_MAX_SIZE 256
|
||||
uint8_t data[LOGROUND_BASE_DATA_MAX_SIZE];
|
||||
} loground_base_t;
|
||||
|
||||
void
|
||||
loground_base_initialize(
|
||||
loground_base_t* base,
|
||||
loshader_ground_drawer_t* drawer
|
||||
);
|
||||
|
||||
void
|
||||
loground_base_reinitialize(
|
||||
loground_base_t* base,
|
||||
loentity_id_t id
|
||||
);
|
||||
|
||||
void
|
||||
loground_base_deinitialize(
|
||||
loground_base_t* base
|
||||
);
|
||||
|
||||
bool
|
||||
loground_base_unpack(
|
||||
loground_base_t* base,
|
||||
const msgpack_object *obj
|
||||
);
|
35
core/loground/island.c
Normal file
35
core/loground/island.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./base.h"
|
||||
#include "./misc.h"
|
||||
|
||||
bool loground_island_update(loground_base_t* base) {
|
||||
assert(base != NULL);
|
||||
|
||||
base->cache.instance = (loshader_ground_drawer_instance_t) {
|
||||
.ground_id = LOSHADER_GROUND_ID_ISLAND,
|
||||
.size = base->super.size,
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
void loground_island_build(
|
||||
loground_base_t* base,
|
||||
const locommon_position_t* pos,
|
||||
const vec2_t* size) {
|
||||
assert(base != NULL);
|
||||
assert(locommon_position_valid(pos));
|
||||
assert(vec2_valid(size));
|
||||
assert(size->x >= 0 && size->y >= 0);
|
||||
|
||||
base->type = LOGROUND_TYPE_ISLAND;
|
||||
|
||||
base->super.super.pos = *pos;
|
||||
base->super.size = *size;
|
||||
}
|
31
core/loground/island.h
Normal file
31
core/loground/island.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/locommon/position.h"
|
||||
|
||||
#include "./base.h"
|
||||
|
||||
bool
|
||||
loground_island_update(
|
||||
loground_base_t* base
|
||||
);
|
||||
|
||||
void
|
||||
loground_island_build(
|
||||
loground_base_t* base,
|
||||
const locommon_position_t* pos,
|
||||
const vec2_t* size
|
||||
);
|
||||
|
||||
#define loground_island_tear_down(base)
|
||||
|
||||
#define loground_island_pack_data(base, packer) \
|
||||
msgpack_pack_nil(packer)
|
||||
|
||||
#define loground_island_unpack_data(base, obj) \
|
||||
(obj != NULL)
|
37
core/loground/misc.c
Normal file
37
core/loground/misc.c
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "./misc.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
const char* loground_type_stringify(loground_type_t type) {
|
||||
# define each_(NAME, name) do { \
|
||||
if (type == LOGROUND_TYPE_##NAME) return #name; \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
|
||||
assert(false);
|
||||
return NULL;
|
||||
|
||||
# undef each_
|
||||
}
|
||||
|
||||
bool loground_type_unstringify(
|
||||
loground_type_t* type, const char* v, size_t len) {
|
||||
assert(type != NULL);
|
||||
assert(v != NULL || len == 0);
|
||||
|
||||
# define each_(NAME, name) do { \
|
||||
if (strncmp(v, #name, len) == 0 && #name[len] == 0) { \
|
||||
*type = LOGROUND_TYPE_##NAME; \
|
||||
return true; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
LOGROUND_TYPE_EACH_(each_);
|
||||
return false;
|
||||
|
||||
# undef each_
|
||||
}
|
25
core/loground/misc.h
Normal file
25
core/loground/misc.h
Normal file
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* dont forget to update EACH macro */
|
||||
typedef enum {
|
||||
LOGROUND_TYPE_ISLAND,
|
||||
} loground_type_t;
|
||||
|
||||
#define LOGROUND_TYPE_EACH_(PROC) do { \
|
||||
PROC(ISLAND, island); \
|
||||
} while (0)
|
||||
|
||||
const char*
|
||||
loground_type_stringify(
|
||||
loground_type_t type
|
||||
);
|
||||
|
||||
bool
|
||||
loground_type_unstringify(
|
||||
loground_type_t* type,
|
||||
const char* v,
|
||||
size_t len
|
||||
);
|
89
core/loground/pool.c
Normal file
89
core/loground/pool.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include "./pool.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/memory/memory.h"
|
||||
|
||||
#include "core/locommon/counter.h"
|
||||
#include "core/loshader/ground.h"
|
||||
|
||||
#include "./base.h"
|
||||
|
||||
struct loground_pool_t {
|
||||
loshader_ground_drawer_t* drawer;
|
||||
locommon_counter_t* idgen;
|
||||
|
||||
size_t length;
|
||||
loground_base_t items[1];
|
||||
};
|
||||
|
||||
static size_t loground_pool_find_unused_item_index_(
|
||||
const loground_pool_t* pool) {
|
||||
assert(pool != NULL);
|
||||
|
||||
for (size_t i = 0; i < pool->length; ++i) {
|
||||
if (!pool->items[i].used) return i;
|
||||
}
|
||||
fprintf(stderr, "ground pool overflow\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
loground_pool_t* loground_pool_new(
|
||||
loshader_ground_drawer_t* drawer,
|
||||
locommon_counter_t* idgen,
|
||||
size_t length) {
|
||||
assert(drawer != NULL);
|
||||
assert(idgen != NULL);
|
||||
assert(length > 0);
|
||||
|
||||
loground_pool_t* pool = memory_new(
|
||||
sizeof(*pool) + (length-1)*sizeof(pool->items[0]));
|
||||
*pool = (typeof(*pool)) {
|
||||
.drawer = drawer,
|
||||
.idgen = idgen,
|
||||
.length = length,
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < pool->length; ++i) {
|
||||
loground_base_initialize(&pool->items[i], drawer);
|
||||
}
|
||||
return pool;
|
||||
}
|
||||
|
||||
void loground_pool_delete(loground_pool_t* pool) {
|
||||
assert(pool != NULL);
|
||||
|
||||
for (size_t i = 0; i < pool->length; ++i) {
|
||||
loground_base_deinitialize(&pool->items[i]);
|
||||
}
|
||||
memory_delete(pool);
|
||||
}
|
||||
|
||||
loground_base_t* loground_pool_create(loground_pool_t* pool) {
|
||||
assert(pool != NULL);
|
||||
|
||||
const size_t i = loground_pool_find_unused_item_index_(pool);
|
||||
|
||||
loground_base_reinitialize(
|
||||
&pool->items[i], locommon_counter_count(pool->idgen));
|
||||
|
||||
pool->items[i].used = true;
|
||||
return &pool->items[i];
|
||||
}
|
||||
|
||||
loground_base_t* loground_pool_unpack_item(
|
||||
loground_pool_t* pool, const msgpack_object* obj) {
|
||||
assert(pool != NULL);
|
||||
|
||||
const size_t i = loground_pool_find_unused_item_index_(pool);
|
||||
|
||||
if (!loground_base_unpack(&pool->items[i], obj)) return NULL;
|
||||
|
||||
pool->items[i].used = true;
|
||||
return &pool->items[i];
|
||||
}
|
39
core/loground/pool.h
Normal file
39
core/loground/pool.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <msgpack.h>
|
||||
|
||||
#include "util/math/vector.h"
|
||||
|
||||
#include "core/lobullet/pool.h"
|
||||
#include "core/locommon/counter.h"
|
||||
#include "core/loshader/ground.h"
|
||||
|
||||
#include "./base.h"
|
||||
|
||||
struct loground_pool_t;
|
||||
typedef struct loground_pool_t loground_pool_t;
|
||||
|
||||
loground_pool_t* /* OWNERSHIP */
|
||||
loground_pool_new(
|
||||
loshader_ground_drawer_t* drawer,
|
||||
locommon_counter_t* idgen,
|
||||
size_t length
|
||||
);
|
||||
|
||||
void
|
||||
loground_pool_delete(
|
||||
loground_pool_t* pool /* OWNERSHIP */
|
||||
);
|
||||
|
||||
loground_base_t* /* OWNERSHIP */
|
||||
loground_pool_create(
|
||||
loground_pool_t* pool
|
||||
);
|
||||
|
||||
loground_base_t* /* OWNERSHIP/NULLABLE */
|
||||
loground_pool_unpack_item(
|
||||
loground_pool_t* pool,
|
||||
const msgpack_object* obj
|
||||
);
|
Reference in New Issue
Block a user