1 /*
2  * This file is part of gtkD.
3  *
4  * gtkD is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License
6  * as published by the Free Software Foundation; either version 3
7  * of the License, or (at your option) any later version, with
8  * some exceptions, please read the COPYING file.
9  *
10  * gtkD is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with gtkD; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
18  */
19 
20 // generated automatically - do not change
21 // find conversion definition on APILookup.txt
22 // implement new conversion functionalities on the wrap.utils pakage
23 
24 
25 module gstreamer.Bin;
26 
27 private import glib.ConstructionException;
28 private import glib.Str;
29 private import gobject.ObjectG;
30 private import gobject.Signals;
31 private import gstreamer.ChildProxyIF;
32 private import gstreamer.ChildProxyT;
33 private import gstreamer.Element;
34 private import gstreamer.Iterator;
35 private import gstreamer.Pad;
36 private import gstreamerc.gstreamer;
37 public  import gstreamerc.gstreamertypes;
38 public  import gtkc.gdktypes;
39 
40 
41 /**
42  * #GstBin is an element that can contain other #GstElement, allowing them to be
43  * managed as a group.
44  * Pads from the child elements can be ghosted to the bin, see #GstGhostPad.
45  * This makes the bin look like any other elements and enables creation of
46  * higher-level abstraction elements.
47  * 
48  * A new #GstBin is created with gst_bin_new(). Use a #GstPipeline instead if you
49  * want to create a toplevel bin because a normal bin doesn't have a bus or
50  * handle clock distribution of its own.
51  * 
52  * After the bin has been created you will typically add elements to it with
53  * gst_bin_add(). You can remove elements with gst_bin_remove().
54  * 
55  * An element can be retrieved from a bin with gst_bin_get_by_name(), using the
56  * elements name. gst_bin_get_by_name_recurse_up() is mainly used for internal
57  * purposes and will query the parent bins when the element is not found in the
58  * current bin.
59  * 
60  * An iterator of elements in a bin can be retrieved with
61  * gst_bin_iterate_elements(). Various other iterators exist to retrieve the
62  * elements in a bin.
63  * 
64  * gst_object_unref() is used to drop your reference to the bin.
65  * 
66  * The #GstBin::element-added signal is fired whenever a new element is added to
67  * the bin. Likewise the #GstBin::element-removed signal is fired whenever an
68  * element is removed from the bin.
69  * 
70  * <refsect2><title>Notes</title>
71  * <para>
72  * A #GstBin internally intercepts every #GstMessage posted by its children and
73  * implements the following default behaviour for each of them:
74  * <variablelist>
75  * <varlistentry>
76  * <term>GST_MESSAGE_EOS</term>
77  * <listitem><para>This message is only posted by sinks in the PLAYING
78  * state. If all sinks posted the EOS message, this bin will post and EOS
79  * message upwards.</para></listitem>
80  * </varlistentry>
81  * <varlistentry>
82  * <term>GST_MESSAGE_SEGMENT_START</term>
83  * <listitem><para>just collected and never forwarded upwards.
84  * The messages are used to decide when all elements have completed playback
85  * of their segment.</para></listitem>
86  * </varlistentry>
87  * <varlistentry>
88  * <term>GST_MESSAGE_SEGMENT_DONE</term>
89  * <listitem><para> Is posted by #GstBin when all elements that posted
90  * a SEGMENT_START have posted a SEGMENT_DONE.</para></listitem>
91  * </varlistentry>
92  * <varlistentry>
93  * <term>GST_MESSAGE_DURATION_CHANGED</term>
94  * <listitem><para> Is posted by an element that detected a change
95  * in the stream duration. The default bin behaviour is to clear any
96  * cached duration values so that the next duration query will perform
97  * a full duration recalculation. The duration change is posted to the
98  * application so that it can refetch the new duration with a duration
99  * query. Note that these messages can be posted before the bin is
100  * prerolled, in which case the duration query might fail.
101  * </para></listitem>
102  * </varlistentry>
103  * <varlistentry>
104  * <term>GST_MESSAGE_CLOCK_LOST</term>
105  * <listitem><para> This message is posted by an element when it
106  * can no longer provide a clock. The default bin behaviour is to
107  * check if the lost clock was the one provided by the bin. If so and
108  * the bin is currently in the PLAYING state, the message is forwarded to
109  * the bin parent.
110  * This message is also generated when a clock provider is removed from
111  * the bin. If this message is received by the application, it should
112  * PAUSE the pipeline and set it back to PLAYING to force a new clock
113  * distribution.
114  * </para></listitem>
115  * </varlistentry>
116  * <varlistentry>
117  * <term>GST_MESSAGE_CLOCK_PROVIDE</term>
118  * <listitem><para> This message is generated when an element
119  * can provide a clock. This mostly happens when a new clock
120  * provider is added to the bin. The default behaviour of the bin is to
121  * mark the currently selected clock as dirty, which will perform a clock
122  * recalculation the next time the bin is asked to provide a clock.
123  * This message is never sent tot the application but is forwarded to
124  * the parent of the bin.
125  * </para></listitem>
126  * </varlistentry>
127  * <varlistentry>
128  * <term>OTHERS</term>
129  * <listitem><para> posted upwards.</para></listitem>
130  * </varlistentry>
131  * </variablelist>
132  * 
133  * 
134  * A #GstBin implements the following default behaviour for answering to a
135  * #GstQuery:
136  * <variablelist>
137  * <varlistentry>
138  * <term>GST_QUERY_DURATION</term>
139  * <listitem><para>If the query has been asked before with the same format
140  * and the bin is a toplevel bin (ie. has no parent),
141  * use the cached previous value. If no previous value was cached, the
142  * query is sent to all sink elements in the bin and the MAXIMUM of all
143  * values is returned. If the bin is a toplevel bin the value is cached.
144  * If no sinks are available in the bin, the query fails.
145  * </para></listitem>
146  * </varlistentry>
147  * <varlistentry>
148  * <term>GST_QUERY_POSITION</term>
149  * <listitem><para>The query is sent to all sink elements in the bin and the
150  * MAXIMUM of all values is returned. If no sinks are available in the bin,
151  * the query fails.
152  * </para></listitem>
153  * </varlistentry>
154  * <varlistentry>
155  * <term>OTHERS</term>
156  * <listitem><para>the query is forwarded to all sink elements, the result
157  * of the first sink that answers the query successfully is returned. If no
158  * sink is in the bin, the query fails.</para></listitem>
159  * </varlistentry>
160  * </variablelist>
161  * 
162  * A #GstBin will by default forward any event sent to it to all sink elements.
163  * If all the sinks return %TRUE, the bin will also return %TRUE, else %FALSE is
164  * returned. If no sinks are in the bin, the event handler will return %TRUE.
165  * 
166  * </para>
167  * </refsect2>
168  */
169 public class Bin : Element, ChildProxyIF
170 {
171 	/** the main Gtk struct */
172 	protected GstBin* gstBin;
173 
174 	/** Get the main Gtk struct */
175 	public GstBin* getBinStruct()
176 	{
177 		return gstBin;
178 	}
179 
180 	/** the main Gtk struct as a void* */
181 	protected override void* getStruct()
182 	{
183 		return cast(void*)gstBin;
184 	}
185 
186 	protected override void setStruct(GObject* obj)
187 	{
188 		gstBin = cast(GstBin*)obj;
189 		super.setStruct(obj);
190 	}
191 
192 	/**
193 	 * Sets our main struct and passes it to the parent class.
194 	 */
195 	public this (GstBin* gstBin, bool ownedRef = false)
196 	{
197 		this.gstBin = gstBin;
198 		super(cast(GstElement*)gstBin, ownedRef);
199 	}
200 
201 	// add the ChildProxy capabilities
202 	mixin ChildProxyT!(GstBin);
203 
204 	/** */
205 	public this(Element elem)
206 	{
207 		super( elem.getElementStruct(), true );
208 		this.gstBin = cast(GstBin*)elem.getElementStruct();
209 	}
210 	
211 	/**
212 	 * Adds a list of elements to a bin.
213 	 * This function is equivalent to calling add() for each member of the list.
214 	 * The return value of each add() is ignored.
215 	 */
216 	public void addMany( Element[] elems... )
217 	{
218 		foreach( e; elems ) add( e );
219 	}
220 	
221 	/**
222 	 * Remove a list of elements from a bin.
223 	 * This function is equivalent to calling remove() with each member of the list.
224 	 */
225 	public void removeMany( Element[] elems... )
226 	{
227 		foreach( e; elems ) remove( e );
228 	}
229 
230 	/**
231 	 */
232 
233 	/** */
234 	public static GType getType()
235 	{
236 		return gst_bin_get_type();
237 	}
238 
239 	/**
240 	 * Creates a new bin with the given name.
241 	 *
242 	 * Params:
243 	 *     name = the name of the new bin
244 	 *
245 	 * Return: a new #GstBin
246 	 *
247 	 * Throws: ConstructionException GTK+ fails to create the object.
248 	 */
249 	public this(string name)
250 	{
251 		auto p = gst_bin_new(Str.toStringz(name));
252 		
253 		if(p is null)
254 		{
255 			throw new ConstructionException("null returned by new");
256 		}
257 		
258 		this(cast(GstBin*) p);
259 	}
260 
261 	/**
262 	 * Adds the given element to the bin.  Sets the element's parent, and thus
263 	 * takes ownership of the element. An element can only be added to one bin.
264 	 *
265 	 * If the element's pads are linked to other pads, the pads will be unlinked
266 	 * before the element is added to the bin.
267 	 *
268 	 * <note>
269 	 * When you add an element to an already-running pipeline, you will have to
270 	 * take care to set the state of the newly-added element to the desired
271 	 * state (usually PLAYING or PAUSED, same you set the pipeline to originally)
272 	 * with gst_element_set_state(), or use gst_element_sync_state_with_parent().
273 	 * The bin or pipeline will not take care of this for you.
274 	 * </note>
275 	 *
276 	 * MT safe.
277 	 *
278 	 * Params:
279 	 *     element = the #GstElement to add
280 	 *
281 	 * Return: %TRUE if the element could be added, %FALSE if
282 	 *     the bin does not want to accept the element.
283 	 */
284 	public bool add(Element element)
285 	{
286 		return gst_bin_add(gstBin, (element is null) ? null : element.getElementStruct()) != 0;
287 	}
288 
289 	/**
290 	 * Recursively looks for elements with an unlinked pad of the given
291 	 * direction within the specified bin and returns an unlinked pad
292 	 * if one is found, or %NULL otherwise. If a pad is found, the caller
293 	 * owns a reference to it and should use gst_object_unref() on the
294 	 * pad when it is not needed any longer.
295 	 *
296 	 * Params:
297 	 *     direction = whether to look for an unlinked source or sink pad
298 	 *
299 	 * Return: unlinked pad of the given
300 	 *     direction, %NULL.
301 	 */
302 	public Pad findUnlinkedPad(GstPadDirection direction)
303 	{
304 		auto p = gst_bin_find_unlinked_pad(gstBin, direction);
305 		
306 		if(p is null)
307 		{
308 			return null;
309 		}
310 		
311 		return ObjectG.getDObject!(Pad)(cast(GstPad*) p, true);
312 	}
313 
314 	/**
315 	 * Looks for an element inside the bin that implements the given
316 	 * interface. If such an element is found, it returns the element.
317 	 * You can cast this element to the given interface afterwards.  If you want
318 	 * all elements that implement the interface, use
319 	 * gst_bin_iterate_all_by_interface(). This function recurses into child bins.
320 	 *
321 	 * MT safe.  Caller owns returned reference.
322 	 *
323 	 * Params:
324 	 *     iface = the #GType of an interface
325 	 *
326 	 * Return: A #GstElement inside the bin implementing the interface
327 	 */
328 	public Element getByInterface(GType iface)
329 	{
330 		auto p = gst_bin_get_by_interface(gstBin, iface);
331 		
332 		if(p is null)
333 		{
334 			return null;
335 		}
336 		
337 		return ObjectG.getDObject!(Element)(cast(GstElement*) p, true);
338 	}
339 
340 	/**
341 	 * Gets the element with the given name from a bin. This
342 	 * function recurses into child bins.
343 	 *
344 	 * Returns %NULL if no element with the given name is found in the bin.
345 	 *
346 	 * MT safe.  Caller owns returned reference.
347 	 *
348 	 * Params:
349 	 *     name = the element name to search for
350 	 *
351 	 * Return: the #GstElement with the given
352 	 *     name, or %NULL
353 	 */
354 	public Element getByName(string name)
355 	{
356 		auto p = gst_bin_get_by_name(gstBin, Str.toStringz(name));
357 		
358 		if(p is null)
359 		{
360 			return null;
361 		}
362 		
363 		return ObjectG.getDObject!(Element)(cast(GstElement*) p, true);
364 	}
365 
366 	/**
367 	 * Gets the element with the given name from this bin. If the
368 	 * element is not found, a recursion is performed on the parent bin.
369 	 *
370 	 * Returns %NULL if:
371 	 * - no element with the given name is found in the bin
372 	 *
373 	 * MT safe.  Caller owns returned reference.
374 	 *
375 	 * Params:
376 	 *     name = the element name to search for
377 	 *
378 	 * Return: the #GstElement with the given
379 	 *     name, or %NULL
380 	 */
381 	public Element getByNameRecurseUp(string name)
382 	{
383 		auto p = gst_bin_get_by_name_recurse_up(gstBin, Str.toStringz(name));
384 		
385 		if(p is null)
386 		{
387 			return null;
388 		}
389 		
390 		return ObjectG.getDObject!(Element)(cast(GstElement*) p, true);
391 	}
392 
393 	/**
394 	 * Return the suppressed flags of the bin.
395 	 *
396 	 * MT safe.
397 	 *
398 	 * Return: the bin's suppressed #GstElementFlags.
399 	 *
400 	 * Since: 1.10
401 	 */
402 	public GstElementFlags getSuppressedFlags()
403 	{
404 		return gst_bin_get_suppressed_flags(gstBin);
405 	}
406 
407 	/**
408 	 * Looks for all elements inside the bin that implements the given
409 	 * interface. You can safely cast all returned elements to the given interface.
410 	 * The function recurses inside child bins. The iterator will yield a series
411 	 * of #GstElement that should be unreffed after use.
412 	 *
413 	 * MT safe.  Caller owns returned value.
414 	 *
415 	 * Params:
416 	 *     iface = the #GType of an interface
417 	 *
418 	 * Return: a #GstIterator of #GstElement
419 	 *     for all elements in the bin implementing the given interface,
420 	 *     or %NULL
421 	 */
422 	public Iterator iterateAllByInterface(GType iface)
423 	{
424 		auto p = gst_bin_iterate_all_by_interface(gstBin, iface);
425 		
426 		if(p is null)
427 		{
428 			return null;
429 		}
430 		
431 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
432 	}
433 
434 	/**
435 	 * Gets an iterator for the elements in this bin.
436 	 *
437 	 * MT safe.  Caller owns returned value.
438 	 *
439 	 * Return: a #GstIterator of #GstElement,
440 	 *     or %NULL
441 	 */
442 	public Iterator iterateElements()
443 	{
444 		auto p = gst_bin_iterate_elements(gstBin);
445 		
446 		if(p is null)
447 		{
448 			return null;
449 		}
450 		
451 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
452 	}
453 
454 	/**
455 	 * Gets an iterator for the elements in this bin.
456 	 * This iterator recurses into GstBin children.
457 	 *
458 	 * MT safe.  Caller owns returned value.
459 	 *
460 	 * Return: a #GstIterator of #GstElement,
461 	 *     or %NULL
462 	 */
463 	public Iterator iterateRecurse()
464 	{
465 		auto p = gst_bin_iterate_recurse(gstBin);
466 		
467 		if(p is null)
468 		{
469 			return null;
470 		}
471 		
472 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
473 	}
474 
475 	/**
476 	 * Gets an iterator for all elements in the bin that have the
477 	 * #GST_ELEMENT_FLAG_SINK flag set.
478 	 *
479 	 * MT safe.  Caller owns returned value.
480 	 *
481 	 * Return: a #GstIterator of #GstElement,
482 	 *     or %NULL
483 	 */
484 	public Iterator iterateSinks()
485 	{
486 		auto p = gst_bin_iterate_sinks(gstBin);
487 		
488 		if(p is null)
489 		{
490 			return null;
491 		}
492 		
493 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
494 	}
495 
496 	/**
497 	 * Gets an iterator for the elements in this bin in topologically
498 	 * sorted order. This means that the elements are returned from
499 	 * the most downstream elements (sinks) to the sources.
500 	 *
501 	 * This function is used internally to perform the state changes
502 	 * of the bin elements and for clock selection.
503 	 *
504 	 * MT safe.  Caller owns returned value.
505 	 *
506 	 * Return: a #GstIterator of #GstElement,
507 	 *     or %NULL
508 	 */
509 	public Iterator iterateSorted()
510 	{
511 		auto p = gst_bin_iterate_sorted(gstBin);
512 		
513 		if(p is null)
514 		{
515 			return null;
516 		}
517 		
518 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
519 	}
520 
521 	/**
522 	 * Gets an iterator for all elements in the bin that have the
523 	 * #GST_ELEMENT_FLAG_SOURCE flag set.
524 	 *
525 	 * MT safe.  Caller owns returned value.
526 	 *
527 	 * Return: a #GstIterator of #GstElement,
528 	 *     or %NULL
529 	 */
530 	public Iterator iterateSources()
531 	{
532 		auto p = gst_bin_iterate_sources(gstBin);
533 		
534 		if(p is null)
535 		{
536 			return null;
537 		}
538 		
539 		return ObjectG.getDObject!(Iterator)(cast(GstIterator*) p, true);
540 	}
541 
542 	/**
543 	 * Query @bin for the current latency using and reconfigures this latency to all the
544 	 * elements with a LATENCY event.
545 	 *
546 	 * This method is typically called on the pipeline when a #GST_MESSAGE_LATENCY
547 	 * is posted on the bus.
548 	 *
549 	 * This function simply emits the 'do-latency' signal so any custom latency
550 	 * calculations will be performed.
551 	 *
552 	 * Return: %TRUE if the latency could be queried and reconfigured.
553 	 */
554 	public bool recalculateLatency()
555 	{
556 		return gst_bin_recalculate_latency(gstBin) != 0;
557 	}
558 
559 	/**
560 	 * Removes the element from the bin, unparenting it as well.
561 	 * Unparenting the element means that the element will be dereferenced,
562 	 * so if the bin holds the only reference to the element, the element
563 	 * will be freed in the process of removing it from the bin.  If you
564 	 * want the element to still exist after removing, you need to call
565 	 * gst_object_ref() before removing it from the bin.
566 	 *
567 	 * If the element's pads are linked to other pads, the pads will be unlinked
568 	 * before the element is removed from the bin.
569 	 *
570 	 * MT safe.
571 	 *
572 	 * Params:
573 	 *     element = the #GstElement to remove
574 	 *
575 	 * Return: %TRUE if the element could be removed, %FALSE if
576 	 *     the bin does not want to remove the element.
577 	 */
578 	public bool remove(Element element)
579 	{
580 		return gst_bin_remove(gstBin, (element is null) ? null : element.getElementStruct()) != 0;
581 	}
582 
583 	/**
584 	 * Suppress the given flags on the bin. #GstElementFlags of a
585 	 * child element are propagated when it is added to the bin.
586 	 * When suppressed flags are set, those specified flags will
587 	 * not be propagated to the bin.
588 	 *
589 	 * MT safe.
590 	 *
591 	 * Params:
592 	 *     flags = the #GstElementFlags to suppress
593 	 *
594 	 * Since: 1.10
595 	 */
596 	public void setSuppressedFlags(GstElementFlags flags)
597 	{
598 		gst_bin_set_suppressed_flags(gstBin, flags);
599 	}
600 
601 	/**
602 	 * Synchronizes the state of every child of @bin with the state
603 	 * of @bin. See also gst_element_sync_state_with_parent().
604 	 *
605 	 * Return: %TRUE if syncing the state was successful for all children,
606 	 *     otherwise %FALSE.
607 	 *
608 	 * Since: 1.6
609 	 */
610 	public bool syncChildrenStates()
611 	{
612 		return gst_bin_sync_children_states(gstBin) != 0;
613 	}
614 
615 	int[string] connectedSignals;
616 
617 	void delegate(Bin, Element, Bin)[] onDeepElementAddedListeners;
618 	/**
619 	 * Will be emitted after the element was added to sub_bin.
620 	 *
621 	 * Params:
622 	 *     subBin = the #GstBin the element was added to
623 	 *     element = the #GstElement that was added to @sub_bin
624 	 *
625 	 * Since: 1.10
626 	 */
627 	void addOnDeepElementAdded(void delegate(Bin, Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
628 	{
629 		if ( "deep-element-added" !in connectedSignals )
630 		{
631 			Signals.connectData(
632 				this,
633 				"deep-element-added",
634 				cast(GCallback)&callBackDeepElementAdded,
635 				cast(void*)this,
636 				null,
637 				connectFlags);
638 			connectedSignals["deep-element-added"] = 1;
639 		}
640 		onDeepElementAddedListeners ~= dlg;
641 	}
642 	extern(C) static void callBackDeepElementAdded(GstBin* binStruct, GstBin* subBin, GstElement* element, Bin _bin)
643 	{
644 		foreach ( void delegate(Bin, Element, Bin) dlg; _bin.onDeepElementAddedListeners )
645 		{
646 			dlg(ObjectG.getDObject!(Bin)(subBin), ObjectG.getDObject!(Element)(element), _bin);
647 		}
648 	}
649 
650 	void delegate(Bin, Element, Bin)[] onDeepElementRemovedListeners;
651 	/**
652 	 * Will be emitted after the element was removed from sub_bin.
653 	 *
654 	 * Params:
655 	 *     subBin = the #GstBin the element was removed from
656 	 *     element = the #GstElement that was removed from @sub_bin
657 	 *
658 	 * Since: 1.10
659 	 */
660 	void addOnDeepElementRemoved(void delegate(Bin, Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
661 	{
662 		if ( "deep-element-removed" !in connectedSignals )
663 		{
664 			Signals.connectData(
665 				this,
666 				"deep-element-removed",
667 				cast(GCallback)&callBackDeepElementRemoved,
668 				cast(void*)this,
669 				null,
670 				connectFlags);
671 			connectedSignals["deep-element-removed"] = 1;
672 		}
673 		onDeepElementRemovedListeners ~= dlg;
674 	}
675 	extern(C) static void callBackDeepElementRemoved(GstBin* binStruct, GstBin* subBin, GstElement* element, Bin _bin)
676 	{
677 		foreach ( void delegate(Bin, Element, Bin) dlg; _bin.onDeepElementRemovedListeners )
678 		{
679 			dlg(ObjectG.getDObject!(Bin)(subBin), ObjectG.getDObject!(Element)(element), _bin);
680 		}
681 	}
682 
683 	bool delegate(Bin)[] onDoLatencyListeners;
684 	/**
685 	 * Will be emitted when the bin needs to perform latency calculations. This
686 	 * signal is only emitted for toplevel bins or when async-handling is
687 	 * enabled.
688 	 *
689 	 * Only one signal handler is invoked. If no signals are connected, the
690 	 * default handler is invoked, which will query and distribute the lowest
691 	 * possible latency to all sinks.
692 	 *
693 	 * Connect to this signal if the default latency calculations are not
694 	 * sufficient, like when you need different latencies for different sinks in
695 	 * the same pipeline.
696 	 */
697 	void addOnDoLatency(bool delegate(Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
698 	{
699 		if ( "do-latency" !in connectedSignals )
700 		{
701 			Signals.connectData(
702 				this,
703 				"do-latency",
704 				cast(GCallback)&callBackDoLatency,
705 				cast(void*)this,
706 				null,
707 				connectFlags);
708 			connectedSignals["do-latency"] = 1;
709 		}
710 		onDoLatencyListeners ~= dlg;
711 	}
712 	extern(C) static int callBackDoLatency(GstBin* binStruct, Bin _bin)
713 	{
714 		foreach ( bool delegate(Bin) dlg; _bin.onDoLatencyListeners )
715 		{
716 			if ( dlg(_bin) )
717 			{
718 				return 1;
719 			}
720 		}
721 		
722 		return 0;
723 	}
724 
725 	void delegate(Element, Bin)[] onElementAddedListeners;
726 	/**
727 	 * Will be emitted after the element was added to the bin.
728 	 *
729 	 * Params:
730 	 *     element = the #GstElement that was added to the bin
731 	 */
732 	void addOnElementAdded(void delegate(Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
733 	{
734 		if ( "element-added" !in connectedSignals )
735 		{
736 			Signals.connectData(
737 				this,
738 				"element-added",
739 				cast(GCallback)&callBackElementAdded,
740 				cast(void*)this,
741 				null,
742 				connectFlags);
743 			connectedSignals["element-added"] = 1;
744 		}
745 		onElementAddedListeners ~= dlg;
746 	}
747 	extern(C) static void callBackElementAdded(GstBin* binStruct, GstElement* element, Bin _bin)
748 	{
749 		foreach ( void delegate(Element, Bin) dlg; _bin.onElementAddedListeners )
750 		{
751 			dlg(ObjectG.getDObject!(Element)(element), _bin);
752 		}
753 	}
754 
755 	void delegate(Element, Bin)[] onElementRemovedListeners;
756 	/**
757 	 * Will be emitted after the element was removed from the bin.
758 	 *
759 	 * Params:
760 	 *     element = the #GstElement that was removed from the bin
761 	 */
762 	void addOnElementRemoved(void delegate(Element, Bin) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
763 	{
764 		if ( "element-removed" !in connectedSignals )
765 		{
766 			Signals.connectData(
767 				this,
768 				"element-removed",
769 				cast(GCallback)&callBackElementRemoved,
770 				cast(void*)this,
771 				null,
772 				connectFlags);
773 			connectedSignals["element-removed"] = 1;
774 		}
775 		onElementRemovedListeners ~= dlg;
776 	}
777 	extern(C) static void callBackElementRemoved(GstBin* binStruct, GstElement* element, Bin _bin)
778 	{
779 		foreach ( void delegate(Element, Bin) dlg; _bin.onElementRemovedListeners )
780 		{
781 			dlg(ObjectG.getDObject!(Element)(element), _bin);
782 		}
783 	}
784 }