After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 667228 - Deprecate GValueArray
Deprecate GValueArray
Status: RESOLVED FIXED
Product: glib
Classification: Platform
Component: gobject
unspecified
Other All
: Normal enhancement
: ---
Assigned To: gtkdev
gtkdev
Depends on: 667243
Blocks:
 
 
Reported: 2012-01-03 22:46 UTC by Emmanuele Bassi (:ebassi)
Modified: 2015-08-11 15:16 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
Deprecate GValueArray (7.34 KB, patch)
2012-01-04 09:35 UTC, Emmanuele Bassi (:ebassi)
none Details | Review
Deprecate GValueArray (9.47 KB, patch)
2012-01-25 04:38 UTC, Matthias Clasen
committed Details | Review
Revert deprecation (9.36 KB, patch)
2012-02-16 17:19 UTC, Colin Walters
none Details | Review

Description Emmanuele Bassi (:ebassi) 2012-01-03 22:46:32 UTC
GValueArray is a redundant type that has several problems:

 - the API does not conform with the GArray, GPtrArray, and GByteArray types;
 - it's fully exposed on the stack, so we cannot add ref/unref;
 - there's no way to forcibly resize it.

the reason why we have GValueArray in the first place is because when GObject was new, back in the Jurassic GArray didn't have a GType. GArray now does, and it's a better, more extensible API.

GValueArray should just be deprecated in favor of GArray.
Comment 1 Emmanuele Bassi (:ebassi) 2012-01-03 22:50:52 UTC
the missing bit in the GArray API to allow a full replacement of GValueArray is adding a way to unset the GValue when freeing the array.

a simple g_array_set_free_func() function, modelled on the equivalent GPtrArray one, would fit the bill.
Comment 2 Matthias Clasen 2012-01-04 02:55:41 UTC
Sounds like a good idea to me
Comment 3 Emmanuele Bassi (:ebassi) 2012-01-04 08:07:34 UTC
the array clear function is tracked in bug 667243. I'll attach the GValueArray deprecation patches here.
Comment 4 Emmanuele Bassi (:ebassi) 2012-01-04 09:35:39 UTC
Created attachment 204552 [details] [review]
Deprecate GValueArray

The GValueArray type was added in a time, during the Jurassic era or so,
when GArray did not have a representable GType. The GValueArray API has
various issues as well:

  - it doesn't match the other GLib array types;
  - it is not reference counted;
  - the structure is fully exposed on the stack, so it cannot be
    extended to add reference counting;
  - it cannot be forcibly resized.

The nice thing is that now we have a GArray type that can replace in
full GValueArray, so we can deprecate the latter, and reduce the
complexity in GLib, application code, and bindings.
Comment 5 Matthias Clasen 2012-01-04 17:40:32 UTC
Review of attachment 204552 [details] [review]:

Presumably the boxed type and the paramspec should go with it ? (being deprecated, I mean)
Comment 6 Matthias Clasen 2012-01-04 17:40:33 UTC
Review of attachment 204552 [details] [review]:

Presumably the boxed type and the paramspec should go with it ? (being deprecated, I mean)
Comment 7 Emmanuele Bassi (:ebassi) 2012-01-04 18:39:14 UTC
Review of attachment 204552 [details] [review]:

yes, good point.
Comment 8 Benjamin Otte (Company) 2012-01-16 22:36:20 UTC
(In reply to comment #1)
> a simple g_array_set_free_func() function, modelled on the equivalent GPtrArray
> one, would fit the bill.
>
One thing I noted on IRC:
This should probably be named differently, because - as opposed to regular free funcs - you're not supposed to free the value, but only to clear the contents.
So something like g_array_set_clear_func() sounds like a better idea to me.
Comment 9 Matthias Clasen 2012-01-25 04:38:46 UTC
The following fix has been pushed:
0ac9ab4 Deprecate GValueArray
Comment 10 Matthias Clasen 2012-01-25 04:38:50 UTC
Created attachment 206051 [details] [review]
Deprecate GValueArray

The GValueArray type was added in a time, during the Jurassic era or so,
when GArray did not have a representable GType. The GValueArray API has
various issues as well:

  - it doesn't match the other GLib array types;
  - it is not reference counted;
  - the structure is fully exposed on the stack, so it cannot be
    extended to add reference counting;
  - it cannot be forcibly resized.

The nice thing is that now we have a GArray type that can replace in
full GValueArray, so we can deprecate the latter, and reduce the
complexity in GLib, application code, and bindings.
Comment 11 Emmanuele Bassi (:ebassi) 2012-01-25 17:00:20 UTC
apparently, GStreamer is using GValueArray in one of their signals on a plugin, and special-casing GValueArray to do some introspection on it. switching to GArray would remove their ability to use the signal from other languages, given that the plugin cannot use the common gobject-introspection annotations.

relevant discussion:

16:07 < slomo> ebassi: the deprecation of GValueArray is not really a good idea until GArray has something to specify the element type
16:07 < slomo> ebassi: the advatange of GValueArray was that it was introspectable at runtime and there's nothing to replace this
16:08 < ebassi> it doesn't even guarantee you're storing the same GType
16:08 < slomo> ebassi: with GValueArray you knew that the elements are GValues and that you can get the type of them. with GArray you don't know anything about the elements
16:08 < slomo> ebassi: GArray just points to random memory without any information about how to interprete it
16:09 < ebassi> slomo: that's just because you could special-case GValueArray
16:10 < ebassi> "introspecting" GArray is done using annotations
16:10 < ebassi> you can define the element type
16:10 < slomo> ebassi: yes but that's not possible in the case of plugins, like the gstreamer plugins
16:11 < tpm> ebassi, e.g. 
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-plugins/html/gst-plugins-base-plugins-decodebin2.html#GstDecodeBin2-autoplug-factories
16:17 < ebassi> is the GValueArray returned by that signal going to hold the same GType or any?
16:18 < tpm> it will be an array of GObjects

options:

- undeprecate GValueArray, with a huge caveat section, basically just for GStreamer;
- GStreamer gets its own GstValueArray type and language bindings learn how tocope with that in the same way they cope with other Gst types;
- we somehow add API to store the type of the contents of a GArray;
- we add a GObjectArray to gobject, which "subclasses" GPtrArray but does a bunch of additional stuff, like type checks and correct ref/unref on the elements.
Comment 12 Emmanuele Bassi (:ebassi) 2012-01-25 17:02:02 UTC
additional awfulness:

16:54 < slomo> ebassi: ok, same problem with a new type :) we have a GValueArray of doubles in a plugin too
16:54 < slomo> ebassi: i don't want a GObject that wraps a double :P
Comment 13 Sebastian Dröge (slomo) 2012-01-25 17:07:09 UTC
IMHO there should be a GObjectArray and a GNewAndBetterValueArray
Comment 14 Benjamin Otte (Company) 2012-01-25 17:44:45 UTC
I don't like adding special-cased array types much.
What I'd like however is a function like g_ptr_array_set_value_type() - but I'm not sure how that fits into the glib/gobject split.
Comment 15 Emmanuele Bassi (:ebassi) 2012-01-25 17:52:39 UTC
as I said, there's also the distinct path of GStreamer dealing with its own API issues by having a GstWhateverArray - as a refcounted, boxed type - and using it in place of GValueArray.

there's also the option of allowing the signal to express the GType of the data stored inside the GArray returned by the signal, i.e. by adding a GType (out) parameter to the signal itself, or a GType property on the class that will emit those signals - i.e.:

  plugin.autoplug_factory_type = WhateverAwesomeObject
  factories = plugin.emit('autoplug-factory-create', args)

there's also the chance of passing an ad hoc collection type to the signal itself, and leave it to the people connecting to the signal to fill that up.

alternatively, GStreamer starts using the GIRepository API, and expects its plugins to expose a GIR/typelib describing their API (especially signals and properties), since the object introspection API is comically limited, and the GIRepository API was introduced exactly for this kind of stuff.
Comment 16 Emmanuele Bassi (:ebassi) 2012-01-25 17:54:39 UTC
yes, special-casing array types is not great.

this obviously brings up the whole "where does the type system live" issue; with a GType in GLib, we could have a proper array that does type checking.

