dm: прямой обмен сообщениями (DM) + soundtouch + архитектура звонков
- src/dm/: dm_core/dm_crypto/dm_mailbox — прямой обмен сообщениями (DM) - lib/soundtouch-master/: vendored SoundTouch (изменение темпа/высоты аудио) - doc/dm_arch.md, doc/chat_call_arch.md: архитектура DM и звонков - tests: test_dm.c, test_dm_e2e.c - chat: рефакторинг chat_* модулей, member_sync, invite_build - chatgui/chatgui-android: синхронизация с новым API чата - lib/u_async, debug_config, utun_instance: сопутствующие изменения
This commit is contained in:
1 parent
761f64cf76
commit
73fe99b33f
123 files changed
+14095
-1270
No files matched your search
+58
-53
@@ -2,22 +2,19 @@
|
||||
* chat_setting.c — chat-related settings: validation, storage, on-the-fly apply
|
||||
*
|
||||
* Используется и из парсера конфига (headless), и из GUI (через bridge).
|
||||
* Никаких зависимостей от g_cc или instance — работает автономно.
|
||||
* Состояние per-instance (struct chat_setting_state).
|
||||
*/
|
||||
|
||||
#include "chat_setting.h"
|
||||
#include "../utun_instance.h"
|
||||
#include "../../lib/debug_config.h"
|
||||
|
||||
#ifdef DEBUG_CATEGORY_CHAT_SYNC
|
||||
#define CS_ID DEBUG_CATEGORY_CHAT_SYNC
|
||||
#else
|
||||
#define CS_ID DEBUG_CATEGORY_GENERAL
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define CS_ID DEBUG_CATEGORY_CHAT_SYNC
|
||||
|
||||
/* ─── типы настроек ─── */
|
||||
|
||||
#define CHAT_SETTING_INT 0
|
||||
@@ -32,12 +29,6 @@ struct chat_setting_def {
|
||||
int max_val;
|
||||
};
|
||||
|
||||
/* хранилище для строковых значений */
|
||||
#define CHAT_SETTING_STRING_MAX 16
|
||||
static int g_chat_string_idx[CHAT_SETTING_STRING_MAX];
|
||||
static char g_chat_string_val[CHAT_SETTING_STRING_MAX][256];
|
||||
static int g_chat_string_count = 0;
|
||||
|
||||
/* ─── реестр всех известных настроек ─── */
|
||||
|
||||
static const struct chat_setting_def g_setting_defs[] = {
|
||||
@@ -59,38 +50,32 @@ static const struct chat_setting_def g_setting_defs[] = {
|
||||
|
||||
#define CHAT_SETTING_COUNT (sizeof(g_setting_defs) / sizeof(g_setting_defs[0]))
|
||||
|
||||
/* ─── состояние (текущие значения) ─── */
|
||||
/* ─── state helpers ─── */
|
||||
|
||||
static int g_chat_values[CHAT_SETTING_COUNT];
|
||||
static int g_chat_initialized = 0;
|
||||
|
||||
static void chat_setting_reset_defaults(void) {
|
||||
static void chat_setting_reset_defaults(struct chat_setting_state* s) {
|
||||
for (size_t i = 0; i < CHAT_SETTING_COUNT; i++)
|
||||
g_chat_values[i] = g_setting_defs[i].default_val;
|
||||
g_chat_initialized = 1;
|
||||
s->values[i] = g_setting_defs[i].default_val;
|
||||
s->initialized = 1;
|
||||
}
|
||||
|
||||
/* ─── поиск ─── */
|
||||
|
||||
static int chat_setting_find(const char* name) {
|
||||
for (size_t i = 0; i < CHAT_SETTING_COUNT; i++)
|
||||
if (strcmp(g_setting_defs[i].name, name) == 0) return (int)i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* ─── apply: вызов специфичного для настройки кода ─── */
|
||||
|
||||
static void chat_setting_apply(void) {
|
||||
static void chat_setting_apply(struct chat_setting_state* s) {
|
||||
(void)s;
|
||||
/* будет заполняться по мере появления runtime-setter'ов в модулях:
|
||||
if (idx == ...) some_module_set_xxx(value); */
|
||||
}
|
||||
|
||||
/* ─── public API ─── */
|
||||
/* ─── state-level API ─── */
|
||||
|
||||
int chat_setting_set(const char* name, const char* value) {
|
||||
if (!name || !value || !*name || !*value) return -2;
|
||||
int chat_setting_set_state(struct chat_setting_state* s, const char* name, const char* value) {
|
||||
if (!s || !name || !value || !*name || !*value) return -2;
|
||||
|
||||
if (!g_chat_initialized) chat_setting_reset_defaults();
|
||||
if (!s->initialized) chat_setting_reset_defaults(s);
|
||||
|
||||
int idx = chat_setting_find(name);
|
||||
if (idx < 0) {
|
||||
@@ -102,25 +87,24 @@ int chat_setting_set(const char* name, const char* value) {
|
||||
int v;
|
||||
|
||||
if (def->type == CHAT_SETTING_STRING) {
|
||||
/* сохраняем строку в отдельном хранилище */
|
||||
for (int i = 0; i < g_chat_string_count; i++) {
|
||||
if (g_chat_string_idx[i] == idx) {
|
||||
if (strcmp(g_chat_string_val[i], value) == 0) return 0;
|
||||
snprintf(g_chat_string_val[i], sizeof(g_chat_string_val[i]), "%s", value);
|
||||
for (int i = 0; i < s->string_count; i++) {
|
||||
if (s->string_idx[i] == idx) {
|
||||
if (strcmp(s->string_val[i], value) == 0) return 0;
|
||||
snprintf(s->string_val[i], sizeof(s->string_val[i]), "%s", value);
|
||||
DEBUG_INFO(CS_ID, "chat_setting: %s = %s", name, value);
|
||||
chat_setting_apply();
|
||||
chat_setting_apply(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (g_chat_string_count >= CHAT_SETTING_STRING_MAX) {
|
||||
if (s->string_count >= CHAT_SETTING_STRING_MAX) {
|
||||
DEBUG_ERROR(CS_ID, "chat_setting: string storage full for '%s'", name);
|
||||
return -2;
|
||||
}
|
||||
g_chat_string_idx[g_chat_string_count] = idx;
|
||||
snprintf(g_chat_string_val[g_chat_string_count], sizeof(g_chat_string_val[0]), "%s", value);
|
||||
g_chat_string_count++;
|
||||
s->string_idx[s->string_count] = idx;
|
||||
snprintf(s->string_val[s->string_count], sizeof(s->string_val[0]), "%s", value);
|
||||
s->string_count++;
|
||||
DEBUG_INFO(CS_ID, "chat_setting: %s = %s", name, value);
|
||||
chat_setting_apply();
|
||||
chat_setting_apply(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -138,34 +122,55 @@ int chat_setting_set(const char* name, const char* value) {
|
||||
v = (int)lv;
|
||||
}
|
||||
|
||||
if (g_chat_values[idx] == v) return 0;
|
||||
if (s->values[idx] == v) return 0;
|
||||
|
||||
g_chat_values[idx] = v;
|
||||
s->values[idx] = v;
|
||||
DEBUG_INFO(CS_ID, "chat_setting: %s = %s", name, value);
|
||||
chat_setting_apply();
|
||||
chat_setting_apply(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* chat_setting_get(const char* name) {
|
||||
if (!g_chat_initialized) chat_setting_reset_defaults();
|
||||
const char* chat_setting_get_state(const struct chat_setting_state* s, const char* name) {
|
||||
if (!s || !s->initialized) return NULL;
|
||||
int idx = chat_setting_find(name);
|
||||
if (idx < 0) return NULL;
|
||||
|
||||
const struct chat_setting_def* def = &g_setting_defs[idx];
|
||||
if (def->type == CHAT_SETTING_STRING) {
|
||||
for (int i = 0; i < g_chat_string_count; i++) {
|
||||
if (g_chat_string_idx[i] == idx) return g_chat_string_val[i];
|
||||
for (int i = 0; i < s->string_count; i++) {
|
||||
if (s->string_idx[i] == idx) return s->string_val[i];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
static char buf[16];
|
||||
snprintf(buf, sizeof(buf), "%d", g_chat_values[idx]);
|
||||
return buf;
|
||||
snprintf((char*)s->int_buf, sizeof(s->int_buf), "%d", s->values[idx]);
|
||||
return s->int_buf;
|
||||
}
|
||||
|
||||
int chat_setting_get_int(const char* name, int def) {
|
||||
if (!g_chat_initialized) chat_setting_reset_defaults();
|
||||
int chat_setting_get_int_state(const struct chat_setting_state* s, const char* name, int def) {
|
||||
if (!s || !s->initialized) return def;
|
||||
int idx = chat_setting_find(name);
|
||||
return idx >= 0 ? g_chat_values[idx] : def;
|
||||
return idx >= 0 ? s->values[idx] : def;
|
||||
}
|
||||
|
||||
/* ─── instance-level API ─── */
|
||||
|
||||
static struct chat_setting_state* cs_state(struct UTUN_INSTANCE* inst) {
|
||||
return inst ? &inst->chat_settings : NULL;
|
||||
}
|
||||
|
||||
int chat_setting_set(struct UTUN_INSTANCE* inst, const char* name, const char* value) {
|
||||
struct chat_setting_state* s = cs_state(inst);
|
||||
if (!s) return -2;
|
||||
return chat_setting_set_state(s, name, value);
|
||||
}
|
||||
|
||||
const char* chat_setting_get(struct UTUN_INSTANCE* inst, const char* name) {
|
||||
struct chat_setting_state* s = cs_state(inst);
|
||||
return s ? chat_setting_get_state(s, name) : NULL;
|
||||
}
|
||||
|
||||
int chat_setting_get_int(struct UTUN_INSTANCE* inst, const char* name, int def) {
|
||||
struct chat_setting_state* s = cs_state(inst);
|
||||
return s ? chat_setting_get_int_state(s, name, def) : def;
|
||||
}
|
||||
Reference in new issue
Block a user