clapper: reactable: Add timeline insert/remove functions

Similar to queue alternation functions present in reactable, also
add ones for timeline alternations as these are a must for non-newly
created items.

For consistency, remove auto thread switching logic from insert/remove
functions in ClapperTimeline object. Such behavior is unexpected and
I feel it could lead to potential issues such as deadlocks.
This commit is contained in:
Rafał Dzięgiel
2025-12-06 15:48:20 +01:00
parent e1d635e6dd
commit c3533ddec2
5 changed files with 80 additions and 43 deletions

View File

@@ -206,3 +206,55 @@ clapper_reactable_queue_clear_sync (ClapperReactable *self)
clapper_utils_queue_clear_on_main_sync (queue);
});
}
/**
* clapper_reactable_timeline_insert_sync:
* @reactable: a #ClapperReactable
* @timeline: a #ClapperTimeline
* @marker: a #ClapperMarker
*
* A convenience function that within application main thread synchronously
* inserts @marker into @timeline.
*
* Reactable enhancers should only modify timeline of an item that is already
* in queue from the application main thread, switching thread either themselves
* or using this convenience function that does so.
*
* Since: 0.10
*/
void
clapper_reactable_timeline_insert_sync (ClapperReactable *self,
ClapperTimeline *timeline, ClapperMarker *marker)
{
g_return_if_fail (CLAPPER_IS_REACTABLE (self));
g_return_if_fail (CLAPPER_IS_TIMELINE (timeline));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
clapper_utils_timeline_insert_on_main_sync (timeline, marker);
}
/**
* clapper_reactable_timeline_remove_sync:
* @reactable: a #ClapperReactable
* @timeline: a #ClapperTimeline
* @marker: a #ClapperMarker
*
* A convenience function that within application main thread synchronously
* removes @marker from @timeline.
*
* Reactable enhancers should only modify timeline of an item that is already
* in queue from the application main thread, switching thread either themselves
* or using this convenience function that does so.
*
* Since: 0.10
*/
void
clapper_reactable_timeline_remove_sync (ClapperReactable *self,
ClapperTimeline *timeline, ClapperMarker *marker)
{
g_return_if_fail (CLAPPER_IS_REACTABLE (self));
g_return_if_fail (CLAPPER_IS_TIMELINE (timeline));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
clapper_utils_timeline_remove_on_main_sync (timeline, marker);
}

View File

@@ -28,6 +28,9 @@
#include <clapper/clapper-visibility.h>
#include <clapper/clapper-player.h>
#include <clapper/clapper-media-item.h>
#include <clapper/clapper-timeline.h>
#include <clapper/clapper-marker.h>
#include <clapper/clapper-enums.h>
G_BEGIN_DECLS
@@ -237,4 +240,10 @@ void clapper_reactable_queue_remove_sync (ClapperReactable *reactable, ClapperMe
CLAPPER_API
void clapper_reactable_queue_clear_sync (ClapperReactable *reactable);
CLAPPER_API
void clapper_reactable_timeline_insert_sync (ClapperReactable *reactable, ClapperTimeline *timeline, ClapperMarker *marker);
CLAPPER_API
void clapper_reactable_timeline_remove_sync (ClapperReactable *reactable, ClapperTimeline *timeline, ClapperMarker *marker);
G_END_DECLS

View File

@@ -34,10 +34,4 @@ gboolean clapper_timeline_set_toc (ClapperTimeline *timeline, GstToc *toc, gbool
G_GNUC_INTERNAL
void clapper_timeline_refresh (ClapperTimeline *timeline);
G_GNUC_INTERNAL
void clapper_timeline_insert_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker);
G_GNUC_INTERNAL
void clapper_timeline_remove_marker_internal (ClapperTimeline *timeline, ClapperMarker *marker);
G_END_DECLS

View File

@@ -188,12 +188,22 @@ _take_marker_unlocked (ClapperTimeline *self, ClapperMarker *marker)
return g_sequence_iter_get_position (iter);
}
/**
* clapper_timeline_insert_marker:
* @timeline: a #ClapperTimeline
* @marker: a #ClapperMarker
*
* Insert the #ClapperMarker into @timeline.
*/
void
clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *marker)
clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
{
gboolean success;
gint position = 0;
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
GST_OBJECT_LOCK (self);
if ((success = !g_sequence_lookup (self->markers_seq, marker,
@@ -211,31 +221,22 @@ clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *m
}
/**
* clapper_timeline_insert_marker:
* clapper_timeline_remove_marker:
* @timeline: a #ClapperTimeline
* @marker: a #ClapperMarker
*
* Insert the #ClapperMarker into @timeline.
* Removes #ClapperMarker from the timeline if present.
*/
void
clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
{
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
if (g_main_context_is_owner (g_main_context_default ()))
clapper_timeline_insert_marker_internal (self, marker);
else
clapper_utils_timeline_insert_on_main_sync (self, marker);
}
void
clapper_timeline_remove_marker_internal (ClapperTimeline *self, ClapperMarker *marker)
clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
{
GSequenceIter *iter;
gint position = 0;
gboolean success = FALSE;
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
GST_OBJECT_LOCK (self);
if ((iter = g_sequence_lookup (self->markers_seq, marker,
@@ -256,25 +257,6 @@ clapper_timeline_remove_marker_internal (ClapperTimeline *self, ClapperMarker *m
}
}
/**
* clapper_timeline_remove_marker:
* @timeline: a #ClapperTimeline
* @marker: a #ClapperMarker
*
* Removes #ClapperMarker from the timeline if present.
*/
void
clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
{
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
g_return_if_fail (CLAPPER_IS_MARKER (marker));
if (g_main_context_is_owner (g_main_context_default ()))
clapper_timeline_remove_marker_internal (self, marker);
else
clapper_utils_timeline_remove_on_main_sync (self, marker);
}
/**
* clapper_timeline_get_marker:
* @timeline: a #ClapperTimeline

View File

@@ -136,11 +136,11 @@ clapper_utils_list_alter_on_main (ClapperUtilsListAlterData *data)
clapper_queue_clear (CLAPPER_QUEUE_CAST (data->list));
break;
case CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT:
clapper_timeline_insert_marker_internal (CLAPPER_TIMELINE_CAST (data->list),
clapper_timeline_insert_marker (CLAPPER_TIMELINE_CAST (data->list),
CLAPPER_MARKER_CAST (data->item));
break;
case CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE:
clapper_timeline_remove_marker_internal (CLAPPER_TIMELINE_CAST (data->list),
clapper_timeline_remove_marker (CLAPPER_TIMELINE_CAST (data->list),
CLAPPER_MARKER_CAST (data->item));
break;
default: