base: 将通用动态数组操作接入 layout/state/config

This commit is contained in:
2026-03-24 20:09:55 +08:00
parent e7a519be6a
commit e6b4486f89
8 changed files with 31 additions and 92 deletions

View File

@@ -5,6 +5,12 @@
#include "base/memory.h" #include "base/memory.h"
static constexpr size_t INIT_CAPACITY = 4;
static inline size_t next_capacity(size_t capacity) {
if (capacity) return capacity * 2;
return INIT_CAPACITY;
}
/** /**
* @file array.h * @file array.h
* @brief 动态数组基础操作。 * @brief 动态数组基础操作。

View File

@@ -5,8 +5,6 @@
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include "base/macros.h"
#define p_alloc_nr(x) (((x) + 16) * 3 / 2) #define p_alloc_nr(x) (((x) + 16) * 3 / 2)
#define p_new(type, count) ((type *)xmalloc(sizeof(type) * (count))) #define p_new(type, count) ((type *)xmalloc(sizeof(type) * (count)))
#define p_clear(p, count) ((void)memset((p), 0, sizeof(*(p)) * (count))) #define p_clear(p, count) ((void)memset((p), 0, sizeof(*(p)) * (count)))
@@ -65,9 +63,3 @@ static inline void xrealloc(void **ptr, ssize_t newsize) {
* Unlike strlen(), a_strlen() accepts nullptr and returns 0 in that case. * Unlike strlen(), a_strlen() accepts nullptr and returns 0 in that case.
*/ */
static inline ssize_t a_strlen(const char *s) { return s ? strlen(s) : 0; } static inline ssize_t a_strlen(const char *s) { return s ? strlen(s) : 0; }
static constexpr size_t INIT_CAPACITY = 4;
static inline size_t next_capacity(size_t capacity) {
if (capacity) return capacity * 2;
return INIT_CAPACITY;
}

View File

