Change signature

This commit is contained in:
cpq committed 2026-04-18 05:39:42 +01:00
1 parent f123bf3154
commit 06a9f71b1e
2 files changed
+76 -114

No files matched your search

+38 -57
View File
@@ -3140,28 +3140,21 @@ void mg_rpc_list(struct mg_rpc_req *r);
enum mg_val_type { MG_VAL_INT, MG_VAL_BOOL, MG_VAL_DBL, MG_VAL_STR };
enum mg_val_type { MG_VAL_INT, MG_VAL_BOOL, MG_VAL_DBL, MG_VAL_STR, MG_VAL_FN };
union mg_val {
int i;
bool b;
double d;
struct mg_str s;
void (*fn)(void);
};
struct mg_field {
const char *name;
enum mg_val_type type;
union mg_val value;
};
typedef void (*mg_dash_get_fn)(struct mg_field *);
typedef void (*mg_dash_set_fn)(struct mg_field *);
struct mg_dash {
struct mg_field *fields;
mg_dash_get_fn get;
mg_dash_set_fn set;
void (*get)(union mg_val *);
void (*set)(const union mg_val *);
};
static inline struct mg_str trimq(struct mg_str s) { // Trim double quotes
@@ -3218,35 +3211,41 @@ static inline struct mg_field *mg_dash_find_field(struct mg_field *fields,
static inline size_t mg_print_field(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_field *f = va_arg(*ap, struct mg_field *);
union mg_val val = {0};
size_t n = 0;
if (f->get) f->get(&val);
n += mg_xprintf(fn, arg, "%m:", MG_ESC(f->name));
if (f->type == MG_VAL_BOOL) {
n += mg_xprintf(fn, arg, "%s", f->value.b ? "true" : "false");
n += mg_xprintf(fn, arg, "%s", val.b ? "true" : "false");
} else if (f->type == MG_VAL_INT) {
n += mg_xprintf(fn, arg, "%d", f->value.i);
n += mg_xprintf(fn, arg, "%d", val.i);
} else if (f->type == MG_VAL_DBL) {
n += mg_xprintf(fn, arg, "%g", f->value.d);
n += mg_xprintf(fn, arg, "%g", val.d);
} else if (f->type == MG_VAL_STR) {
struct mg_str s = f->value.s;
n += mg_xprintf(fn, arg, "%m", mg_print_esc, s.len, s.buf);
n += mg_xprintf(fn, arg, "%m", mg_print_esc, val.s.len, val.s.buf);
} else if (f->type == MG_VAL_FN) {
n += mg_xprintf(fn, arg, "%M", val.fn);
} else {
n += mg_xprintf(fn, arg, "null");
}
return n;
}
static inline bool mg_parse_field(struct mg_str json, struct mg_field *f) {
static inline bool mg_parse_field(struct mg_str json, struct mg_field *f,
union mg_val *val) {
bool ok = false;
if (f->type == MG_VAL_BOOL) {
ok = mg_json_get_bool(json, "$", &f->value.b);
ok = mg_json_get_bool(json, "$", &val->b);
} else if (f->type == MG_VAL_INT) {
double d;
ok = mg_json_get_num(json, "$", &d);
if (ok) f->value.i = (int) d;
if (ok) val->i = (int) d;
} else if (f->type == MG_VAL_DBL) {
ok = mg_json_get_num(json, "$", &f->value.d);
ok = mg_json_get_num(json, "$", &val->d);
} else if (f->type == MG_VAL_STR) {
f->value.s = trimq(json);
val->s = trimq(json);
} else if (f->type == MG_VAL_FN) {
val->s = json;
}
return ok;
}
@@ -3254,7 +3253,7 @@ static inline bool mg_parse_field(struct mg_str json, struct mg_field *f) {
static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_str *req = va_arg(*ap, struct mg_str *);
struct mg_field *fields = va_arg(*ap, struct mg_field *);
mg_dash_get_fn get = va_arg(*ap, mg_dash_get_fn);
// mg_dash_get_fn get = va_arg(*ap, mg_dash_get_fn);
struct mg_str name = trimq(mg_json_get_tok(*req, "$.params"));
struct mg_field *f = mg_dash_find_field(fields, name);
size_t i, n = 0;
@@ -3262,15 +3261,12 @@ static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
const char *comma = "";
n += mg_xprintf(fn, arg, "{");
for (i = 0; fields[i].name != NULL; i++) {
f = &fields[i];
if (get) get(f);
n += mg_xprintf(fn, arg, "%s", comma);
n += mg_xprintf(fn, arg, "%M", mg_print_field, f);
n += mg_xprintf(fn, arg, "%M", mg_print_field, &fields[i]);
comma = ",";
}
n += mg_xprintf(fn, arg, "}");
} else if (f != NULL) {
if (get) get(f);
n += mg_xprintf(fn, arg, "{%M}", mg_print_field, f);
} else {
n += mg_xprintf(fn, arg, "null");
@@ -3278,58 +3274,43 @@ static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
return n;
}
static inline bool mg_dash_sync(struct mg_mgr *mgr, struct mg_field *f,
mg_dash_get_fn get) {
union mg_val old_value = f->value;
bool changed = false;
if (get) get(f);
// Strings require special comparison
if (f->type == MG_VAL_STR && mg_strcmp(old_value.s, f->value.s) != 0) {
changed = true;
} else if (memcmp(&f->value, &old_value, sizeof(old_value)) != 0) {
changed = true;
}
if (changed && f != NULL) {
static inline void mg_dash_send_change(struct mg_mgr *mgr, struct mg_field *f) {
if (f != NULL) {
mg_dash_broadcast(mgr, "{%m:%m,%m:{%M}}", MG_ESC("method"),
MG_ESC("change"), MG_ESC("params"), mg_print_field, f);
}
return changed;
}
static inline bool mg_dash_apply(struct mg_connection *c, struct mg_str json,
struct mg_field *fields, mg_dash_get_fn get,
mg_dash_set_fn set) {
static inline void mg_dash_apply(struct mg_connection *c, struct mg_str json,
struct mg_field *fields) {
struct mg_str key, val;
size_t ofs = 0;
struct mg_field *f = NULL;
bool changed = false;
while ((ofs = mg_json_next(json, ofs, &key, &val)) > 0) {
key = trimq(key);
if ((f = mg_dash_find_field(fields, key)) != NULL) {
struct mg_field tmp = *f;
mg_parse_field(val, &tmp);
if (set) set(&tmp);
if (mg_dash_sync(c->mgr, f, get)) changed = true;
if ((f = mg_dash_find_field(fields, key)) != NULL && f->set != NULL) {
union mg_val v = {0};
mg_parse_field(val, f, &v);
f->set(&v);
mg_dash_send_change(c->mgr, f);
break;
} else {
MG_ERROR(("UNKNOWN FIELD: [%.*s]", key.len, key.buf));
}
}
return changed;
}
static inline void mg_dash_process_msg(struct mg_connection *c,
struct mg_ws_message *wm,
struct mg_field *fields,
mg_dash_get_fn get, mg_dash_set_fn set) {
struct mg_field *fields) {
struct mg_str req = wm->data;
struct mg_str method = trimq(mg_json_get_tok(req, "$.method"));
if (mg_match(method, mg_str("get"), NULL)) {
mg_dash_success(c, req, "%M", mg_dash_print, &req, fields, get);
mg_dash_success(c, req, "%M", mg_dash_print, &req, fields);
} else if (mg_match(method, mg_str("set"), NULL)) {
struct mg_str params = trimq(mg_json_get_tok(req, "$.params"));
bool changed = mg_dash_apply(c, params, fields, get, set);
mg_dash_success(c, req, "%s", changed ? "true" : "false");
mg_dash_apply(c, params, fields);
mg_dash_success(c, req, "%s", "true");
} else {
mg_dash_error(c, req, "%s", "unknown method");
}
@@ -3350,12 +3331,12 @@ static inline void mg_dash_ev_handler(struct mg_connection *c, int ev,
}
} else if (ev == MG_EV_WS_MSG) {
// Add this to automatically handle "get" and "set" JSON-RPC calls
struct mg_dash *dash = (struct mg_dash *) c->fn_data;
struct mg_field *fields = (struct mg_field *) c->fn_data;
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
if (dash == NULL || dash->fields == NULL) {
if (fields == NULL) {
mg_dash_error(c, wm->data, "%s", "no fields defined");
} else {
mg_dash_process_msg(c, wm, dash->fields, dash->get, dash->set);
mg_dash_process_msg(c, wm, fields);
}
}
}
+38 -57
View File
@@ -2,28 +2,21 @@
#include "ws.h"
enum mg_val_type { MG_VAL_INT, MG_VAL_BOOL, MG_VAL_DBL, MG_VAL_STR };
enum mg_val_type { MG_VAL_INT, MG_VAL_BOOL, MG_VAL_DBL, MG_VAL_STR, MG_VAL_FN };
union mg_val {
int i;
bool b;
double d;
struct mg_str s;
void (*fn)(void);
};
struct mg_field {
const char *name;
enum mg_val_type type;
union mg_val value;
};
typedef void (*mg_dash_get_fn)(struct mg_field *);
typedef void (*mg_dash_set_fn)(struct mg_field *);
struct mg_dash {
struct mg_field *fields;
mg_dash_get_fn get;
mg_dash_set_fn set;
void (*get)(union mg_val *);
void (*set)(const union mg_val *);
};
static inline struct mg_str trimq(struct mg_str s) { // Trim double quotes
@@ -80,35 +73,41 @@ static inline struct mg_field *mg_dash_find_field(struct mg_field *fields,
static inline size_t mg_print_field(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_field *f = va_arg(*ap, struct mg_field *);
union mg_val val = {0};
size_t n = 0;
if (f->get) f->get(&val);
n += mg_xprintf(fn, arg, "%m:", MG_ESC(f->name));
if (f->type == MG_VAL_BOOL) {
n += mg_xprintf(fn, arg, "%s", f->value.b ? "true" : "false");
n += mg_xprintf(fn, arg, "%s", val.b ? "true" : "false");
} else if (f->type == MG_VAL_INT) {
n += mg_xprintf(fn, arg, "%d", f->value.i);
n += mg_xprintf(fn, arg, "%d", val.i);
} else if (f->type == MG_VAL_DBL) {
n += mg_xprintf(fn, arg, "%g", f->value.d);
n += mg_xprintf(fn, arg, "%g", val.d);
} else if (f->type == MG_VAL_STR) {
struct mg_str s = f->value.s;
n += mg_xprintf(fn, arg, "%m", mg_print_esc, s.len, s.buf);
n += mg_xprintf(fn, arg, "%m", mg_print_esc, val.s.len, val.s.buf);
} else if (f->type == MG_VAL_FN) {
n += mg_xprintf(fn, arg, "%M", val.fn);
} else {
n += mg_xprintf(fn, arg, "null");
}
return n;
}
static inline bool mg_parse_field(struct mg_str json, struct mg_field *f) {
static inline bool mg_parse_field(struct mg_str json, struct mg_field *f,
union mg_val *val) {
bool ok = false;
if (f->type == MG_VAL_BOOL) {
ok = mg_json_get_bool(json, "$", &f->value.b);
ok = mg_json_get_bool(json, "$", &val->b);
} else if (f->type == MG_VAL_INT) {
double d;
ok = mg_json_get_num(json, "$", &d);
if (ok) f->value.i = (int) d;
if (ok) val->i = (int) d;
} else if (f->type == MG_VAL_DBL) {
ok = mg_json_get_num(json, "$", &f->value.d);
ok = mg_json_get_num(json, "$", &val->d);
} else if (f->type == MG_VAL_STR) {
f->value.s = trimq(json);
val->s = trimq(json);
} else if (f->type == MG_VAL_FN) {
val->s = json;
}
return ok;
}
@@ -116,7 +115,7 @@ static inline bool mg_parse_field(struct mg_str json, struct mg_field *f) {
static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
struct mg_str *req = va_arg(*ap, struct mg_str *);
struct mg_field *fields = va_arg(*ap, struct mg_field *);
mg_dash_get_fn get = va_arg(*ap, mg_dash_get_fn);
// mg_dash_get_fn get = va_arg(*ap, mg_dash_get_fn);
struct mg_str name = trimq(mg_json_get_tok(*req, "$.params"));
struct mg_field *f = mg_dash_find_field(fields, name);
size_t i, n = 0;
@@ -124,15 +123,12 @@ static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
const char *comma = "";
n += mg_xprintf(fn, arg, "{");
for (i = 0; fields[i].name != NULL; i++) {
f = &fields[i];
if (get) get(f);
n += mg_xprintf(fn, arg, "%s", comma);
n += mg_xprintf(fn, arg, "%M", mg_print_field, f);
n += mg_xprintf(fn, arg, "%M", mg_print_field, &fields[i]);
comma = ",";
}
n += mg_xprintf(fn, arg, "}");
} else if (f != NULL) {
if (get) get(f);
n += mg_xprintf(fn, arg, "{%M}", mg_print_field, f);
} else {
n += mg_xprintf(fn, arg, "null");
@@ -140,58 +136,43 @@ static inline size_t mg_dash_print(mg_pfn_t fn, void *arg, va_list *ap) {
return n;
}
static inline bool mg_dash_sync(struct mg_mgr *mgr, struct mg_field *f,
mg_dash_get_fn get) {
union mg_val old_value = f->value;
bool changed = false;
if (get) get(f);
// Strings require special comparison
if (f->type == MG_VAL_STR && mg_strcmp(old_value.s, f->value.s) != 0) {
changed = true;
} else if (memcmp(&f->value, &old_value, sizeof(old_value)) != 0) {
changed = true;
}
if (changed && f != NULL) {
static inline void mg_dash_send_change(struct mg_mgr *mgr, struct mg_field *f) {
if (f != NULL) {
mg_dash_broadcast(mgr, "{%m:%m,%m:{%M}}", MG_ESC("method"),
MG_ESC("change"), MG_ESC("params"), mg_print_field, f);
}
return changed;
}
static inline bool mg_dash_apply(struct mg_connection *c, struct mg_str json,
struct mg_field *fields, mg_dash_get_fn get,
mg_dash_set_fn set) {
static inline void mg_dash_apply(struct mg_connection *c, struct mg_str json,
struct mg_field *fields) {
struct mg_str key, val;
size_t ofs = 0;
struct mg_field *f = NULL;
bool changed = false;
while ((ofs = mg_json_next(json, ofs, &key, &val)) > 0) {
key = trimq(key);
if ((f = mg_dash_find_field(fields, key)) != NULL) {
struct mg_field tmp = *f;
mg_parse_field(val, &tmp);
if (set) set(&tmp);
if (mg_dash_sync(c->mgr, f, get)) changed = true;
if ((f = mg_dash_find_field(fields, key)) != NULL && f->set != NULL) {
union mg_val v = {0};
mg_parse_field(val, f, &v);
f->set(&v);
mg_dash_send_change(c->mgr, f);
break;
} else {
MG_ERROR(("UNKNOWN FIELD: [%.*s]", key.len, key.buf));
}
}
return changed;
}
static inline void mg_dash_process_msg(struct mg_connection *c,
struct mg_ws_message *wm,
struct mg_field *fields,
mg_dash_get_fn get, mg_dash_set_fn set) {
struct mg_field *fields) {
struct mg_str req = wm->data;
struct mg_str method = trimq(mg_json_get_tok(req, "$.method"));
if (mg_match(method, mg_str("get"), NULL)) {
mg_dash_success(c, req, "%M", mg_dash_print, &req, fields, get);
mg_dash_success(c, req, "%M", mg_dash_print, &req, fields);
} else if (mg_match(method, mg_str("set"), NULL)) {
struct mg_str params = trimq(mg_json_get_tok(req, "$.params"));
bool changed = mg_dash_apply(c, params, fields, get, set);
mg_dash_success(c, req, "%s", changed ? "true" : "false");
mg_dash_apply(c, params, fields);
mg_dash_success(c, req, "%s", "true");
} else {
mg_dash_error(c, req, "%s", "unknown method");
}
@@ -212,12 +193,12 @@ static inline void mg_dash_ev_handler(struct mg_connection *c, int ev,
}
} else if (ev == MG_EV_WS_MSG) {
// Add this to automatically handle "get" and "set" JSON-RPC calls
struct mg_dash *dash = (struct mg_dash *) c->fn_data;
struct mg_field *fields = (struct mg_field *) c->fn_data;
struct mg_ws_message *wm = (struct mg_ws_message *) ev_data;
if (dash == NULL || dash->fields == NULL) {
if (fields == NULL) {
mg_dash_error(c, wm->data, "%s", "no fields defined");
} else {
mg_dash_process_msg(c, wm, dash->fields, dash->get, dash->set);
mg_dash_process_msg(c, wm, fields);
}
}
}