|
View:
New views
16 Messages
—
Rating Filter:
Alert me
|
|
|
GParamSpec further funcsI was having a nose around some of the Glib::ParamSpec bits and wondered
if g_param_value_set_default() could do the work for $paramspec->get_default_value. Or is there some magic in the current dispatch? I tried the couple of lines below which seem to work, though bools may come out different from gperl_sv_from_value(). I also wondered if there'd be some value in g_param_value_validate and/or g_param_values_cmp. I was tinkering with some comparing for my "ConnectProperties". g_param_values_cmp looks like it respects the "epsilon" in float and double, though it also looks pretty useless on boxed types (just a pointer compare). --- GParamSpec.xs 18 Oct 2005 05:26:09 +1000 1.23 +++ GParamSpec.xs 16 Jun 2008 10:27:37 +1000 @@ -288,6 +288,73 @@ const gchar* g_param_spec_get_blurb (GParamSpec * pspec) +MODULE = Glib::ParamSpec PACKAGE = Glib::ParamSpec PREFIX = g_param_ + +SV * +g_param_xxx_get_default_value (GParamSpec * pspec) + PREINIT: + GValue v = { 0, }; + GType type; + CODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v, type); + g_param_value_set_default (pspec, &v); + RETVAL = gperl_sv_from_value (&v); + g_value_unset (&v); + OUTPUT: + RETVAL + +=for apidoc + +=signature bool = $paramspec->value_validate (value) + +=signature (bool, newval) = $paramspec->value_validate (value) + +In scalar context return a boolean indicating whether $value is valid +for $paramspec. In array context return also a new value which is +$value modified to be valid, which means for instance clamped to the +minimum/maximum, etc. + +=cut +void +g_param_value_validate (GParamSpec * pspec, SV *value) + PREINIT: + GValue v = { 0, }; + GType type; + int ret; + PPCODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v, type); + gperl_value_from_sv (&v, value); + ret = g_param_value_validate (pspec, &v); + EXTEND (SP, 2); + PUSHs (sv_2mortal (boolSV (ret))); + if (GIMME_V == G_ARRAY) + PUSHs (sv_2mortal (gperl_sv_from_value (&v))); + g_value_unset (&v); + +int +g_param_values_cmp (GParamSpec * pspec, SV *value1, SV *value2) + PREINIT: + GValue v1 = { 0, }; + GValue v2 = { 0, }; + GType type; + CODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v1, type); + g_value_init (&v2, type); + gperl_value_from_sv (&v1, value1); + gperl_value_from_sv (&v2, value2); + RETVAL = g_param_values_cmp (pspec, &v1, &v2); + g_value_unset (&v1); + g_value_unset (&v2); + OUTPUT: + RETVAL + +## gboolean g_value_type_compatible (GType src_type, GType dest_type); +## gboolean g_value_type_transformable (GType src_type, GType dest_type); + +MODULE = Glib::ParamSpec PACKAGE = Glib::ParamSpec PREFIX = g_param_spec_ ## stuff from gparamspecs.h _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsKevin Ryde wrote:
> I was having a nose around some of the Glib::ParamSpec bits and wondered > if g_param_value_set_default() could do the work for > $paramspec->get_default_value. Or is there some magic in the current > dispatch? I tried the couple of lines below which seem to work, though > bools may come out different from gperl_sv_from_value(). So what you're suggesting is that we implement a generic Glib::ParamSpec->get_default_value by using g_param_value_set_default. Good idea! Currently, every subclass of Glib::ParamSpec implements its own get_default_value. > +MODULE = Glib::ParamSpec PACKAGE = Glib::ParamSpec PREFIX = g_param_ > + > +SV * > +g_param_xxx_get_default_value (GParamSpec * pspec) > + [...] It won't work like this though, I think. The XSUB would need to be called simply g_param_spec_get_default_value and would need to reside in a MODULE section with "PREFIX = g_param_spec_". Then you'd have to remove all the get_default_value XSUBs from the various subclasses. Since the subclasses inherit from Glib::ParamSpec, calling get_default_value on them would now invoke your generic one. If the test suite still passes after these changes, we have a winner. > I also wondered if there'd be some value in g_param_value_validate > and/or g_param_values_cmp. I was tinkering with some comparing for my > "ConnectProperties". g_param_values_cmp looks like it respects the > "epsilon" in float and double, though it also looks pretty useless on > boxed types (just a pointer compare). Yeah, I think they would be useful. Could you provide a patch with some tests? Also, your patch mixes spaces and tabs for indention. Our convention is to use four spaces for indenting the XS codewords (PREINIT, CODE, etc.) and tabs for indenting code. -- Bye, -Torsten _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsTorsten Schoenfeld <kaffeetisch@...> writes:
> > So what you're suggesting is that we implement a generic > Glib::ParamSpec->get_default_value by using g_param_value_set_default. Yep. > It won't work like this though, I think. The XSUB would need to be > called simply g_param_spec_get_default_value and would need to reside in > a MODULE section with "PREFIX = g_param_spec_". Ah yes. I was playing with the other couple that are only g_param_foo instead of g_param_spec_foo. > Then you'd have to > remove all the get_default_value XSUBs from the various subclasses. Though I see the gunichar one stays, to continue to return a string. > If the test suite still passes after these changes, we have a winner. Plus a couple more tests for object, boxed, etc which now get the generic method. The "param" one tickles the NULL problem too, per other message. > Also, your patch mixes spaces and tabs for indention. Ah, that'll be a combination of cut and paste and me having `indent-tabs' off normally. I've yet to find an emacs setup that works decently for xs. I tend to use cc-mode with some settings, and then get annoyed when it indents wrong, and then switch to text-mode or pod-mode for the doc bits :-( * GParamSpec.xs (get_default_value): Use g_param_value_set_default instead of explicit code, except keep Glib::Param::Unichar. * t/e.t: Exercise get_default_value on Object, Boxed, Param, Scalar, IV and UV, as they now get that func. Note Glib::Param::Boolean::get_default_value previously returned the empty string '' for false, but now ends up 0 from the generic gperl_sv_from_value. This may be a good thing since 0 is what $obj->get() itself returns for a false bool property. --- GParamSpec.xs 18 Oct 2005 05:26:09 +1000 1.23 +++ GParamSpec.xs 23 Jun 2008 19:12:06 +1000 @@ -288,6 +288,26 @@ const gchar* g_param_spec_get_blurb (GParamSpec * pspec) +=for apidoc +This is the C level C<value_set_default> method of GParamSpecClass. +If C<$pspec> doesn't have a C<default_value> field the return is +C<undef> (for example object or scalar). + +See also L<Glib::Param::Unichar> which has its own version of this method. +=cut +SV * +g_param_spec_get_default_value (GParamSpec * pspec) + PREINIT: + GValue v = { 0, }; + GType type; + CODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v, type); + g_param_value_set_default (pspec, &v); + RETVAL = gperl_sv_from_value (&v); + g_value_unset (&v); + OUTPUT: + RETVAL ## stuff from gparamspecs.h @@ -686,27 +706,6 @@ RETVAL -=for apidoc Glib::Param::Char::get_default_value __hide__ -=cut - -=for apidoc Glib::Param::Long::get_default_value __hide__ -=cut - -IV -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::Int::get_default_value = 1 - Glib::Param::Long::get_default_value = 2 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_CHAR (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_INT (pspec)->default_value; break; - case 2: RETVAL = G_PARAM_SPEC_LONG (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0; - } - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::UChar ## similarly, all unsigned integer types @@ -772,27 +771,6 @@ RETVAL -=for apidoc Glib::Param::UChar::get_default_value __hide__ -=cut - -=for apidoc Glib::Param::ULong::get_default_value __hide__ -=cut - -UV -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::UInt::get_default_value = 1 - Glib::Param::ULong::get_default_value = 2 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_UCHAR (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_UINT (pspec)->default_value; break; - case 2: RETVAL = G_PARAM_SPEC_ULONG (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0; - } - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Int64 =for object Glib::Param::Int64 @@ -820,13 +798,6 @@ OUTPUT: RETVAL -gint64 -get_default_value (GParamSpec * pspec) - CODE: - RETVAL = G_PARAM_SPEC_INT64 (pspec)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::UInt64 =for object Glib::Param::UInt64 @@ -854,13 +825,6 @@ OUTPUT: RETVAL -guint64 -get_default_value (GParamSpec * pspec) - CODE: - RETVAL = G_PARAM_SPEC_UINT64 (pspec)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Float ## and again for the floating-point types @@ -915,23 +879,6 @@ RETVAL -=for apidoc Glib::Param::Float::get_default_value __hide__ -=cut - -double -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::Double::get_default_value = 1 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_FLOAT (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_DOUBLE (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0.0; - } - OUTPUT: - RETVAL - - =for apidoc Glib::Param::Float::get_epsilon __hide__ =cut @@ -953,13 +900,6 @@ =for see_also Glib::ParamSpec =cut -gboolean -get_default_value (GParamSpec * pspec_boolean) - CODE: - RETVAL = G_PARAM_SPEC_BOOLEAN (pspec_boolean)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Enum =for see_also Glib::ParamSpec @@ -974,17 +914,6 @@ OUTPUT: RETVAL -SV * -get_default_value (GParamSpec * pspec_enum) - PREINIT: - GParamSpecEnum * penum; - CODE: - penum = G_PARAM_SPEC_ENUM (pspec_enum); - RETVAL = gperl_convert_back_enum (G_ENUM_CLASS_TYPE (penum->enum_class), - penum->default_value); - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Flags =for see_also Glib::ParamSpec @@ -999,30 +928,11 @@ OUTPUT: RETVAL -SV * -get_default_value (GParamSpec * pspec_flags) - PREINIT: - GParamSpecFlags * pflags; - CODE: - pflags = G_PARAM_SPEC_FLAGS (pspec_flags); - RETVAL = gperl_convert_back_flags - (G_FLAGS_CLASS_TYPE (pflags->flags_class), - pflags->default_value); - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::String =for see_also Glib::ParamSpec =cut -gchar * -get_default_value (GParamSpec * pspec_string) - CODE: - RETVAL = G_PARAM_SPEC_STRING (pspec_string)->default_value; - OUTPUT: - RETVAL - ## the others are fairly uninteresting. ## string cset_first ## string cset_nth @@ -1035,6 +945,14 @@ =for see_also Glib::ParamSpec =cut +# this overrides the base get_default_value() in Glib::ParamSpec above +# because a GParamSpecUnichar is only type G_TYPE_UINT and so comes +# back from gperl_sv_from_value() as an integer, where we prefer a +# string (a single-char Perl wide-char string) +# +=for apidoc +Return the default value as a single-character string. +=cut gunichar get_default_value (GParamSpec * pspec_unichar) CODE: --- e.t 02 Jun 2008 09:56:28 +1000 1.2 +++ e.t 23 Jun 2008 16:50:32 +1000 @@ -3,7 +3,7 @@ # use strict; use Glib ':constants'; -use Test::More tests => 231; +use Test::More tests => 237; # first register some types with which to play below. @@ -132,6 +132,7 @@ # we only know one boxed type at this point. 'Glib::Scalar', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Boxed', G_PARAM_READWRITE, 'Glib::Scalar'); +is ($pspec->get_default_value, undef, 'Boxed default'); push @params, $pspec; @@ -139,6 +140,7 @@ 'I object, Your Honor, that\'s pure conjecture!', 'Skeezle', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Object', G_PARAM_READWRITE, 'Skeezle'); +is ($pspec->get_default_value, undef, 'Object default'); push @params, $pspec; @@ -154,6 +156,7 @@ ok ($pspec->get_flags == G_PARAM_READWRITE, 'Param flags'); is ($pspec->get_value_type, 'Glib::Param::Enum', 'Param value type'); ok (! $pspec->get_owner_type, 'Param owner type'); +is ($pspec->get_default_value, undef, 'Param default'); push @params, $pspec; @@ -171,6 +174,7 @@ $pspec = Glib::ParamSpec->IV ('iv', 'IV', 'This is the same as Int', -20, 10, -5, G_PARAM_READWRITE); +is ($pspec->get_default_value, -5, 'IV default'); isa_ok ($pspec, 'Glib::Param::Long', 'IV is actually Long'); push @params, $pspec; @@ -179,6 +183,7 @@ 'This is the same as UInt', 10, 20, 15, G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::ULong', 'UV is actually ULong'); +is ($pspec->get_default_value, 15, 'UV default'); push @params, $pspec; @@ -187,6 +192,7 @@ G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::Boxed', 'Scalar is actually Boxed'); is ($pspec->get_value_type, 'Glib::Scalar', 'boxed holding scalar'); +is ($pspec->get_default_value, undef, 'Scalar default'); push @params, $pspec; -- The sigfile one-line movie reviews series: "Razorback" -- easily the best homicidal wild pig movie ever made. _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsKevin Ryde wrote:
>> If the test suite still passes after these changes, we have a winner. > > Plus a couple more tests for object, boxed, etc which now get the > generic method. The "param" one tickles the NULL problem too, per other > message. Thanks for the patch. Some points: +=for apidoc +This is the C level C<value_set_default> method of GParamSpecClass. +If C<$pspec> doesn't have a C<default_value> field the return is +C<undef> (for example object or scalar). + +See also L<Glib::Param::Unichar> which has its own version of this method. +=cut I'm not sure the first sentence is useful to a Perl programmer. Also, with the custom get_default_value xsubs gone from the subclasses, there will be no entry for it in their POD pages anymore. It might be good to rectify this with a POD paragraph in every subclass: =for apidoc get_default_value =for signature value = $pspec->get_default_value =cut -gboolean -get_default_value (GParamSpec * pspec_boolean) - CODE: - RETVAL = G_PARAM_SPEC_BOOLEAN (pspec_boolean)->default_value; - OUTPUT: - RETVAL As you note in your ChangeLog entry (thanks for writing it!), this change is not quite backwards compatible. gperl_sv_from_value is really not handling booleans correctly: it's treating them as integers with newSViv whereas it should use boolSV, in my opinion. boolSV is what the gboolean typemap ends up using. But it's too late to change gperl_sv_from_value. So I think the old get_default_value for booleans should stay, for backwards compatibility and because it's actually more correct. muppet? >> Also, your patch mixes spaces and tabs for indention. > > Ah, that'll be a combination of cut and paste and me having > `indent-tabs' off normally. I've yet to find an emacs setup that works > decently for xs. I tend to use cc-mode with some settings, and then get > annoyed when it indents wrong, and then switch to text-mode or pod-mode > for the doc bits :-( I have the same problems. Newer emacsen automatically use ld-script-mode for *.xs files which is not that bad for indention but which lacks syntax highlighting completely. There's an xs-mode.el on the emacs wiki[1], but I haven't really tried it yet. [1] <http://www.emacswiki.org/cgi-bin/emacs/xs-mode.el> linked to by <http://www.emacswiki.org/cgi-bin/wiki/PerlLanguage>. -- Bye, -Torsten _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsOn Jul 13, 2008, at 12:04 PM, Torsten Schoenfeld wrote: > As you note in your ChangeLog entry (thanks for writing it!), this > change is > not quite backwards compatible. gperl_sv_from_value is really not > handling > booleans correctly: it's treating them as integers with newSViv > whereas it > should use boolSV, in my opinion. boolSV is what the gboolean > typemap ends up > using. But it's too late to change gperl_sv_from_value. > > So I think the old get_default_value for booleans should stay, for > backwards > compatibility and because it's actually more correct. > > muppet? The old setup works by duck typing from the perl level. By using g_param_set_default_value() to access the default value, you're using the polymorphic function pointers down in C code. What would be broken by changing newSViv(boolval) to boolSV(boolval) ? if ($obj->get ('boolparm') == '') { # false is empty string! Quite frankly, i see this as about as useful as doing bool foo = some_thing (); bool bar = some_other_thing (); if (foo == true && bar == true) { in C to get "better readability" ... it's not actually more readable -- it's non-idiomatic, and creates more code, and makes you susceptible to breakage if some_thing() starts returning more than just 0 and 1. But, somebody probably has that code out there, because not everyone has learned by hard knocks that such coding styles are bad. What can we do? Use magical blessed Bool objects with overloaded operators? While it might be a fun hack, that's heavy overengineering. So, changing gperl_sv_from_value() to use boolSV() is likely a compatibility break and therefore a non-starter. By changing most of the stuff to use g_param_spec_set_default() for most but explicit get_default_value()s for the rest, we have a rather strange mix of duck typing and polymorphism. This is a rarely-used back corner of the API, but still not worth creating something with so many oddities. I'd say, then, that adding value_validate() and set_default() is a fine idea. Since we try to hide GValue from the perl API, replacing it with normal scalars, g_param_values_cmp() should be left out in favor of gperl_sv_from_value() and the normal perl-level operators. And, don't change the get_default_value() mess to retain compatibility. Hey, take heart -- gtk+ 3.0 is now not that far away (next year!), and we'll get a chance to clean up all this sort of mess with a new Gtk3 namespace. Just make sure we write down all these things so they don't get lost. http://blogs.gnome.org/lucasr/2008/07/10/gnome-30/ http://people.imendio.com/kris/gtk-state-of-the-union-2008.pdf >> Ah, that'll be a combination of cut and paste and me having >> `indent-tabs' off normally. I've yet to find an emacs setup that >> works >> decently for xs. I tend to use cc-mode with some settings, and >> then get >> annoyed when it indents wrong, and then switch to text-mode or pod- >> mode >> for the doc bits :-( > > I have the same problems. Newer emacsen automatically use ld-script- > mode for > *.xs files which is not that bad for indention but which lacks syntax > highlighting completely. There's an xs-mode.el on the emacs > wiki[1], but I > haven't really tried it yet. I'd like to introduce you poor fellows to my good friend vim... he doesn't have these problems. :-) -- Zella, carrying a kite in a long plastic box: It's like book! Yvonne, carrying the wooden kite string spool: It's like a wood! _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsmuppet <scott@...> writes:
> > Since we try to hide GValue from the perl API, replacing > it with normal scalars, g_param_values_cmp() should be left out in > favor of gperl_sv_from_value() and the normal perl-level operators. Actually, values_cmp() was the one I most wanted. The point of it is a compare has to pay attention to the paramspec type, otherwise you don't know whether "eq", "==" or bool is the right thing. It also does stuff like following the "epsilon" for the floats and doubles, and chops down from double to float for the compare. At any rate being one of those polymorphic things it's got a chance of doing something decent on paramspec flavours not even thought of yet ... _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsTorsten Schoenfeld <kaffeetisch@...> writes:
> > +This is the C level C<value_set_default> method of GParamSpecClass. > +If C<$pspec> doesn't have a C<default_value> field the return is > +C<undef> (for example object or scalar). > + > +See also L<Glib::Param::Unichar> which has its own version of this method. > +=cut > > I'm not sure the first sentence is useful to a Perl programmer. Yep, though it's also one of only a few places the c and perl names aren't the same. Perhaps tone it down to just =for apidoc (This is the C level C<g_param_value_set_default> function.) =cut (Since it's otherwise pretty self-explanatory.) > Also, with > the custom get_default_value xsubs gone from the subclasses, there will be no > entry for it in their POD pages anymore. It might be good to rectify this > with a POD paragraph in every subclass: I guess that's true of all subclasses though. Perhaps just making the class hierarchy clearer would be enough. I didn't realize immediately the funcs like Glib::ParamSpec->double created Glib::Param::Double etc. And the pod for Glib::Param::Double when you get there alas lacks a "HIERARCHY" section to enlighten the ignorant that you can go back to Glib::ParamSpec for other methods. Perhaps separate sections in the Glib::ParamSpec pod for constructors-of-subclasses versus generic methods would help too. (The subtly different Glib::Param::Foo versus Glib::ParamSpec names are a bit off-putting too. I guess for gtk3 there could be a chance to switch to Glib::ParamSpec::Foo. Not that names have to reflect hierarchy of course, but "Param" starts to suggest the value instead of the spec, if you know what I mean.) _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsmuppet <scott@...> writes:
> > What would be broken by changing newSViv(boolval) to boolSV(boolval) ? > > if ($obj->get ('boolparm') == '') { # false is empty string! Yes, improbable as it might seem. Thinking some more ... I guess my best bet for breakage would be something being printed out. It used to print or display 0, now it would be the empty string ... that'd be bad. > By changing most of the stuff to use g_param_spec_set_default() for > most but explicit get_default_value()s for the rest, we have a rather > strange mix of duck typing and polymorphism. I guess the polymorphism is still a good thing. The proposal then would be the poly base func, with exceptions for bool for historical compatibility, and for unichar for usefulness plus compatibility. Is that more trouble than it's worth? > I'd like to introduce you poor fellows to my good friend vim... he > doesn't have these problems. :-) Aaagh, spawn of the evil one! _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsNew attempt below, using the polymorphic g_param_value_set_default() in
all cases, but with the return converted specially as boolSV or newSVpv for bools and unichars. Maybe it'd be better to identify bool and unichar cases with some sort of test of the input pspec's G_PARAM_SPEC_GET_CLASS(), instead of adding "ALIAS"s. --- GParamSpec.xs 18 Oct 2005 05:26:09 +1000 1.23 +++ GParamSpec.xs 15 Jul 2008 09:24:22 +1000 @@ -288,6 +288,48 @@ const gchar* g_param_spec_get_blurb (GParamSpec * pspec) +=for apidoc +(This is the C level C<g_param_value_set_default> function.) +=cut +SV * +g_param_spec_get_default_value (GParamSpec * pspec) + ALIAS: + Glib::Param::Boolean::get_default_value = 1 + Glib::Param::Unichar::get_default_value = 2 + PREINIT: + GValue v = { 0, }; + GType type; + CODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v, type); + g_param_value_set_default (pspec, &v); + switch (ix) { + default: + RETVAL = gperl_sv_from_value (&v); + break; + case 1: + /* For historical compatibility we want boolSV here, the same as + gboolean typemap output. But gperl_sv_from_value() only puts + out newSViv() on a bool, hence a special case. */ + RETVAL = boolSV (g_value_get_boolean (&v)); + break; + case 2: + /* For usefulness and for historical compatibility we return a + single-char string here, the same as gunichar typemap output. + The GValue for a GParamSpecUnichar is only left set to a uint, + there's nothing gperl_sv_from_value() can look at to identify + it as a unichar, hence special code here. */ + { + gchar temp[6]; + gint length = g_unichar_to_utf8 (g_value_get_uint(&v), temp); + RETVAL = newSVpv (temp, length); + SvUTF8_on (RETVAL); + } + break; + } + g_value_unset (&v); + OUTPUT: + RETVAL ## stuff from gparamspecs.h @@ -686,27 +728,6 @@ RETVAL -=for apidoc Glib::Param::Char::get_default_value __hide__ -=cut - -=for apidoc Glib::Param::Long::get_default_value __hide__ -=cut - -IV -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::Int::get_default_value = 1 - Glib::Param::Long::get_default_value = 2 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_CHAR (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_INT (pspec)->default_value; break; - case 2: RETVAL = G_PARAM_SPEC_LONG (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0; - } - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::UChar ## similarly, all unsigned integer types @@ -772,27 +793,6 @@ RETVAL -=for apidoc Glib::Param::UChar::get_default_value __hide__ -=cut - -=for apidoc Glib::Param::ULong::get_default_value __hide__ -=cut - -UV -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::UInt::get_default_value = 1 - Glib::Param::ULong::get_default_value = 2 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_UCHAR (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_UINT (pspec)->default_value; break; - case 2: RETVAL = G_PARAM_SPEC_ULONG (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0; - } - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Int64 =for object Glib::Param::Int64 @@ -820,13 +820,6 @@ OUTPUT: RETVAL -gint64 -get_default_value (GParamSpec * pspec) - CODE: - RETVAL = G_PARAM_SPEC_INT64 (pspec)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::UInt64 =for object Glib::Param::UInt64 @@ -854,13 +847,6 @@ OUTPUT: RETVAL -guint64 -get_default_value (GParamSpec * pspec) - CODE: - RETVAL = G_PARAM_SPEC_UINT64 (pspec)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Float ## and again for the floating-point types @@ -915,23 +901,6 @@ RETVAL -=for apidoc Glib::Param::Float::get_default_value __hide__ -=cut - -double -get_default_value (GParamSpec * pspec) - ALIAS: - Glib::Param::Double::get_default_value = 1 - CODE: - switch (ix) { - case 0: RETVAL = G_PARAM_SPEC_FLOAT (pspec)->default_value; break; - case 1: RETVAL = G_PARAM_SPEC_DOUBLE (pspec)->default_value; break; - default: g_assert_not_reached (); RETVAL = 0.0; - } - OUTPUT: - RETVAL - - =for apidoc Glib::Param::Float::get_epsilon __hide__ =cut @@ -950,16 +919,6 @@ MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Boolean -=for see_also Glib::ParamSpec -=cut - -gboolean -get_default_value (GParamSpec * pspec_boolean) - CODE: - RETVAL = G_PARAM_SPEC_BOOLEAN (pspec_boolean)->default_value; - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Enum =for see_also Glib::ParamSpec @@ -974,17 +933,6 @@ OUTPUT: RETVAL -SV * -get_default_value (GParamSpec * pspec_enum) - PREINIT: - GParamSpecEnum * penum; - CODE: - penum = G_PARAM_SPEC_ENUM (pspec_enum); - RETVAL = gperl_convert_back_enum (G_ENUM_CLASS_TYPE (penum->enum_class), - penum->default_value); - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Flags =for see_also Glib::ParamSpec @@ -999,30 +947,11 @@ OUTPUT: RETVAL -SV * -get_default_value (GParamSpec * pspec_flags) - PREINIT: - GParamSpecFlags * pflags; - CODE: - pflags = G_PARAM_SPEC_FLAGS (pspec_flags); - RETVAL = gperl_convert_back_flags - (G_FLAGS_CLASS_TYPE (pflags->flags_class), - pflags->default_value); - OUTPUT: - RETVAL - MODULE = Glib::ParamSpec PACKAGE = Glib::Param::String =for see_also Glib::ParamSpec =cut -gchar * -get_default_value (GParamSpec * pspec_string) - CODE: - RETVAL = G_PARAM_SPEC_STRING (pspec_string)->default_value; - OUTPUT: - RETVAL - ## the others are fairly uninteresting. ## string cset_first ## string cset_nth @@ -1032,16 +961,6 @@ MODULE = Glib::ParamSpec PACKAGE = Glib::Param::Unichar -=for see_also Glib::ParamSpec -=cut - -gunichar -get_default_value (GParamSpec * pspec_unichar) - CODE: - RETVAL = G_PARAM_SPEC_UNICHAR (pspec_unichar)->default_value; - OUTPUT: - RETVAL - ##MODULE = Glib::ParamSpec PACKAGE = Glib::Param::ValueArray ##element_spec --- e.t 02 Jun 2008 09:56:28 +1000 1.2 +++ e.t 15 Jul 2008 09:44:59 +1000 @@ -3,7 +3,7 @@ # use strict; use Glib ':constants'; -use Test::More tests => 231; +use Test::More tests => 238; # first register some types with which to play below. @@ -58,11 +58,20 @@ 'Is you is, or is you ain\'t my baby', TRUE, 'readable'); pspec_common_ok ($pspec, 'Boolean', 'readable'); -ok ($pspec->get_default_value, "Boolean default (expect TRUE)"); +is ($pspec->get_default_value, 1, "Boolean default (expect TRUE)"); push @params, $pspec; +$pspec = Glib::ParamSpec->boolean ('untrue', 'Untrue', + 'A pernicious falsehood', + FALSE, 'readable'); +# this is PL_sv_no, not a 0, for historical compatibility +is ($pspec->get_default_value, '', "Boolean default (expect TRUE)"); +# not pushed, just checking the default +# push @params, $pspec; + + # # all of the integer types have the same interface. # @@ -132,6 +141,7 @@ # we only know one boxed type at this point. 'Glib::Scalar', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Boxed', G_PARAM_READWRITE, 'Glib::Scalar'); +is ($pspec->get_default_value, undef, 'Boxed default'); push @params, $pspec; @@ -139,6 +149,7 @@ 'I object, Your Honor, that\'s pure conjecture!', 'Skeezle', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Object', G_PARAM_READWRITE, 'Skeezle'); +is ($pspec->get_default_value, undef, 'Object default'); push @params, $pspec; @@ -154,6 +165,7 @@ ok ($pspec->get_flags == G_PARAM_READWRITE, 'Param flags'); is ($pspec->get_value_type, 'Glib::Param::Enum', 'Param value type'); ok (! $pspec->get_owner_type, 'Param owner type'); +is ($pspec->get_default_value, undef, 'Param default'); push @params, $pspec; @@ -171,6 +183,7 @@ $pspec = Glib::ParamSpec->IV ('iv', 'IV', 'This is the same as Int', -20, 10, -5, G_PARAM_READWRITE); +is ($pspec->get_default_value, -5, 'IV default'); isa_ok ($pspec, 'Glib::Param::Long', 'IV is actually Long'); push @params, $pspec; @@ -179,6 +192,7 @@ 'This is the same as UInt', 10, 20, 15, G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::ULong', 'UV is actually ULong'); +is ($pspec->get_default_value, 15, 'UV default'); push @params, $pspec; @@ -187,6 +201,7 @@ G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::Boxed', 'Scalar is actually Boxed'); is ($pspec->get_value_type, 'Glib::Scalar', 'boxed holding scalar'); +is ($pspec->get_default_value, undef, 'Scalar default'); push @params, $pspec; _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsKevin Ryde wrote:
> I also wondered if there'd be some value in g_param_value_validate > and/or g_param_values_cmp. I was tinkering with some comparing for my > "ConnectProperties". g_param_values_cmp looks like it respects the > "epsilon" in float and double, though it also looks pretty useless on > boxed types (just a pointer compare). Here's an updated patch for g_param_value_validate and g_param_values_cmp. I had to change the doc for g_param_value_validate since its boolean return value surprisingly means something else. Commit? -- Bye, -Torsten Index: GParamSpec.xs =================================================================== RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/GParamSpec.xs,v retrieving revision 1.23 diff -u -d -p -r1.23 GParamSpec.xs --- GParamSpec.xs 17 Oct 2005 19:26:09 -0000 1.23 +++ GParamSpec.xs 3 Aug 2008 15:49:05 -0000 @@ -289,8 +289,60 @@ const gchar* g_param_spec_get_nick (GPar const gchar* g_param_spec_get_blurb (GParamSpec * pspec) +MODULE = Glib::ParamSpec PACKAGE = Glib::ParamSpec PREFIX = g_param_ + +=for apidoc + +=signature bool = $paramspec->value_validate (value) + +=signature (bool, newval) = $paramspec->value_validate (value) + +In scalar context return a boolean indicating whether $value is valid for +$paramspec: FALSE if it is valid, and TRUE otherwise. (Note that this is +likely the opposite of what you expect.) In array context return also a new +value which is $value modified to be valid, which means for instance clamped to +the minimum/maximum, etc. + +=cut +void +g_param_value_validate (GParamSpec * pspec, SV *value) + PREINIT: + GValue v = { 0, }; + GType type; + int ret; + PPCODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v, type); + gperl_value_from_sv (&v, value); + ret = g_param_value_validate (pspec, &v); + PUSHs (sv_2mortal (boolSV (ret))); + if (GIMME_V == G_ARRAY) + XPUSHs (sv_2mortal (gperl_sv_from_value (&v))); + g_value_unset (&v); + +int +g_param_values_cmp (GParamSpec * pspec, SV *value1, SV *value2) + PREINIT: + GValue v1 = { 0, }; + GValue v2 = { 0, }; + GType type; + CODE: + type = G_PARAM_SPEC_VALUE_TYPE (pspec); + g_value_init (&v1, type); + g_value_init (&v2, type); + gperl_value_from_sv (&v1, value1); + gperl_value_from_sv (&v2, value2); + RETVAL = g_param_values_cmp (pspec, &v1, &v2); + g_value_unset (&v1); + g_value_unset (&v2); + OUTPUT: + RETVAL + + ## stuff from gparamspecs.h +MODULE = Glib::ParamSpec PACKAGE = Glib::ParamSpec PREFIX = g_param_spec_ + ### ### glib's param specs offer lots of different sizes of integers and floating ### point values, but perl only supports UV (uint), IV (int), and NV (double). Index: t/e.t =================================================================== RCS file: /cvsroot/gtk2-perl/gtk2-perl-xs/Glib/t/e.t,v retrieving revision 1.2 diff -u -d -p -r1.2 e.t --- t/e.t 20 Oct 2004 17:33:56 -0000 1.2 +++ t/e.t 3 Aug 2008 15:49:05 -0000 @@ -1,9 +1,10 @@ +#!/usr/bin/perl # # ParamSpec stuff. # use strict; use Glib ':constants'; -use Test::More tests => 231; +use Test::More tests => 234; # first register some types with which to play below. @@ -204,3 +205,18 @@ Glib::Type->register ( foreach (@params) { is ($_->get_owner_type, 'Bar', ref($_)." owner type after adding"); } + + + +# +# test value_validate and values_cmp +# +{ + my $pspec = Glib::ParamSpec->int ('int', 'Int', 'Int', + 1, 5, 2, + G_PARAM_READWRITE); + is ($pspec->value_validate (3), FALSE); + is_deeply ([$pspec->value_validate (6)], [TRUE, 5]); + + is ($pspec->values_cmp (4, 3), 1); +} _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsTorsten Schoenfeld <kaffeetisch@...> writes:
> > +In scalar context return a boolean indicating whether $value is valid for > +$paramspec: FALSE if it is valid, and TRUE otherwise. (Note that this is > +likely the opposite of what you expect.) Oh, I see, that's annoying, isn't it. Maybe it could be written in a "positive" sense the same as in the gtk reference: so true if it has to be modified. Or true if invalid. (And the second return is a suitably modified value.) I wrote some tests for values_cmp and didn't post them yet (unless I did and I forgot!) using the various test pspecs. Perhaps they exercise gtk more than the interface, though you always want to know if something isn't reaching what it's supposed to do ... --- e.t 02 Jun 2008 09:56:28 +1000 1.2 +++ e.t 23 Jul 2008 17:18:50 +1000 @@ -3,7 +3,7 @@ # use strict; use Glib ':constants'; -use Test::More tests => 231; +use Test::More tests => 238; # first register some types with which to play below. @@ -58,11 +58,25 @@ 'Is you is, or is you ain\'t my baby', TRUE, 'readable'); pspec_common_ok ($pspec, 'Boolean', 'readable'); -ok ($pspec->get_default_value, "Boolean default (expect TRUE)"); +is ($pspec->get_default_value, 1, "Boolean default (expect TRUE)"); +is ($pspec->values_cmp(0,1), -1); +is ($pspec->values_cmp(1,0), 1); +is ($pspec->values_cmp(1,1), 0); +is ($pspec->values_cmp(123,456), 0); +is ($pspec->values_cmp('',''), 0); push @params, $pspec; +$pspec = Glib::ParamSpec->boolean ('untrue', 'Untrue', + 'A pernicious falsehood', + FALSE, 'readable'); +# this is PL_sv_no, not a 0, for historical compatibility +is ($pspec->get_default_value, '', "Boolean default (expect TRUE)"); +# not pushed, just checking the default +# push @params, $pspec; + + # # all of the integer types have the same interface. # @@ -82,6 +96,10 @@ is ($pspec->get_maximum, $max, "$nick max"); is ($pspec->get_default_value, $default, "$nick default"); push @params, $pspec; + + is ($pspec->values_cmp(22,33), -1); + is ($pspec->values_cmp(33,22), 1); + is ($pspec->values_cmp(22,22), 0); } # @@ -101,6 +119,12 @@ is_float ($pspec->get_maximum, $max, "$nick maximum"); is_float ($pspec->get_default_value, $default, "$nick default"); ok ($pspec->get_epsilon > 0.0, "$nick epsilon"); + is ($pspec->values_cmp(22,33), -1); + is ($pspec->values_cmp(33,22), 1); + is ($pspec->values_cmp(22,22), 0); + is ($pspec->values_cmp(0, $pspec->get_epsilon / 2), 0); + is ($pspec->values_cmp($pspec->get_epsilon / 4, + - $pspec->get_epsilon / 4), 0); push @params, $pspec; } @@ -115,6 +139,10 @@ pspec_common_ok ($pspec, 'Enum', G_PARAM_READWRITE, 'Fish'); is ($pspec->get_enum_class, 'Fish', 'enum class'); is ($pspec->get_default_value, 'blue', "Enum default"); +is ($pspec->values_cmp('one','two'), -1); +is ($pspec->values_cmp('red','blue'), -1); +is ($pspec->values_cmp('blue','one'), 1); +is ($pspec->values_cmp('red','red'), 0); push @params, $pspec; @@ -124,6 +152,9 @@ pspec_common_ok ($pspec, 'Flags', G_PARAM_READWRITE, 'Rain'); is ($pspec->get_flags_class, 'Rain', 'flags class'); ok ($pspec->get_default_value == ['light', 'warm'], 'Flags default'); +is ($pspec->values_cmp('warm','cold'), -1); +is ($pspec->values_cmp(['cold','light'],['light']), 1); +is ($pspec->values_cmp(['heavy'],'heavy'), 0); push @params, $pspec; @@ -132,6 +163,11 @@ # we only know one boxed type at this point. 'Glib::Scalar', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Boxed', G_PARAM_READWRITE, 'Glib::Scalar'); +is ($pspec->get_default_value, undef, 'Boxed default'); +{ # 1 or -1 depends on address, which is unpredictable + ok ($pspec->values_cmp('foo','bar') != 0); + # almost no Glib::Scalar has an equal address, so no tests for 0 here +} push @params, $pspec; @@ -139,6 +175,8 @@ 'I object, Your Honor, that\'s pure conjecture!', 'Skeezle', G_PARAM_READWRITE); pspec_common_ok ($pspec, 'Object', G_PARAM_READWRITE, 'Skeezle'); +is ($pspec->get_default_value, undef, 'Object default'); +is ($pspec->values_cmp(undef,undef), 0); push @params, $pspec; @@ -154,6 +192,9 @@ ok ($pspec->get_flags == G_PARAM_READWRITE, 'Param flags'); is ($pspec->get_value_type, 'Glib::Param::Enum', 'Param value type'); ok (! $pspec->get_owner_type, 'Param owner type'); +is ($pspec->get_default_value, undef, 'Param default'); +is ($pspec->values_cmp($pspec,$pspec), 0); +ok ($pspec->values_cmp($pspec,$params[0]) != 0); push @params, $pspec; @@ -162,6 +203,9 @@ 'ö', qw/readable/); pspec_common_ok ($pspec, 'Unichar', qw/readable/, 'Glib::UInt'); is ($pspec->get_default_value, 'ö', 'Unichar default'); +is ($pspec->values_cmp('A','B'), -1); +is ($pspec->values_cmp('B','A'), -1); +is ($pspec->values_cmp('B','B'), 0); push @params, $pspec; @@ -171,6 +215,7 @@ $pspec = Glib::ParamSpec->IV ('iv', 'IV', 'This is the same as Int', -20, 10, -5, G_PARAM_READWRITE); +is ($pspec->get_default_value, -5, 'IV default'); isa_ok ($pspec, 'Glib::Param::Long', 'IV is actually Long'); push @params, $pspec; @@ -179,6 +224,7 @@ 'This is the same as UInt', 10, 20, 15, G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::ULong', 'UV is actually ULong'); +is ($pspec->get_default_value, 15, 'UV default'); push @params, $pspec; @@ -187,6 +233,7 @@ G_PARAM_READWRITE); isa_ok ($pspec, 'Glib::Param::Boxed', 'Scalar is actually Boxed'); is ($pspec->get_value_type, 'Glib::Scalar', 'boxed holding scalar'); +is ($pspec->get_default_value, undef, 'Scalar default'); push @params, $pspec; _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcsKevin Ryde wrote:
> Perhaps just making the class hierarchy clearer would be enough. I > didn't realize immediately the funcs like Glib::ParamSpec->double > created Glib::Param::Double etc. And the pod for Glib::Param::Double > when you get there alas lacks a "HIERARCHY" section to enlighten the > ignorant that you can go back to Glib::ParamSpec for other methods. Good idea. I just added a HIERARCHY section to every subclass. -- Bye, -Torsten _______________________________________________ gtk-perl-list mailing list gtk-perl-list@... http://mail.gnome.org/mailman/listinfo/gtk-perl-list |
|
|
Re: GParamSpec further funcs |