mirror of
https://github.com/Rafostar/clapper.git
synced 2025-08-29 23:32:04 +02:00
clapper: Make timeline insert/remove work from any thread
Detect and auto switch thread to main if done from a different one. With this, apps can still continue to implement thread switch and doing multiple insertions/deletions within single main thread invoke or simply call this function from a different thread for convenience.
This commit is contained in:
@@ -34,4 +34,10 @@ gboolean clapper_timeline_set_toc (ClapperTimeline *timeline, GstToc *toc, gbool
|
|||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
void clapper_timeline_refresh (ClapperTimeline *timeline);
|
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
|
G_END_DECLS
|
||||||
|
@@ -30,6 +30,7 @@
|
|||||||
#include "clapper-player-private.h"
|
#include "clapper-player-private.h"
|
||||||
#include "clapper-reactables-manager-private.h"
|
#include "clapper-reactables-manager-private.h"
|
||||||
#include "clapper-features-manager-private.h"
|
#include "clapper-features-manager-private.h"
|
||||||
|
#include "clapper-utils-private.h"
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT clapper_timeline_debug
|
#define GST_CAT_DEFAULT clapper_timeline_debug
|
||||||
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
||||||
@@ -187,25 +188,12 @@ _take_marker_unlocked (ClapperTimeline *self, ClapperMarker *marker)
|
|||||||
return g_sequence_iter_get_position (iter);
|
return g_sequence_iter_get_position (iter);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
void
|
||||||
* clapper_timeline_insert_marker:
|
clapper_timeline_insert_marker_internal (ClapperTimeline *self, ClapperMarker *marker)
|
||||||
* @timeline: a #ClapperTimeline
|
|
||||||
* @marker: a #ClapperMarker
|
|
||||||
*
|
|
||||||
* Insert the #ClapperMarker into @timeline.
|
|
||||||
*
|
|
||||||
* Returns: %TRUE if inserted, %FALSE if marker was
|
|
||||||
* already inserted into timeline.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
|
|
||||||
{
|
{
|
||||||
gboolean success;
|
gboolean success;
|
||||||
gint position = 0;
|
gint position = 0;
|
||||||
|
|
||||||
g_return_val_if_fail (CLAPPER_IS_TIMELINE (self), FALSE);
|
|
||||||
g_return_val_if_fail (CLAPPER_IS_MARKER (marker), FALSE);
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (self);
|
GST_OBJECT_LOCK (self);
|
||||||
|
|
||||||
if ((success = !g_sequence_lookup (self->markers_seq, marker,
|
if ((success = !g_sequence_lookup (self->markers_seq, marker,
|
||||||
@@ -220,30 +208,34 @@ clapper_timeline_insert_marker (ClapperTimeline *self, ClapperMarker *marker)
|
|||||||
|
|
||||||
clapper_timeline_post_item_updated (self);
|
clapper_timeline_post_item_updated (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* clapper_timeline_remove_marker:
|
* clapper_timeline_insert_marker:
|
||||||
* @timeline: a #ClapperTimeline
|
* @timeline: a #ClapperTimeline
|
||||||
* @marker: a #ClapperMarker
|
* @marker: a #ClapperMarker
|
||||||
*
|
*
|
||||||
* Removes #ClapperMarker from the timeline.
|
* Insert the #ClapperMarker into @timeline.
|
||||||
*
|
|
||||||
* If marker was not in the @timeline, this function will do nothing,
|
|
||||||
* so it is safe to call if unsure.
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
|
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)
|
||||||
{
|
{
|
||||||
GSequenceIter *iter;
|
GSequenceIter *iter;
|
||||||
gint position = 0;
|
gint position = 0;
|
||||||
gboolean success = FALSE;
|
gboolean success = FALSE;
|
||||||
|
|
||||||
g_return_if_fail (CLAPPER_IS_TIMELINE (self));
|
|
||||||
g_return_if_fail (CLAPPER_IS_MARKER (marker));
|
|
||||||
|
|
||||||
GST_OBJECT_LOCK (self);
|
GST_OBJECT_LOCK (self);
|
||||||
|
|
||||||
if ((iter = g_sequence_lookup (self->markers_seq, marker,
|
if ((iter = g_sequence_lookup (self->markers_seq, marker,
|
||||||
@@ -264,6 +256,25 @@ clapper_timeline_remove_marker (ClapperTimeline *self, ClapperMarker *marker)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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:
|
* clapper_timeline_get_marker:
|
||||||
* @timeline: a #ClapperTimeline
|
* @timeline: a #ClapperTimeline
|
||||||
|
@@ -38,7 +38,7 @@ CLAPPER_API
|
|||||||
G_DECLARE_FINAL_TYPE (ClapperTimeline, clapper_timeline, CLAPPER, TIMELINE, GstObject)
|
G_DECLARE_FINAL_TYPE (ClapperTimeline, clapper_timeline, CLAPPER, TIMELINE, GstObject)
|
||||||
|
|
||||||
CLAPPER_API
|
CLAPPER_API
|
||||||
gboolean clapper_timeline_insert_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
void clapper_timeline_insert_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||||
|
|
||||||
CLAPPER_API
|
CLAPPER_API
|
||||||
void clapper_timeline_remove_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
void clapper_timeline_remove_marker (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||||
|
@@ -26,6 +26,8 @@
|
|||||||
#include "clapper-utils.h"
|
#include "clapper-utils.h"
|
||||||
#include "clapper-queue.h"
|
#include "clapper-queue.h"
|
||||||
#include "clapper-media-item.h"
|
#include "clapper-media-item.h"
|
||||||
|
#include "clapper-timeline.h"
|
||||||
|
#include "clapper-marker.h"
|
||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@@ -44,6 +46,12 @@ void clapper_utils_queue_remove_on_main_sync (ClapperQueue *queue, ClapperMediaI
|
|||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
void clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue);
|
void clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
void clapper_utils_timeline_insert_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||||
|
|
||||||
|
G_GNUC_INTERNAL
|
||||||
|
void clapper_utils_timeline_remove_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker);
|
||||||
|
|
||||||
G_GNUC_INTERNAL
|
G_GNUC_INTERNAL
|
||||||
void clapper_utils_prop_notify_on_main_sync (GObject *object, GParamSpec *pspec);
|
void clapper_utils_prop_notify_on_main_sync (GObject *object, GParamSpec *pspec);
|
||||||
|
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "clapper-utils-private.h"
|
#include "clapper-utils-private.h"
|
||||||
|
#include "clapper-timeline-private.h"
|
||||||
#include "../shared/clapper-shared-utils-private.h"
|
#include "../shared/clapper-shared-utils-private.h"
|
||||||
|
|
||||||
#define GST_CAT_DEFAULT clapper_utils_debug
|
#define GST_CAT_DEFAULT clapper_utils_debug
|
||||||
@@ -24,19 +25,21 @@ GST_DEBUG_CATEGORY_STATIC (GST_CAT_DEFAULT);
|
|||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
CLAPPER_UTILS_QUEUE_ALTER_APPEND = 1,
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND = 1,
|
||||||
CLAPPER_UTILS_QUEUE_ALTER_INSERT,
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT,
|
||||||
CLAPPER_UTILS_QUEUE_ALTER_REMOVE,
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE,
|
||||||
CLAPPER_UTILS_QUEUE_ALTER_CLEAR
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR,
|
||||||
} ClapperUtilsQueueAlterMethod;
|
CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT,
|
||||||
|
CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE
|
||||||
|
} ClapperUtilsListAlterMethod;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
ClapperQueue *queue;
|
GListModel *list;
|
||||||
ClapperMediaItem *item;
|
GObject *item;
|
||||||
ClapperMediaItem *after_item;
|
GObject *after_item;
|
||||||
ClapperUtilsQueueAlterMethod method;
|
ClapperUtilsListAlterMethod method;
|
||||||
} ClapperUtilsQueueAlterData;
|
} ClapperUtilsListAlterData;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@@ -51,27 +54,26 @@ clapper_utils_initialize (void)
|
|||||||
"Clapper Utilities");
|
"Clapper Utilities");
|
||||||
}
|
}
|
||||||
|
|
||||||
static ClapperUtilsQueueAlterData *
|
static ClapperUtilsListAlterData *
|
||||||
clapper_utils_queue_alter_data_new (ClapperQueue *queue,
|
clapper_utils_list_alter_data_new (GListModel *list, GObject *item,
|
||||||
ClapperMediaItem *item, ClapperMediaItem *after_item,
|
GObject *after_item, ClapperUtilsListAlterMethod method)
|
||||||
ClapperUtilsQueueAlterMethod method)
|
|
||||||
{
|
{
|
||||||
ClapperUtilsQueueAlterData *data = g_new (ClapperUtilsQueueAlterData, 1);
|
ClapperUtilsListAlterData *data = g_new (ClapperUtilsListAlterData, 1);
|
||||||
|
|
||||||
data->queue = queue;
|
data->list = list;
|
||||||
data->item = item;
|
data->item = item;
|
||||||
data->after_item = after_item;
|
data->after_item = after_item;
|
||||||
data->method = method;
|
data->method = method;
|
||||||
|
|
||||||
GST_TRACE ("Created queue alter data: %p", data);
|
GST_TRACE ("Created list alter data: %p", data);
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clapper_utils_queue_alter_data_free (ClapperUtilsQueueAlterData *data)
|
clapper_utils_list_alter_data_free (ClapperUtilsListAlterData *data)
|
||||||
{
|
{
|
||||||
GST_TRACE ("Freeing queue alter data: %p", data);
|
GST_TRACE ("Freeing list alter data: %p", data);
|
||||||
|
|
||||||
g_free (data);
|
g_free (data);
|
||||||
}
|
}
|
||||||
@@ -98,35 +100,48 @@ clapper_utils_prop_notify_data_free (ClapperUtilsPropNotifyData *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static gpointer
|
static gpointer
|
||||||
clapper_utils_queue_alter_on_main (ClapperUtilsQueueAlterData *data)
|
clapper_utils_list_alter_on_main (ClapperUtilsListAlterData *data)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Queue alter invoked");
|
GST_DEBUG ("Queue alter invoked");
|
||||||
|
|
||||||
switch (data->method) {
|
switch (data->method) {
|
||||||
case CLAPPER_UTILS_QUEUE_ALTER_APPEND:
|
case CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND:
|
||||||
clapper_queue_add_item (data->queue, data->item);
|
clapper_queue_add_item (CLAPPER_QUEUE_CAST (data->list),
|
||||||
|
CLAPPER_MEDIA_ITEM_CAST (data->item));
|
||||||
break;
|
break;
|
||||||
case CLAPPER_UTILS_QUEUE_ALTER_INSERT:{
|
case CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT:{
|
||||||
guint index;
|
guint index;
|
||||||
|
|
||||||
/* If we have "after_item" then we need to insert after it, otherwise prepend */
|
/* If we have "after_item" then we need to insert after it, otherwise prepend */
|
||||||
if (data->after_item) {
|
if (data->after_item) {
|
||||||
if (clapper_queue_find_item (data->queue, data->after_item, &index))
|
if (clapper_queue_find_item (CLAPPER_QUEUE_CAST (data->list),
|
||||||
|
CLAPPER_MEDIA_ITEM_CAST (data->after_item), &index)) {
|
||||||
index++;
|
index++;
|
||||||
else // If not found, just append at the end
|
} else {
|
||||||
index = -1;
|
index = -1; // if not found, just append at the end
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
index = 0;
|
index = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clapper_queue_insert_item (data->queue, data->item, index);
|
clapper_queue_insert_item (CLAPPER_QUEUE_CAST (data->list),
|
||||||
|
CLAPPER_MEDIA_ITEM_CAST (data->item), index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CLAPPER_UTILS_QUEUE_ALTER_REMOVE:
|
case CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE:
|
||||||
clapper_queue_remove_item (data->queue, data->item);
|
clapper_queue_remove_item (CLAPPER_QUEUE_CAST (data->list),
|
||||||
|
CLAPPER_MEDIA_ITEM_CAST (data->item));
|
||||||
break;
|
break;
|
||||||
case CLAPPER_UTILS_QUEUE_ALTER_CLEAR:
|
case CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR:
|
||||||
clapper_queue_clear (data->queue);
|
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_MARKER_CAST (data->item));
|
||||||
|
break;
|
||||||
|
case CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE:
|
||||||
|
clapper_timeline_remove_marker_internal (CLAPPER_TIMELINE_CAST (data->list),
|
||||||
|
CLAPPER_MARKER_CAST (data->item));
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
g_assert_not_reached ();
|
g_assert_not_reached ();
|
||||||
@@ -146,13 +161,13 @@ clapper_utils_prop_notify_on_main (ClapperUtilsPropNotifyData *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
clapper_utils_queue_alter_invoke_on_main_sync_take (ClapperUtilsQueueAlterData *data)
|
clapper_utils_list_alter_invoke_on_main_sync_take (ClapperUtilsListAlterData *data)
|
||||||
{
|
{
|
||||||
GST_DEBUG ("Invoking queue alter on main...");
|
GST_DEBUG ("Invoking queue alter on main...");
|
||||||
|
|
||||||
clapper_shared_utils_context_invoke_sync_full (g_main_context_default (),
|
clapper_shared_utils_context_invoke_sync_full (g_main_context_default (),
|
||||||
(GThreadFunc) clapper_utils_queue_alter_on_main, data,
|
(GThreadFunc) clapper_utils_list_alter_on_main, data,
|
||||||
(GDestroyNotify) clapper_utils_queue_alter_data_free);
|
(GDestroyNotify) clapper_utils_list_alter_data_free);
|
||||||
|
|
||||||
GST_DEBUG ("Queue alter invoke finished");
|
GST_DEBUG ("Queue alter invoke finished");
|
||||||
}
|
}
|
||||||
@@ -160,34 +175,56 @@ clapper_utils_queue_alter_invoke_on_main_sync_take (ClapperUtilsQueueAlterData *
|
|||||||
void
|
void
|
||||||
clapper_utils_queue_append_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
|
clapper_utils_queue_append_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
|
||||||
{
|
{
|
||||||
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
item, NULL, CLAPPER_UTILS_QUEUE_ALTER_APPEND);
|
(GListModel *) queue, (GObject *) item, NULL,
|
||||||
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_APPEND);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clapper_utils_queue_insert_on_main_sync (ClapperQueue *queue,
|
clapper_utils_queue_insert_on_main_sync (ClapperQueue *queue,
|
||||||
ClapperMediaItem *item, ClapperMediaItem *after_item)
|
ClapperMediaItem *item, ClapperMediaItem *after_item)
|
||||||
{
|
{
|
||||||
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
item, after_item, CLAPPER_UTILS_QUEUE_ALTER_INSERT);
|
(GListModel *) queue, (GObject *) item, (GObject *) after_item,
|
||||||
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_INSERT);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clapper_utils_queue_remove_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
|
clapper_utils_queue_remove_on_main_sync (ClapperQueue *queue, ClapperMediaItem *item)
|
||||||
{
|
{
|
||||||
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
item, NULL, CLAPPER_UTILS_QUEUE_ALTER_REMOVE);
|
(GListModel *) queue, (GObject *) item, NULL,
|
||||||
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_REMOVE);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue)
|
clapper_utils_queue_clear_on_main_sync (ClapperQueue *queue)
|
||||||
{
|
{
|
||||||
ClapperUtilsQueueAlterData *data = clapper_utils_queue_alter_data_new (queue,
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
NULL, NULL, CLAPPER_UTILS_QUEUE_ALTER_CLEAR);
|
(GListModel *) queue, NULL, NULL,
|
||||||
clapper_utils_queue_alter_invoke_on_main_sync_take (data);
|
CLAPPER_UTILS_LIST_ALTER_QUEUE_CLEAR);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clapper_utils_timeline_insert_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker)
|
||||||
|
{
|
||||||
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
|
(GListModel *) timeline, (GObject *) marker, NULL,
|
||||||
|
CLAPPER_UTILS_LIST_ALTER_TIMELINE_INSERT);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
clapper_utils_timeline_remove_on_main_sync (ClapperTimeline *timeline, ClapperMarker *marker)
|
||||||
|
{
|
||||||
|
ClapperUtilsListAlterData *data = clapper_utils_list_alter_data_new (
|
||||||
|
(GListModel *) timeline, (GObject *) marker, NULL,
|
||||||
|
CLAPPER_UTILS_LIST_ALTER_TIMELINE_REMOVE);
|
||||||
|
clapper_utils_list_alter_invoke_on_main_sync_take (data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
Reference in New Issue
Block a user