📄 gparamspecs.c
字号:
{ GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_FLAGS)); if (fspec->flags_class) { g_type_class_unref (fspec->flags_class); fspec->flags_class = NULL; } parent_class->finalize (pspec);}static voidparam_flags_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_ulong = G_PARAM_SPEC_FLAGS (pspec)->default_value;}static gbooleanparam_flags_validate (GParamSpec *pspec, GValue *value){ GParamSpecFlags *fspec = G_PARAM_SPEC_FLAGS (pspec); gulong oval = value->data[0].v_ulong; if (fspec->flags_class) value->data[0].v_ulong &= fspec->flags_class->mask; else value->data[0].v_ulong = fspec->default_value; return value->data[0].v_ulong != oval;}static voidparam_float_init (GParamSpec *pspec){ GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); fspec->minimum = G_MINFLOAT; fspec->maximum = G_MAXFLOAT; fspec->default_value = 0; fspec->epsilon = G_FLOAT_EPSILON;}static voidparam_float_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_float = G_PARAM_SPEC_FLOAT (pspec)->default_value;}static gbooleanparam_float_validate (GParamSpec *pspec, GValue *value){ GParamSpecFloat *fspec = G_PARAM_SPEC_FLOAT (pspec); gfloat oval = value->data[0].v_float; value->data[0].v_float = CLAMP (value->data[0].v_float, fspec->minimum, fspec->maximum); return value->data[0].v_float != oval;}static gintparam_float_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ gfloat epsilon = G_PARAM_SPEC_FLOAT (pspec)->epsilon; if (value1->data[0].v_float < value2->data[0].v_float) return - (value2->data[0].v_float - value1->data[0].v_float > epsilon); else return value1->data[0].v_float - value2->data[0].v_float > epsilon;}static voidparam_double_init (GParamSpec *pspec){ GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); dspec->minimum = G_MINDOUBLE; dspec->maximum = G_MAXDOUBLE; dspec->default_value = 0; dspec->epsilon = G_DOUBLE_EPSILON;}static voidparam_double_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_double = G_PARAM_SPEC_DOUBLE (pspec)->default_value;}static gbooleanparam_double_validate (GParamSpec *pspec, GValue *value){ GParamSpecDouble *dspec = G_PARAM_SPEC_DOUBLE (pspec); gdouble oval = value->data[0].v_double; value->data[0].v_double = CLAMP (value->data[0].v_double, dspec->minimum, dspec->maximum); return value->data[0].v_double != oval;}static gintparam_double_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ gdouble epsilon = G_PARAM_SPEC_DOUBLE (pspec)->epsilon; if (value1->data[0].v_double < value2->data[0].v_double) return - (value2->data[0].v_double - value1->data[0].v_double > epsilon); else return value1->data[0].v_double - value2->data[0].v_double > epsilon;}static voidparam_string_init (GParamSpec *pspec){ GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); sspec->default_value = NULL; sspec->cset_first = NULL; sspec->cset_nth = NULL; sspec->substitutor = '_'; sspec->null_fold_if_empty = FALSE; sspec->ensure_non_null = FALSE;}static voidparam_string_finalize (GParamSpec *pspec){ GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_STRING)); g_free (sspec->default_value); g_free (sspec->cset_first); g_free (sspec->cset_nth); sspec->default_value = NULL; sspec->cset_first = NULL; sspec->cset_nth = NULL; parent_class->finalize (pspec);}static voidparam_string_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_pointer = g_strdup (G_PARAM_SPEC_STRING (pspec)->default_value);}static gbooleanparam_string_validate (GParamSpec *pspec, GValue *value){ GParamSpecString *sspec = G_PARAM_SPEC_STRING (pspec); gchar *string = value->data[0].v_pointer; guint changed = 0; if (string && string[0]) { gchar *s; if (sspec->cset_first && !strchr (sspec->cset_first, string[0])) { string[0] = sspec->substitutor; changed++; } if (sspec->cset_nth) for (s = string + 1; *s; s++) if (!strchr (sspec->cset_nth, *s)) { *s = sspec->substitutor; changed++; } } if (sspec->null_fold_if_empty && string && string[0] == 0) { g_free (value->data[0].v_pointer); value->data[0].v_pointer = NULL; changed++; string = value->data[0].v_pointer; } if (sspec->ensure_non_null && !string) { value->data[0].v_pointer = g_strdup (""); changed++; string = value->data[0].v_pointer; } return changed;}static gintparam_string_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ if (!value1->data[0].v_pointer) return value2->data[0].v_pointer != NULL ? -1 : 0; else if (!value2->data[0].v_pointer) return value1->data[0].v_pointer != NULL; else return strcmp (value1->data[0].v_pointer, value2->data[0].v_pointer);}static voidparam_param_init (GParamSpec *pspec){ /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */}static voidparam_param_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_pointer = NULL;}static gbooleanparam_param_validate (GParamSpec *pspec, GValue *value){ /* GParamSpecParam *spec = G_PARAM_SPEC_PARAM (pspec); */ GParamSpec *param = value->data[0].v_pointer; guint changed = 0; if (param && !g_value_type_compatible (G_PARAM_SPEC_TYPE (param), G_PARAM_SPEC_VALUE_TYPE (pspec))) { g_param_spec_unref (param); value->data[0].v_pointer = NULL; changed++; } return changed;}static voidparam_boxed_init (GParamSpec *pspec){ /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */}static voidparam_boxed_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_pointer = NULL;}static gbooleanparam_boxed_validate (GParamSpec *pspec, GValue *value){ /* GParamSpecBoxed *bspec = G_PARAM_SPEC_BOXED (pspec); */ guint changed = 0; /* can't do a whole lot here since we haven't even G_BOXED_TYPE() */ return changed;}static gintparam_boxed_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ guint8 *p1 = value1->data[0].v_pointer; guint8 *p2 = value2->data[0].v_pointer; /* not much to compare here, try to at least provide stable lesser/greater result */ return p1 < p2 ? -1 : p1 > p2;}static voidparam_pointer_init (GParamSpec *pspec){ /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */}static voidparam_pointer_set_default (GParamSpec *pspec, GValue *value){ value->data[0].v_pointer = NULL;}static gbooleanparam_pointer_validate (GParamSpec *pspec, GValue *value){ /* GParamSpecPointer *spec = G_PARAM_SPEC_POINTER (pspec); */ guint changed = 0; return changed;}static gintparam_pointer_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ guint8 *p1 = value1->data[0].v_pointer; guint8 *p2 = value2->data[0].v_pointer; /* not much to compare here, try to at least provide stable lesser/greater result */ return p1 < p2 ? -1 : p1 > p2;}static voidparam_value_array_init (GParamSpec *pspec){ GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); aspec->element_spec = NULL; aspec->fixed_n_elements = 0; /* disable */}static inline guintvalue_array_ensure_size (GValueArray *value_array, guint fixed_n_elements){ guint changed = 0; if (fixed_n_elements) { while (value_array->n_values < fixed_n_elements) { g_value_array_append (value_array, NULL); changed++; } while (value_array->n_values > fixed_n_elements) { g_value_array_remove (value_array, value_array->n_values - 1); changed++; } } return changed;}static voidparam_value_array_finalize (GParamSpec *pspec){ GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); GParamSpecClass *parent_class = g_type_class_peek (g_type_parent (G_TYPE_PARAM_VALUE_ARRAY)); if (aspec->element_spec) { g_param_spec_unref (aspec->element_spec); aspec->element_spec = NULL; } parent_class->finalize (pspec);}static voidparam_value_array_set_default (GParamSpec *pspec, GValue *value){ GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); if (!value->data[0].v_pointer && aspec->fixed_n_elements) value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements); if (value->data[0].v_pointer) { /* g_value_reset (value); already done */ value_array_ensure_size (value->data[0].v_pointer, aspec->fixed_n_elements); }}static gbooleanparam_value_array_validate (GParamSpec *pspec, GValue *value){ GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); GValueArray *value_array = value->data[0].v_pointer; guint changed = 0; if (!value->data[0].v_pointer && aspec->fixed_n_elements) value->data[0].v_pointer = g_value_array_new (aspec->fixed_n_elements); if (value->data[0].v_pointer) { /* ensure array size validity */ changed += value_array_ensure_size (value_array, aspec->fixed_n_elements); /* ensure array values validity against a present element spec */ if (aspec->element_spec) { GParamSpec *element_spec = aspec->element_spec; guint i; for (i = 0; i < value_array->n_values; i++) { GValue *element = value_array->values + i; /* need to fixup value type, or ensure that the array value is initialized at all */ if (!g_value_type_compatible (G_VALUE_TYPE (element), G_PARAM_SPEC_VALUE_TYPE (element_spec))) { if (G_VALUE_TYPE (element) != 0) g_value_unset (element); g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec)); g_param_value_set_default (element_spec, element); changed++; } /* validate array value against element_spec */ changed += g_param_value_validate (element_spec, element); } } } return changed;}static gintparam_value_array_values_cmp (GParamSpec *pspec, const GValue *value1, const GValue *value2){ GParamSpecValueArray *aspec = G_PARAM_SPEC_VALUE_ARRAY (pspec); GValueArray *value_array1 = value1->data[0].v_pointer; GValueArray *value_array2 = value2->data[0].v_pointer; if (!value_array1 || !value_array2) return value_array2 ? -1 : value_array1 != value_array2; if (value_array1->n_values != value_array2->n_values) return value_array1->n_values < value_array2->n_values ? -1 : 1; else if (!aspec->element_spec) { /* we need an element specification for comparisons, so there's not much * to compare here, try to at least provide stable lesser/greater result */ return value_array1->n_values < value_array2->n_values ? -1 : value_array1->n_values > value_array2->n_values; } else /* value_array1->n_values == value_array2->n_values */ { guint i; for (i = 0; i < value_array1->n_values; i++) { GValue *element1 = value_array1->values + i; GValue *element2 = value_array2->values + i; gint cmp; /* need corresponding element types, provide stable result otherwise */ if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2)) return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1; cmp = g_param_values_cmp (aspec->element_spec, element1, element2); if (cmp)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -