From 74f1bde37dd4363e3fe3251b2a3567b3666d3a14 Mon Sep 17 00:00:00 2001 From: Matthias Vogelgesang Date: Tue, 10 Oct 2017 17:03:52 +0200 Subject: Improve custom enum handling --- uca-net-camera.c | 24 ++++++++++++++++++++++++ uca-net-protocol.h | 9 +++++++++ ucad.c | 20 ++++++++++++++++++++ 3 files changed, 53 insertions(+) diff --git a/uca-net-camera.c b/uca-net-camera.c index b108c32..4d05863 100644 --- a/uca-net-camera.c +++ b/uca-net-camera.c @@ -479,6 +479,30 @@ deserialize_param_spec (UcaNetMessageProperty *prop) return g_param_spec_string (prop->name, prop->nick, prop->blurb, prop->spec.gstring.default_value, prop->flags); + case G_TYPE_ENUM: + { + /* Register a new enum type */ + GType type; + GEnumValue *values; + + /* Allocate one more value to mark the end of the array */ + values = g_new0 (GEnumValue, prop->spec.genum.n_values + 1); + + for (guint i = 0; i < prop->spec.genum.n_values; i++) { + gchar *name; + + name = g_strdup_printf ("%s_%i", prop->name, i); + + values[i].value = prop->spec.genum.values[i]; + values[i].value_name = name; + values[i].value_nick = name; + } + + type = g_enum_register_static (prop->name, values); + + return g_param_spec_enum (prop->name, prop->nick, prop->blurb, type, + prop->spec.genum.default_value, prop->flags); + } CASE_NUMERIC (G_TYPE_INT, int) CASE_NUMERIC (G_TYPE_UINT, uint) CASE_NUMERIC (G_TYPE_FLOAT, float) diff --git a/uca-net-protocol.h b/uca-net-protocol.h index 4a1b5b6..1460cbd 100644 --- a/uca-net-protocol.h +++ b/uca-net-protocol.h @@ -3,6 +3,8 @@ #include +#define UCA_NET_MAX_ENUM_LENGTH 128 + typedef enum { UCA_NET_MESSAGE_INVALID = 0, UCA_NET_MESSAGE_GET_PROPERTIES, @@ -86,6 +88,13 @@ typedef struct { struct { gchar default_value[128]; } gstring; + struct { + gint default_value; + gint minimum; + gint maximum; + guint n_values; + gint values[UCA_NET_MAX_ENUM_LENGTH]; + } genum; NUMERIC_STRUCT (gint) NUMERIC_STRUCT (guint) NUMERIC_STRUCT (gfloat) diff --git a/ucad.c b/ucad.c index f5817b9..28fbc16 100644 --- a/ucad.c +++ b/ucad.c @@ -114,6 +114,26 @@ serialize_param_spec (GParamSpec *pspec, UcaNetMessageProperty *prop) prop->value_type = pspec->value_type; prop->flags = pspec->flags; + if (g_type_is_a (pspec->value_type, G_TYPE_ENUM)) { + GEnumClass *enum_class; + + enum_class = ((GParamSpecEnum *) pspec)->enum_class; + prop->value_type = G_TYPE_ENUM; + prop->spec.genum.default_value = ((GParamSpecEnum *) pspec)->default_value; + prop->spec.genum.minimum = enum_class->minimum; + prop->spec.genum.maximum = enum_class->maximum; + prop->spec.genum.n_values = enum_class->n_values; + + if (enum_class->n_values > UCA_NET_MAX_ENUM_LENGTH) + g_warning ("Cannot serialize all values of %s", prop->name); + + /* We do not transfer the enum value names (yet) ... */ + for (guint i = 0; i < MIN (enum_class->n_values, UCA_NET_MAX_ENUM_LENGTH); i++) + prop->spec.genum.values[i] = enum_class->values[i].value; + + return TRUE; + } + #define CASE_NUMERIC(type, storage, typeclass) \ case type: \ prop->spec.storage.minimum = ((typeclass *) pspec)->minimum; \ -- cgit v1.2.3