add array & signal utils

This commit is contained in:
falsycat 2023-11-25 15:23:58 +09:00
parent 7897f8ede2
commit ce9936ad3b
6 changed files with 186 additions and 0 deletions

View File

@ -44,6 +44,7 @@ struct nf7_mod* nf7_core_sdl2_new(const struct nf7* nf7) {
.poll_interval = 30,
};
nf7_util_signal_init(&this->update, this->malloc);
if (!(new_setup_gl_() && new_init_win_(this))) {
goto ABORT;
@ -104,6 +105,8 @@ static void del_(struct nf7_mod* this_) {
if (nullptr != this->win) {
SDL_DestroyWindow(this->win);
}
nf7_util_signal_deinit(&this->update);
nf7_util_malloc_del(this->malloc, this);
}
if (0 == atomic_fetch_sub(&sdl_refcnt_, 1)) {

View File

@ -9,6 +9,7 @@
#include "nf7.h"
#include "util/malloc.h"
#include "util/signal.h"
extern const struct nf7_mod_meta nf7_core_sdl2;
@ -26,6 +27,9 @@ struct nf7_core_sdl2 {
// uv handles (immutable)
uv_timer_t poll_timer;
// signals
struct nf7_util_signal update;
// mutable parameters
uint64_t poll_interval;
};

3
main.c
View File

@ -8,6 +8,8 @@
#include "nf7.h"
#include "util/malloc.h"
#include "core/all.h"
@ -25,6 +27,7 @@ int main(int argc, char** argv) {
.argc = argc,
.argv = (const char* const*) argv,
.uv = &uv,
.malloc = &(struct nf7_util_malloc) {0},
};
// load modules

View File

@ -3,6 +3,8 @@ target_sources(nf7util
PRIVATE
malloc.c
PUBLIC
array.h
malloc.h
signal.h
)
target_link_libraries(nf7util PRIVATE nf7config)

105
util/array.h Normal file
View File

@ -0,0 +1,105 @@
// No copyright
#pragma once
#include <assert.h>
#include <stdint.h>
#include <string.h>
#include "util/malloc.h"
#define NF7_UTIL_ARRAY(PREFIX, T) \
struct PREFIX { \
struct nf7_util_malloc* malloc; \
\
uint64_t n; \
T* ptr; \
}; \
\
static inline void PREFIX##_init(struct PREFIX* this, struct nf7_util_malloc* malloc) { \
assert(nullptr != this); \
assert(nullptr != malloc); \
*this = (struct PREFIX) { \
.malloc = malloc, \
}; \
} \
static inline void PREFIX##_deinit(struct PREFIX* this) { \
assert(nullptr != this); \
nf7_util_malloc_del(this->malloc, this->ptr); \
*this = (struct PREFIX) {}; \
} \
\
static inline bool PREFIX##_resize(struct PREFIX* this, uint64_t n) { \
assert(nullptr != this); \
\
if (this->n == n) { \
return true; \
} \
const bool extend = this->n < n; \
\
T* const newptr = \
nf7_util_malloc_renew(this->malloc, this->ptr, n*sizeof(T)); \
if (nullptr == newptr) { \
if (extend) { return false; } \
} else { \
this->ptr = newptr; \
} \
\
if (extend) { \
memset(this->ptr[this->n], 0, (n - this->n) * sizeof(T)); \
} \
this->n = n; \
return true; \
} \
\
static inline bool PREFIX##_insert(struct PREFIX* this, uint64_t idx, T item) { \
assert(nullptr != this); \
\
if (idx > this->n) { \
idx = this->n; \
} \
if (!PREFIX##_resize(this, this->n+1)) { \
return false; \
} \
const uint64_t tails = this->n - idx - 1; \
memmove(&this->ptr[idx+1], &this->ptr[idx], tails*sizeof(T)); \
this->ptr[this->n] = item; \
return true; \
} \
\
static inline void PREFIX##_remove(struct PREFIX* this, uint64_t idx) { \
assert(nullptr != this); \
\
if (0 == this->n) { \
return; \
} \
if (idx >= this->n) { \
idx = this->n - 1; \
} \
const uint64_t tails = this->n - idx - 1; \
memmove(&this->ptr[idx], &this->ptr[idx+1], tails*sizeof(T)); \
} \
\
static inline bool PREFIX##_find(struct PREFIX* this, uint64_t* idx, const T needle) { \
assert(nullptr != this); \
assert(nullptr != idx); \
\
for (uint64_t i = 0; i < this->n; ++i) { \
if (this->ptr[i] == needle) { \
*idx = i; \
return true; \
} \
} \
return false; \
} \
static inline bool PREFIX##_find_and_remove(struct PREFIX* this, const T needle) { \
assert(nullptr != this); \
\
uint64_t idx; \
if (!PREFIX##_find(this, &idx, needle)) { \
return false; \
} \
PREFIX##_remove(this, idx); \
return true; \
} \
static_assert(true)

69
util/signal.h Normal file
View File

@ -0,0 +1,69 @@
// No copyright
#pragma once
#include "util/array.h"
#include "util/malloc.h"
struct nf7_util_signal;
struct nf7_util_signal_recv;
NF7_UTIL_ARRAY(nf7_util_signal_recvs, struct nf7_util_signal_recv*);
struct nf7_util_signal {
bool emitting;
struct nf7_util_signal_recvs recvs;
};
struct nf7_util_signal_recv {
struct nf7_util_signal* signal;
void* data;
void (*func)(struct nf7_util_signal_recv*);
};
static inline void nf7_util_signal_init(
struct nf7_util_signal* this, struct nf7_util_malloc* malloc) {
assert(nullptr != this);
assert(nullptr != malloc);
*this = (struct nf7_util_signal) {};
nf7_util_signal_recvs_init(&this->recvs, malloc);
}
static inline void nf7_util_signal_deinit(struct nf7_util_signal* this) {
assert(nullptr != this);
for (uint64_t i = 0; i < this->recvs.n; ++i) {
this->recvs.ptr[i]->signal = nullptr;
}
nf7_util_signal_recvs_deinit(&this->recvs);
}
static inline void nf7_util_signal_emit(struct nf7_util_signal* this) {
this->emitting = true;
for (uint64_t i = 0; i < this->recvs.n; ++i) {
const struct nf7_util_signal_recv* recv = this->recvs.ptr[i];
recv->func(recv->data);
}
this->emitting = false;
}
static inline bool nf7_util_signal_recv_set(
struct nf7_util_signal_recv* this, struct nf7_util_signal* signal) {
assert(nullptr != this);
assert(nullptr != this->func);
assert(!signal->emitting);
if (!nf7_util_signal_recvs_insert(&signal->recvs, UINT64_MAX, this)) {
return false;
}
this->signal = signal;
return true;
}
static inline void nf7_util_signal_recv_unset(struct nf7_util_signal_recv* this) {
assert(nullptr != this);
if (nullptr == this->signal) {
return;
}
nf7_util_signal_recvs_find_and_remove(&this->signal->recvs, this);
}