@@ -3,6 +3,7 @@
#include <dlfcn.h> #include <dlfcn.h>
#include <zdwm/config.h> #include <zdwm/config.h>
#include "base/array.h"
#include "base/memory.h" #include "base/memory.h"
#include "config/defaults.h" #include "config/defaults.h"
#include "config/loader.h" #include "config/loader.h"
@@ -42,31 +43,6 @@ static void config_builder_cleanup(zdwm_config_builder_t *builder) {
builder->output_count = 0; builder->output_count = 0;
} }
static bool config_builder_init(zdwm_config_builder_t *builder,
size_t output_count) {
if (!builder || output_count == 0) return false;
p_clear(builder, 1);
builder->output_count = output_count;
layout_registry_init(&builder->layouts);
return true;
}
static bool config_builder_ensure_workspace_capacity(
zdwm_config_builder_t *builder) {
if (!builder) return false;
if (builder->workspace_count < builder->workspace_capacity) return true;
size_t capacity = next_capacity(builder->workspace_capacity);
if (!builder->workspaces) {
builder->workspaces = p_new(workspace_desc_t, capacity);
} else {
p_realloc(&builder->workspaces, capacity);
}
builder->workspace_capacity = capacity;
return true;
}
static layout_id_t runtime_config_register_layout( static layout_id_t runtime_config_register_layout(
zdwm_config_builder_t *builder, const char *name, const char *symbol, zdwm_config_builder_t *builder, const char *name, const char *symbol,
const char *description, layout_fn fn) { const char *description, layout_fn fn) {
@@ -101,18 +77,15 @@ static workspace_id_t runtime_config_define_workspace(
return ZDWM_WORKSPACE_ID_INVALID; return ZDWM_WORKSPACE_ID_INVALID;
} }
} }
if (!config_builder_ensure_workspace_capacity(builder)) {
return ZDWM_WORKSPACE_ID_INVALID;
}
workspace_id_t workspace_id = (workspace_id_t)builder->workspace_count; workspace_id_t workspace_id = (workspace_id_t)builder->workspace_count;
workspace_desc_t *slot = &builder->workspaces[builder->workspace_count]; workspace_desc_t *slot = array_push(
builder->workspaces, builder->workspace_count, builder->workspace_capacity);
slot->output_index = output_index; slot->output_index = output_index;
slot->name = p_strdup(name); slot->name = p_strdup(name);
slot->layout_ids = p_copy(layout_ids, layout_count); slot->layout_ids = p_copy(layout_ids, layout_count);
slot->layout_count = layout_count; slot->layout_count = layout_count;
slot->initial_layout_id = initial_layout_id; slot->initial_layout_id = initial_layout_id;
builder->workspace_count++;
return workspace_id; return workspace_id;
} }
@@ -138,7 +111,7 @@ static bool runtime_config_build(zdwm_config_setup_fn *setup,
runtime_init_desc_t *out) { runtime_init_desc_t *out) {
if (!setup || !out) return false; if (!setup || !out) return false;
zdwm_config_builder_t builder = {0}; zdwm_config_builder_t builder = {0};
if (!config_builder_init(&builder, output_count)) return false; builder.output_count = output_count;
zdwm_api_t api = { zdwm_api_t api = {
.abi_version = ZDWM_CONFIG_ABI_VERSION, .abi_version = ZDWM_CONFIG_ABI_VERSION,

View File

@@ -4,13 +4,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "base/array.h"
#include "base/memory.h" #include "base/memory.h"
#include "core/types.h"
void layout_result_init(layout_result_t *result) {
result->item_count = 0;
result->item_capacity = INIT_CAPACITY;
result->items = p_new(layout_item_t, result->item_capacity);
}
void layout_result_cleanup(layout_result_t *result) { void layout_result_cleanup(layout_result_t *result) {
p_delete(&result->items); p_delete(&result->items);
@@ -19,19 +15,9 @@ void layout_result_cleanup(layout_result_t *result) {
} }
void layout_result_push(layout_result_t *result, layout_item_t item) { void layout_result_push(layout_result_t *result, layout_item_t item) {
if (result->item_count == result->item_capacity) { layout_item_t *slot =
size_t new_capacity = next_capacity(result->item_capacity); array_push(result->items, result->item_count, result->item_capacity);
p_realloc(&result->items, new_capacity); *slot = item;
result->item_capacity = new_capacity;
}
result->items[result->item_count++] = item;
}
void layout_registry_init(layout_registry_t *registry) {
registry->slot_count = 0;
registry->slot_capacity = INIT_CAPACITY;
registry->slots = p_new(layout_slot_t, registry->slot_capacity);
} }
void layout_registry_cleanup(layout_registry_t *registry) { void layout_registry_cleanup(layout_registry_t *registry) {
@@ -77,22 +63,16 @@ layout_id_t layout_register(layout_registry_t *registry, const char *name,
layout_fn fn) { layout_fn fn) {
if (!name || !symbol) return ZDWM_LAYOUT_ID_INVALID; if (!name || !symbol) return ZDWM_LAYOUT_ID_INVALID;
if (registry->slot_count == registry->slot_capacity) {
size_t new_capacity = next_capacity(registry->slot_capacity);
p_realloc(&registry->slots, new_capacity);
registry->slot_capacity = new_capacity;
}
layout_id_t id = (layout_id_t)registry->slot_count; layout_id_t id = (layout_id_t)registry->slot_count;
layout_slot_t *r =
layout_slot_t *r = &registry->slots[registry->slot_count]; array_push(registry->slots, registry->slot_count, registry->slot_capacity);
r->id = id; r->id = id;
r->name = p_strdup(name); r->name = p_strdup(name);
r->symbol = p_strdup(symbol); r->symbol = p_strdup(symbol);
r->description = p_strdup_nullable(description); r->description = p_strdup_nullable(description);
r->fn = fn; r->fn = fn;
registry->slot_count++; return r->id;
return id;
} }
layout_fn layout_get(const layout_registry_t *registry, layout_id_t id) { layout_fn layout_get(const layout_registry_t *registry, layout_id_t id) {

View File

@@ -47,24 +47,10 @@ typedef struct layout_registry_t {
size_t slot_capacity; size_t slot_capacity;
} layout_registry_t; } layout_registry_t;
/*
* 调用约束:
* - result 必须是有效的非空指针
* - 除 init 之外,其余 result 相关接口都要求 result 已初始化
* - 传入空指针或未初始化对象属于调用方错误
*/
void layout_result_init(layout_result_t *result);
void layout_result_cleanup(layout_result_t *result); void layout_result_cleanup(layout_result_t *result);
void layout_result_push(layout_result_t *result, layout_item_t item); void layout_result_push(layout_result_t *result, layout_item_t item);
/*
* 调用约束:
* - registry 必须是有效的非空指针
* - 除 init 之外,其余 registry 相关接口都要求 registry 已初始化
* - 传入空指针或未初始化对象属于调用方错误
*/
void layout_registry_init(layout_registry_t *registry);
void layout_registry_cleanup(layout_registry_t *registry); void layout_registry_cleanup(layout_registry_t *registry);
bool layout_registry_move(layout_registry_t *src, layout_registry_t *dest); bool layout_registry_move(layout_registry_t *src, layout_registry_t *dest);
size_t layout_registry_count(const layout_registry_t *registry); size_t layout_registry_count(const layout_registry_t *registry);

View File

@@ -3,6 +3,7 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include "base/array.h"
#include "base/log.h" #include "base/log.h"
#include "base/memory.h" #include "base/memory.h"
#include "core/types.h" #include "core/types.h"
@@ -257,19 +258,19 @@ const window_t *state_window_add(state_t *state, const window_info_t *info) {
window_id_t id = info->id; window_id_t id = info->id;
window_t *window = (window_t *)state_window_get(state, id); window_t *window = (window_t *)state_window_get(state, id);
if (!window) { if (!window) {
if (state->window_count == state->window_capacity) { size_t index = state->window_count;
size_t capacity = next_capacity(state->window_capacity); size_t old_capacity = state->window_capacity;
p_realloc(&state->windows, capacity); window =
p_realloc(&state->stack_order, capacity); array_push(state->windows, state->window_count, state->window_capacity);
state->window_capacity = capacity; if (old_capacity != state->window_capacity) {
p_realloc(&state->stack_order, state->window_capacity);
} }
window = &state->windows[state->window_count];
p_clear(window, 1); p_clear(window, 1);
window->id = id; window->id = id;
window->workspace_id = ZDWM_WORKSPACE_ID_INVALID; window->workspace_id = ZDWM_WORKSPACE_ID_INVALID;
state->stack_order[state->window_count] = id; state->stack_order[index] = id;
state->window_count++;
} }
state_window_set_geometry_mode(state, id, info->geometry_mode); state_window_set_geometry_mode(state, id, info->geometry_mode);

View File

@@ -1,6 +1,7 @@
#include "rect.h" #include "rect.h"
#include "utils.h" #include "base/macros.h"
#include "base/memory.h"
static inline bool rect_valid(rect_t rect) { static inline bool rect_valid(rect_t rect) {
return rect.x1 < rect.x2 && rect.y1 < rect.y2; return rect.x1 < rect.x2 && rect.y1 < rect.y2;

View File

@@ -98,7 +98,6 @@ static void test_runtime_config_keeps_module_loaded_after_runtime_init(
assert(layout != nullptr); assert(layout != nullptr);
layout_result_t result = {0}; layout_result_t result = {0};
layout_result_init(&result);
layout_ctx_t ctx = { layout_ctx_t ctx = {
.workspace_id = 0, .workspace_id = 0,
@@ -120,7 +119,8 @@ static void test_runtime_config_keeps_module_loaded_after_runtime_init(
assert(runtime.config_module_handle == nullptr); assert(runtime.config_module_handle == nullptr);
} }
static void test_runtime_config_falls_back_to_defaults_when_implicit_library_is_missing( static void
test_runtime_config_falls_back_to_defaults_when_implicit_library_is_missing(
void) { void) {
config_test_clear_env(); config_test_clear_env();