at this point, the idea of moving at least GType and GTypeInstance inside libglib, and leaving GObject inside libgobject, sounds to me more and more like the way forward.
Comment 17 Matthias Clasen 2012-01-25 18:19:17 UTC
There's an existing bug with patches by davidz for adding element-type stuff. Don't have the bug # at hand.
Comment 18 David Zeuthen (not reading bugmail) 2012-01-26 19:04:44 UTC
Please don't deprecate stuff in GLib without at least cleaning up GLib itself - it's not nice that master compiles with a bunch of deprecating warnings.
Comment 19 Emmanuele Bassi (:ebassi) 2012-01-26 19:35:57 UTC
(In reply to comment #18)
> Please don't deprecate stuff in GLib without at least cleaning up GLib itself -
> it's not nice that master compiles with a bunch of deprecating warnings.

which deprecation warnings? the only users in GLib of GValueArray have been protected by using GLIB_DISABLE_DEPRECATION_WARNINGS.

if you mean the autogenerated test code, I guess it will have to be either ported or protected in the same way.
Comment 20 Dan Winship 2012-01-26 19:36:15 UTC
(In reply to comment #11)
> options:
> 
> - undeprecate GValueArray, with a huge caveat section, basically just for
> GStreamer;

libsoup uses GValueArray too, for XML-RPC, in its public API. And it also requires run-time introspectability. (You give the XML-RPC API some GValues, it serializes them into an XML-RPC request, takes the response, and gives it back to you as a GValue.) (At some point I want to port this to being GVariant-based, but it's low on the to-do list, and also slightly tricky in that GVariant doesn't have a datetime type.)
Comment 21 David Zeuthen (not reading bugmail) 2012-01-26 19:59:15 UTC
(In reply to comment #19)
> (In reply to comment #18)
> > Please don't deprecate stuff in GLib without at least cleaning up GLib itself -
> > it's not nice that master compiles with a bunch of deprecating warnings.
> 
> which deprecation warnings? the only users in GLib of GValueArray have been
> protected by using GLIB_DISABLE_DEPRECATION_WARNINGS.
> 
> if you mean the autogenerated test code, I guess it will have to be either
> ported or protected in the same way.

Yes, I meant the code generated by gdbus-codegen (used in more than just tests). Anyway, easily fixed by just using a plain C array, not exactly sure why I use GValueArray in the first place. Fix is here

http://git.gnome.org/browse/glib/commit/?id=8e763aef43b951746662978c7c644365a92ecfa3
Comment 22 Benjamin Otte (Company) 2012-01-26 20:19:19 UTC
I think it's a valid argument to require to fix your own code to not use deprecated API before you deprecate API. And "your own code" should include tests that don't specifically target that API and code generators.

I'm not a fan of people adding G_DEPRECATED_FOR(something_else) in front of functions without taking responsibility for the compiler warnings they create with that.
Comment 23 Matthias Clasen 2012-01-26 21:50:16 UTC
I don't really buy the arguments here - if you think gvalue is great, just stuff gvalues into a garray
Comment 24 Matthias Clasen 2012-01-26 21:51:54 UTC
(In reply to comment #22)
> I think it's a valid argument to require to fix your own code to not use
> deprecated API before you deprecate API. And "your own code" should include
> tests that don't specifically target that API and code generators.
> 
> I'm not a fan of people adding G_DEPRECATED_FOR(something_else) in front of
> functions without taking responsibility for the compiler warnings they create
> with that.

I've committed the deprecations after a full build came up clean of warnings - not really my fault that tests aren't built unless you do an explicit make check.
Comment 25 Tim-Philipp Müller 2012-01-27 09:19:52 UTC
> There's an existing bug with patches by davidz for adding element-type stuff.
> Don't have the bug # at hand.
>  ...
> I don't really buy the arguments here - if you think gvalue is great, just
> stuff gvalues into a garray

Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't really solve anything for us, because there is no way to introspect the element type at runtime, and there's no way to tell dynamic bindings about per-element annotations. The problem is that GStreamer elements don't have any public API beyond GObject/GSignal API. There are no header files or exported symbols for GStreamer elements, and there are no .gir files for GStreamer elements.

Just to give some context, we're in the process of finalising the upcoming GStreamer 1.0 API, which we'd like to keep stable for a few years. We're going to depend on GLib 2.32 initially. We really need a solution that is workable for us, deliverable with GLib 2.32 and will be supported going forward.
Comment 26 Dan Winship 2012-01-27 11:49:44 UTC
(In reply to comment #25)
> Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't
> really solve anything for us, because there is no way to introspect the element
> type at runtime

I believe the suggestion is that gstreamer should assume that (for purposes of gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues". (This wouldn't conflict with any other uses of G_TYPE_ARRAY, since you couldn't be using it anyway since it's not introspectable.)
Comment 27 Sebastian Dröge (slomo) 2012-01-27 13:53:37 UTC
(In reply to comment #26)
> (In reply to comment #25)
> > Emmanuele suggested this in the IRC discussion pasted earlier, but it doesn't
> > really solve anything for us, because there is no way to introspect the element
> > type at runtime
> 
> I believe the suggestion is that gstreamer should assume that (for purposes of
> gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues".
> (This wouldn't conflict with any other uses of G_TYPE_ARRAY, since you couldn't
> be using it anyway since it's not introspectable.)

The problem is not GStreamer assuming something or not, but bindings. Bindings would need to be able to know what the element type of a GArray is without having any GObject-Introspection annotations available. Of course you could define that a GArray without annotations should be treated as a GArray containing GValues by bindings but this decision would seem arbitrary.
Comment 28 Sebastian Dröge (slomo) 2012-02-06 08:06:41 UTC
ping?
Comment 29 Christian Fredrik Kalager Schaller 2012-02-07 12:57:49 UTC
Any updates on this? Any chance to get it 'un-deprecated' ?
Comment 30 Matthias Clasen 2012-02-14 00:02:32 UTC
No, I don't think we want to undeprecate it.
Deprecated != dead, you can still use it until you have your bindings fixed to use something else.
Comment 31 Sebastian Dröge (slomo) 2012-02-14 08:51:55 UTC
"Having your bindings fixed" is not really a useful comment. There's no "your bindings" anymore as every GObject binding now uses (or soon uses) gobject-introspection and everything has to work with g-i now.
Comment 32 Christian Fredrik Kalager Schaller 2012-02-14 10:22:31 UTC
True we can still use the deprecated API, and I guess there is zero chance that it will ever go away in glib 2.x, but it still feels quite annoying to have an API you depend heavily on deprecated with no agreed/suitable alternative solution available.

Also in regards to your comment about 'fixing our bindings' if it is the opinion of one of the main glib maintainers that making sure developers can use glib through gobject-inspection isn't a priority for glib development, then of course that is good feedback to have and we need to revise our bindings strategy for GStreamer accordingly.
Comment 33 Benjamin Otte (Company) 2012-02-14 12:01:06 UTC
Can we be more productive and less whiny please?

I think we can all agree that the current usages of GValueArray are hacks, ie workarounds for missing functionality. I think we can also agree that because of that it makes sense to deprecated GValueArray.

Do we have any idea how such a solution would look? Can we undo the deprecation of GValueArray until such a solution is implemented?
Comment 34 Dan Winship 2012-02-14 12:07:04 UTC
(In reply to comment #33)
> Do we have any idea how such a solution would look?

like dbus-glib's system for registering compound gtypes? 

http://dbus.freedesktop.org/doc/dbus-glib/dbus-glib-Specializable-GType-System.html#dbus-glib-Specializable-GType-System.description

eg (from NM)

#define DBUS_TYPE_G_ARRAY_OF_STRING (dbus_g_type_get_collection ("GPtrArray", G_TYPE_STRING))
#define DBUS_TYPE_G_MAP_OF_VARIANT  (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE))
Comment 35 Matthias Clasen 2012-02-14 14:59:24 UTC
GObject simply has no first-class collection support. Claiming that GValueArray somehow provided that is just misleading, imo.
Comment 36 Simon McVittie 2012-02-14 16:10:27 UTC
(In reply to comment #33)
> I think we can all agree that the current usages of GValueArray are hacks, ie
> workarounds for missing functionality.

I'm not sure that I agree that GValueArray is redundant with GArray. As I see it, a GVA is a heterogeneous tuple of dynamically-typed objects (like a Python tuple). If I remember correctly, it's also the internal representation of the "payload" of a signal? It seems a natural representation for that, anyway.

Compare with GArray and GPtrArray, which are homogeneous arrays of statically-typed objects (each of the (element-type), in g-i terms) - if you have a GArray of GValues, it's not really a tuple of arbitrary objects, but more like a homogeneous array of GValue boxes (with those GValue boxes potentially containing heterogeneous dynamically-typed objects).

Maybe GVA should have been called GTuple, but we already have that, and it does something else and is deprecated.

(In reply to comment #11)
> - undeprecate GValueArray, with a huge caveat section, basically just for
> GStreamer

... and dbus-glib (which uses GVA to represent D-Bus "struct" types), and telepathy-glib, and anything else that was unwise enough to expose the types dbus-glib uses in its API.

(Yes yes, we do intend to move from dbus-glib to GDBus, but it's sufficiently pervasive that it's a very disruptive change.)

(In reply to comment #19)
> it's not nice that master compiles with a bunch of deprecating warnings.

We've turned off GLib deprecation warnings in telepathy-glib (and all projects that use it), because we treat deprecation warnings as fatal on development branches, and there's no way we're going to eradicate GValueArray from our API right now. Turning off *all* GLib deprecation warnings is a rather bigger hammer than we wanted. (The other option would be to make them warn non-fatally, i.e. constantly nag developers about something we/they can't do anything about in the short or medium term.)

(In reply to comment #34)
> like dbus-glib's system for registering compound gtypes? 

Have you looked at the implementation? It's pretty horrible (and I say that as a contributor to it). There's a reason GDBus uses GVariant instead...

With modern support from the GLib types, it could be less bad (e.g. now you can refcount arrays and hash tables, and set their destructors), but I suspect it'd still be pretty bad.

Note that dbus-glib uses GVA in its compound type system, both to represent D-Bus "structs" (tuples) and as its internal representation of an entire D-Bus message (which is basically also a tuple, and GDBus represents it as such).

dbus-glib's use of GVA is pretty close to my mental model for GVA, actually: it doesn't represent a D-Bus 'av' (array of variant) as a GVA, but instead as a GPtrArray<GValue>. So, everywhere that it does use a GVA, it's using it as a tuple.
Comment 37 Dan Winship 2012-02-14 16:24:16 UTC
(In reply to comment #36)
> dbus-glib's use of GVA is pretty close to my mental model for GVA, actually

I would guess that dbus-glib *created* your mental model of GValueArray, since GValueArray is not actually any more inherently tuple-like than GArray or GPtrArray.

Company suggested "g_array_set_element_type()" on IRC this morning, which would solve the problem from comment 27 (once bindings were updated to know about it), although such an API would have to involve weird collusion between libglib and libgobject. (Though no weirder than g_source_set_closure() really...)

> Turning off *all* GLib deprecation warnings is a rather bigger
> hammer than we wanted.

see bug 669671 comment 10
Comment 38 Colin Walters 2012-02-14 16:27:56 UTC
Going back to the original motivation here - the original reporter is saying basically "Hey GArray is better" but honestly GValueArray wasn't a real problem before.  Its usage wasn't creating a serious performance bottleneck, it isn't a huge amount of code that interacts with everything else, etc.

So I'm really not sure it's worth the pain for GLib consumers to deprecate it versus the pretty small "gain" in GLib.
Comment 39 Emmanuele Bassi (:ebassi) 2012-02-14 17:08:45 UTC
(In reply to comment #38)
> Going back to the original motivation here - the original reporter is saying
> basically "Hey GArray is better"

no, what I was saying was: "hey, GValueArray is *broken*". my assessment did not cover GArray (which I consider, like the rest of the container types in GLib, just moderately broken by the lack of typing information of their contents).

because it's fully public we cannot make it (compatibly) refcounted, and its API has a certain impedance mismatch with the API of the other array types in GLib, making it stand out.

as I said two hundred comments ago, in comment 11, undeprecating ValueArray may be doable - but "obvious API wart is obvious", as those damn kids today say. I even outlined a couple of ways to work around it - at least, for GStreamer, which at least is about to break API. dbus-glib users will warrant something else entirely, for instance the macros that Dan wrote.
Comment 40 Colin Walters 2012-02-16 16:22:18 UTC
(In reply to comment #39)
> (In reply to comment #38)
> > Going back to the original motivation here - the original reporter is saying
> > basically "Hey GArray is better"
> 
> no, what I was saying was: "hey, GValueArray is *broken*". 

Mmm...we probably have different definitions of "broken".  Or more precisely I think you're using "broken" where I would say "suboptimal" or "could be improved".

 - the API does not conform with the GArray, GPtrArray, and GByteArray types;

The API not being consistent really isn't "broken", and we have to live with it forever anyways.

 - it's fully exposed on the stack, so we cannot add ref/unref;

Current API consumers were using it without this functionality.  Was there some sort of common pattern of e.g. people leaking memory while using it?  Or is it more about enabling new functionality?

 - there's no way to forcibly resize it.

Same as above.
Comment 41 Emmanuele Bassi (:ebassi) 2012-02-16 16:44:30 UTC
(In reply to comment #40)
> (In reply to comment #39)
> > (In reply to comment #38)
> > > Going back to the original motivation here - the original reporter is saying
> > > basically "Hey GArray is better"
> > 
> > no, what I was saying was: "hey, GValueArray is *broken*". 
> 
> Mmm...we probably have different definitions of "broken".  Or more precisely I
> think you're using "broken" where I would say "suboptimal" or "could be
> improved".

my definition of broken includes "if we cannot safely make it better, then it's broken".

>  - the API does not conform with the GArray, GPtrArray, and GByteArray types;
> 
> The API not being consistent really isn't "broken", and we have to live with it
> forever anyways.

yes; hence the deprecation.

>  - it's fully exposed on the stack, so we cannot add ref/unref;
> 
> Current API consumers were using it without this functionality.

we cannot conceivably use a bigger allocation internall, and then just return a GValueArray to the constructor, without introducing an ABI break for the (possibly insane, but valid nonetheless) use case of people actually assuming that it's entirely possible to place a GValueArray on the stack and let another library consume it; if the other library is updated to use a ref/unref then we'd just have broken the ABI guarantees, as well as have introduced hard to debug crashers.

>  Was there some
> sort of common pattern of e.g. people leaking memory while using it?  Or is it
> more about enabling new functionality?

see above.

the deprecation is a mechanism to cut our losses now, instead of introducing breakage when there are more than two moving parts.

I don't have any horse in this race whatsoever; I ported my code using GValueArray to proper C arrays because GValueArray didn't buy me anything at all - and I never exposed GValueArray (or any other *Array type) in my API because the lack of typing and safety, as well as lack of support in language bindings. as far as I'm concerned, my interest in this bug was exhausted when g_array_set_clear_func() landed, and the deprecation of GValueArray was a nice way to reduce the array type redundancy in GLib.
Comment 42 Colin Walters 2012-02-16 17:19:56 UTC
Created attachment 207795 [details] [review]
Revert deprecation

This patch reverts the deprecation, but I kept the new documentation section which points to GArray + g_array_set_clear_func().
Comment 43 Tim-Philipp Müller 2012-02-16 18:45:29 UTC
> I even outlined a couple of ways to work around it - at least, for GStreamer,
> which at least is about to break API

Unfortunately the suggestions made so far either don't cover all of our use-cases (signals, properties, data sent by elements to applications via GstMessage/GstStructure) or seem very unappealing from a platform point of view. We don't mind migrating away from GValueArray at all, but at the moment our best option seems to be to just stick to it, even if it stays deprecated.


> there's also the distinct path of GStreamer dealing with its own
> API issues by having a GstWhateverArray - as a refcounted, boxed
> type - and using it in place of GValueArray.

This would be a possibility, but it doesn't seem particularly appealing. If I'm not mistaken, it means that g-i-based binding can't implement automagic array conversions unless they link to gstreamer, or people implement some extra python/whatever module with gstreamer magic extensions. High-level language users will have to use GStreamer-specific API for those arrays instead of native language features, which feels a bit fail.


> there's also the option of allowing the signal to express the GType of
> the data stored inside the GArray returned by the signal, (...)

This might work for signals, but we also need to cover properties and stuff sent in element messages (GValues in a dictionary, basically).


> alternatively, GStreamer starts using the GIRepository API, and expects its
> plugins to expose a GIR/typelib describing their API (especially signals and
> properties), since the object introspection API is comically limited, and the
> GIRepository API was introduced exactly for this kind of stuff.

Adding GIR/typelib stuff for GStreamer elements would be possible, but that only solves part of the problem (signals and properties), not data sent in element messages.

It's also a bit iffy for dynamically generated elements in wrapper plugins such as ffmpeg/libav, opencv, frei0r, ladspa etc. - we would have to generate the introspection data for those on the fly as well then.


> the suggestion is that [bindings] should assume that (for purposes of
> gstreamer elements) G_TYPE_ARRAY always means "GArray containing GValues".

This would probably work technically, assuming GLib or gobject-introspection document this as official policy for bindings, but as Sebastian already mentioned, it seems a bit arbitrary, and I'm not convinced this is a step in the right direction. I think we would still prefer a deprecated GValueArray with explicit element types to this.


There was mention of the handling of other GStreamer types (fundamental types such as fractions etc.) earlier. That is certainly a valid point and a problem of sorts as well, but in practice it's much less of a problem, because those types tend to be limited to caps, and caps can be created/manipulated differently, and most people prefer that route anyway (just create caps from a string, that is).

===============

To re-cap, what we need is an array type of some sort that can hold GObjects or doubles or ints etc., where the GType of the content can be determined at run-time using GLib API, and given the type one knows how to extract the different values (that doesn't necessarily have to be via a GValue). In our case the GType is always the same for all elements in the array, for a given array. Refcounting would be nice too of course.

Perhaps we could just come up with a GBetterValueArray ? I feel that this kind of functionality does belong into GObject, even if GStreamer is the only major user we are aware of. It's just where it belongs in the platform IMHO. (But perhaps I am mistaken to assume that GLib these days serves as the base library for our platform, and is no longer just a utility library for Gtk+, or that GStreamer is an important part of that same platform).

A bunch of boxed GTypes such as G_TYPE_OBJECT_ARRAY, G_TYPE_DOUBLE_ARRAY, G_TYPE_BOXED_ARRAY, G_TYPE_INT_ARRAY etc. would work as well, but my impression was that no one's very keen on that, not least because we can't derive from G_TYPE_ARRAY, though I'm not sure if that's really necessary anyway (would anyone want to speculate how much effort it would be to add support for derived boxed types?)
Comment 44 Matthias Clasen 2012-02-16 18:57:10 UTC
I think this does not buy us anything, tbh.

Either we want to use deprecations to inform api users of suboptimal apis that may eventually go away, or we deprecation is just too inconvenient because everybody is religious about immediate deprecation-freeness.

I don't see any value in adding shades of gray between deprecated and non-deprecated.
Comment 45 Colin Walters 2012-02-16 19:14:15 UTC
(In reply to comment #44)
> I think this does not buy us anything, tbh.
> 
> Either we want to use deprecations to inform api users of suboptimal apis that
> may eventually go away, 

I don't agree with "may eventually go away".

> or we deprecation is just too inconvenient because
> everybody is religious about immediate deprecation-freeness.

Yeah, this does intersect with the whole issue of -Werror which is a mess.

> I don't see any value in adding shades of gray between deprecated and
> non-deprecated.

There is no gray here - GValueArray isn't deprecated (after the patch).  It's just that you can also use a GArray in some (possibly "most") circumstances.
Comment 46 Sebastian Dröge (slomo) 2012-02-20 13:02:33 UTC
So what's going to happen here now, AFAIK glib is supposed to be API frozen soon for 2.32 and GValueArray is still deprecated without having a complete replacement yet.

We currently use GValueArray in public GStreamer API and would be happy to move to a better, non-deprecated alternative if one existed. But for using it in the public GStreamer 1.0 API we would need this to exist in GLib 2.32 already. The only alternative would be to stick with GValueArray until GStreamer 2.0.
Comment 47 Pavel Holejsovsky 2012-02-21 09:20:06 UTC
> To re-cap, what we need is an array type of some sort that can hold GObjects or
> doubles or ints etc., where the GType of the content can be determined at
> run-time using GLib API, and given the type one knows how to extract the
> different values (that doesn't necessarily have to be via a GValue). In our
> case the GType is always the same for all elements in the array, for a given
> array. Refcounting would be nice too of course.

Sorry to be a bit dense, but I still don't understand what's wrong with GArray of GValue, i.e. with (element-type GObject.Value) annotation.  IMHO bindings should support this construct 'natively', without any additional care, as an array of GValues, and the application (written on top of the binding) should take care of packing/unpacking the GValue array items.
Comment 48 Sebastian Dröge (slomo) 2012-02-21 09:28:25 UTC
(In reply to comment #47)
> > To re-cap, what we need is an array type of some sort that can hold GObjects or
> > doubles or ints etc., where the GType of the content can be determined at
> > run-time using GLib API, and given the type one knows how to extract the
> > different values (that doesn't necessarily have to be via a GValue). In our
> > case the GType is always the same for all elements in the array, for a given
> > array. Refcounting would be nice too of course.
> 
> Sorry to be a bit dense, but I still don't understand what's wrong with GArray
> of GValue, i.e. with (element-type GObject.Value) annotation.  IMHO bindings
> should support this construct 'natively', without any additional care, as an
> array of GValues, and the application (written on top of the binding) should
> take care of packing/unpacking the GValue array items.

The problem with this is that the element type (i.e. GValue in your example) is not runtime-introspectable. You can't always add static introspection annotations, and in the case of GStreamer there are multiple places where you simply can't. The same is true for other highly-dynamic uses of the GObject type system.
Comment 49 Pavel Holejsovsky 2012-02-21 10:06:45 UTC
(In reply to comment #48)
> (In reply to comment #47)
> > Sorry to be a bit dense, but I still don't understand what's wrong with GArray
> > of GValue, i.e. with (element-type GObject.Value) annotation.  IMHO bindings
> > should support this construct 'natively', without any additional care, as an
> > array of GValues, and the application (written on top of the binding) should
> > take care of packing/unpacking the GValue array items.
> 
> The problem with this is that the element type (i.e. GValue in your example) is
> not runtime-introspectable. You can't always add static introspection
> annotations, and in the case of GStreamer there are multiple places where you
> simply can't. The same is true for other highly-dynamic uses of the GObject
> type system.

I apologize but I still don't get it.  GValue is not runtime-introspectable?  Runtime introspectability is the key feature of GValue, and any sane binding should IMHO somehow respect it - either automatically by transparent boxing/unboxing of values for dynamic languages, or allowing direct access to native g_value_xxx methods, or providing some target-language-friendly wrapper for querying type/value of the GValue, or some combination of above methods.
Comment 50 Sebastian Dröge (slomo) 2012-02-21 10:45:38 UTC
GArray's element type is not runtime-introspectable.
Comment 51 Pavel Holejsovsky 2012-02-21 10:52:48 UTC
(In reply to comment #50)
> GArray's element type is not runtime-introspectable.

True, but GArray's element type will be (compile-time) annotated to be GValue, which is runtime introspectable.
Comment 52 Sebastian Dröge (slomo) 2012-02-21 11:04:58 UTC
Yes, and what you've written in the parenthesis is exactly the problem. It's a compile-time annotation that is necessary to specify the element type of a GArray. There's no runtime introspection for the element type.
Comment 53 Pavel Holejsovsky 2012-02-21 14:12:17 UTC
(In reply to comment #52)
> Yes, and what you've written in the parenthesis is exactly the problem. It's a
> compile-time annotation that is necessary to specify the element type of a
> GArray. There's no runtime introspection for the element type.

Actually, it is GValue that provides the runtime introspection.  To illustrate my point, I've tried adding following method to GI regress test suite (regress.c):

/**
 * regress_test_array_gvalue_return:
 * Return value: (element-type GObject.Value) (transfer full):
 */
GArray *regress_test_array_gvalue_return (void)
{
  GArray *array = g_array_sized_new (FALSE, TRUE, sizeof (GValue), 2);
  g_array_set_size (array, 2);
  g_value_init (&g_array_index (array, GValue, 0), G_TYPE_STRING);
  g_value_set_string (&g_array_index (array, GValue, 0), "Hello");
  g_value_init (&g_array_index (array, GValue, 1), G_TYPE_INT);
  g_value_set_int (&g_array_index (array, GValue, 1), 42);
  return array;
}

And then from python:
Python 2.6.7 (r267:88850, Feb  2 2012, 23:50:20) 
[GCC 4.5.3] on cygwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from gi.repository import Regress
>>> array = Regress.test_array_gvalue_return()
>>> print(array)
['Hello', 42]


The returned array is polymorphic, and python binding correctly unboxed the array elements according to the runtime GValue type.
Comment 54 Dan Winship 2012-02-21 15:03:36 UTC
(In reply to comment #53)
> /**
>  * regress_test_array_gvalue_return:
>  * Return value: (element-type GObject.Value) (transfer full):
>  */
> GArray *regress_test_array_gvalue_return (void)

No, that's not what we're talking about. We're talking about a function:

GValue *
regress_test_mystery_gvalue_return (void)
{
}

The return value could be any type. Sometimes it's an array, sometimes it's not. If you have GValueArray, then it's possible to return an array whose element type can also be determined. But with just GArray you can't; you can know it's an array of 24-byte items, but you don't know (for sure) what those items are.
Comment 55 Pavel Holejsovsky 2012-02-21 15:36:04 UTC
> GValue *
> regress_test_mystery_gvalue_return (void)
> {
> }
> 
> The return value could be any type. Sometimes it's an array, sometimes it's
> not. If you have GValueArray, then it's possible to return an array whose
> element type can also be determined. But with just GArray you can't; you can
> know it's an array of 24-byte items, but you don't know (for sure) what those
> items are.

OK, finally I understand the issue.  Thanks for your patience, and apologies for the noise.
Comment 56 Tim-Philipp Müller 2012-02-27 13:54:01 UTC
Just as an update following an IRC discussion from last week: I think the current plan for GStreamer 0.11 is at this point still to stick with GValueArray for element API (properties, signals, messages), but not to use it in public annotatable API (I think there was only one interface that used it, and that was removed anyway). We believe we can do without a {py,whatever}-gstreamer bindings module in addition to the gir bindings, and doing such a thing just for, or mostly for, some GStreamer-internal GValueArray replacement doesn't seem worth it.
Comment 57 Morten Welinder 2013-02-19 00:56:43 UTC
For the (late) record, this deprecation also means that API breaks will
have to cascade into libgsf.
Comment 58 Alejandro Piñeiro Iglesias (IRC: infapi00) 2013-08-26 13:03:31 UTC
Recently I opened bug 706315 to track the removal of GValueArray, as I understood that it was deprecated. But this bug is still open. Something missing? Bug still open by error?
Comment 59 Sebastian Dröge (slomo) 2013-08-26 14:12:10 UTC
There still is no replacement for GValueArray for all use-cases.
Comment 60 Morten Welinder 2014-04-14 13:00:52 UTC
Can we get undeprecation back on the radar, please?


1. A data structure library like this part of glib is full of redundant types.
   GSList, for example, is clearly redundant.  That's just the nature of things,
   not a sign of anything wrong.



2. Deprecation has a cost.  All the G_GNUC_BEGIN_IGNORE_DEPRECATIONS
   all over, say, gtk+ shows that the warning spam was painful because
   it hides more interesting warnings.

   I believe the cost-benefit analysis was done wrong for this deprecation:
   For a container type the cost seems much higher than the cost of
   keeping the code around.

   This is because this type is used in APIs of libraries so the cost
   cascades into library users.  And with stable APIs it is really not
   obvious how to fix.
Comment 61 Allison Karlitskaya (desrt) 2014-04-14 13:09:09 UTC
Don't hijack bugs by changing the summary -- it only serves to confuse people who may come to this bug later (from links in the commit logs, for example).
Comment 62 Emmanuele Bassi (:ebassi) 2015-08-11 15:16:27 UTC
GValueArray was deprecated not because of redundancy, but because its implementation was duplicating (badly) existing API; since it was duplicating it badly, it was also impossible for us to fix it transparently for applications.

I opened bug 753522 for a replacement convenience API to bridge GArray with GValue.

I think this bug can be closed: GValueArray was deprecated, and all we're missing is some helper API.