core/calendar-monitor: Replace signals by callbacks
This should save quite some resources when manipulating events. Signals are relatively expensive, and 2 pointer chases are definitely better than a global lock + FFI stashing + signal manipulation.
This commit is contained in:
@@ -59,6 +59,9 @@ struct _GcalCalendarMonitor
|
|||||||
GcalCalendar *calendar;
|
GcalCalendar *calendar;
|
||||||
gboolean complete;
|
gboolean complete;
|
||||||
|
|
||||||
|
const GcalCalendarMonitorListener *listener;
|
||||||
|
gpointer listener_user_data;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* These fields are only accessed on the monitor thread, and
|
* These fields are only accessed on the monitor thread, and
|
||||||
* never on the main thread.
|
* never on the main thread.
|
||||||
@@ -88,14 +91,6 @@ static gboolean complete_in_idle_cb (gpointer
|
|||||||
|
|
||||||
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
|
G_DEFINE_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, G_TYPE_OBJECT)
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
EVENT_ADDED,
|
|
||||||
EVENT_UPDATED,
|
|
||||||
EVENT_REMOVED,
|
|
||||||
N_SIGNALS,
|
|
||||||
};
|
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
PROP_0,
|
PROP_0,
|
||||||
@@ -104,7 +99,6 @@ enum
|
|||||||
N_PROPS
|
N_PROPS
|
||||||
};
|
};
|
||||||
|
|
||||||
static gulong signals[N_SIGNALS] = { 0, };
|
|
||||||
static GParamSpec *properties [N_PROPS] = { NULL, };
|
static GParamSpec *properties [N_PROPS] = { NULL, };
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -957,6 +951,7 @@ remove_events_outside_range (GcalCalendarMonitor *self,
|
|||||||
GcalRange *range)
|
GcalRange *range)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_remove = NULL;
|
||||||
GHashTableIter iter;
|
GHashTableIter iter;
|
||||||
GcalEvent *event;
|
GcalEvent *event;
|
||||||
|
|
||||||
@@ -964,6 +959,9 @@ remove_events_outside_range (GcalCalendarMonitor *self,
|
|||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
|
|
||||||
|
events_to_remove = g_ptr_array_new_full (g_hash_table_size (self->shared.events),
|
||||||
|
g_object_unref);
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->shared.events);
|
g_hash_table_iter_init (&iter, self->shared.events);
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event))
|
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event))
|
||||||
{
|
{
|
||||||
@@ -972,36 +970,28 @@ remove_events_outside_range (GcalCalendarMonitor *self,
|
|||||||
if (gcal_range_calculate_overlap (range, event_range, NULL) != GCAL_RANGE_NO_OVERLAP)
|
if (gcal_range_calculate_overlap (range, event_range, NULL) != GCAL_RANGE_NO_OVERLAP)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
g_object_ref (event);
|
g_ptr_array_add (events_to_remove, event);
|
||||||
|
g_hash_table_iter_steal (&iter);
|
||||||
g_hash_table_iter_remove (&iter);
|
|
||||||
g_signal_emit (self, signals[EVENT_REMOVED], 0, event);
|
|
||||||
|
|
||||||
g_object_unref (event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_remove->len > 0)
|
||||||
|
self->listener->remove_events (self, events_to_remove, self->listener_user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
remove_all_events (GcalCalendarMonitor *self)
|
remove_all_events (GcalCalendarMonitor *self)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
GHashTableIter iter;
|
g_autoptr (GPtrArray) events_to_remove = NULL;
|
||||||
GcalEvent *event;
|
|
||||||
|
|
||||||
GCAL_TRACE_MSG ("Removing all events from view");
|
GCAL_TRACE_MSG ("Removing all events from view");
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, self->shared.events);
|
events_to_remove = g_hash_table_steal_all_values (self->shared.events);
|
||||||
while (g_hash_table_iter_next (&iter, NULL, (gpointer*) &event))
|
|
||||||
{
|
|
||||||
g_object_ref (event);
|
|
||||||
|
|
||||||
g_hash_table_iter_remove (&iter);
|
if (events_to_remove->len > 0)
|
||||||
g_signal_emit (self, signals[EVENT_REMOVED], 0, event);
|
self->listener->remove_events (self, events_to_remove, self->listener_user_data);
|
||||||
|
|
||||||
g_object_unref (event);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@@ -1026,6 +1016,7 @@ static gboolean
|
|||||||
add_events_to_timeline_in_idle_cb (gpointer user_data)
|
add_events_to_timeline_in_idle_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_add = NULL;
|
||||||
GcalCalendarMonitor *self;
|
GcalCalendarMonitor *self;
|
||||||
GPtrArray *events;
|
GPtrArray *events;
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
@@ -1037,6 +1028,8 @@ add_events_to_timeline_in_idle_cb (gpointer user_data)
|
|||||||
events = idle_data->events;
|
events = idle_data->events;
|
||||||
g_assert (idle_data->event_ids == NULL);
|
g_assert (idle_data->event_ids == NULL);
|
||||||
|
|
||||||
|
events_to_add = g_ptr_array_sized_new (events->len);
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
for (guint i = 0; i < events->len; i++)
|
for (guint i = 0; i < events->len; i++)
|
||||||
{
|
{
|
||||||
@@ -1049,10 +1042,13 @@ add_events_to_timeline_in_idle_cb (gpointer user_data)
|
|||||||
if (!g_hash_table_contains (self->shared.events, uid))
|
if (!g_hash_table_contains (self->shared.events, uid))
|
||||||
{
|
{
|
||||||
g_hash_table_insert (self->shared.events, g_strdup (uid), g_object_ref (event));
|
g_hash_table_insert (self->shared.events, g_strdup (uid), g_object_ref (event));
|
||||||
g_signal_emit (self, signals[EVENT_ADDED], 0, event);
|
g_ptr_array_add (events_to_add, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_add->len > 0)
|
||||||
|
self->listener->add_events (self, events_to_add, self->listener_user_data);
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1060,6 +1056,8 @@ static gboolean
|
|||||||
update_events_in_idle_cb (gpointer user_data)
|
update_events_in_idle_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
|
g_autoptr (GPtrArray) old_events = NULL;
|
||||||
|
g_autoptr (GPtrArray) new_events = NULL;
|
||||||
g_autoptr (GPtrArray) events = NULL;
|
g_autoptr (GPtrArray) events = NULL;
|
||||||
GcalCalendarMonitor *self;
|
GcalCalendarMonitor *self;
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
@@ -1071,26 +1069,36 @@ update_events_in_idle_cb (gpointer user_data)
|
|||||||
events = g_steal_pointer (&idle_data->events);
|
events = g_steal_pointer (&idle_data->events);
|
||||||
g_assert (idle_data->event_ids == NULL);
|
g_assert (idle_data->event_ids == NULL);
|
||||||
|
|
||||||
|
old_events = g_ptr_array_new_full (events->len, g_object_unref);
|
||||||
|
new_events = g_ptr_array_sized_new (events->len);
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
for (guint i = 0; i < events->len; i++)
|
for (guint i = 0; i < events->len; i++)
|
||||||
{
|
{
|
||||||
g_autoptr (GcalEvent) old_event = NULL;
|
g_autoptr (GcalEvent) old_event = NULL;
|
||||||
|
g_autofree gchar *old_event_id = NULL;
|
||||||
GcalEvent *event;
|
GcalEvent *event;
|
||||||
const gchar *event_id;
|
const gchar *event_id;
|
||||||
|
|
||||||
event = g_ptr_array_index (events, i);
|
event = g_ptr_array_index (events, i);
|
||||||
event_id = gcal_event_get_uid (event);
|
event_id = gcal_event_get_uid (event);
|
||||||
|
|
||||||
old_event = g_hash_table_lookup (self->shared.events, event_id);
|
if (g_hash_table_steal_extended (self->shared.events,
|
||||||
if (old_event)
|
event_id,
|
||||||
|
(gpointer*) &old_event_id,
|
||||||
|
(gpointer*) &old_event))
|
||||||
{
|
{
|
||||||
g_object_ref (old_event);
|
|
||||||
|
|
||||||
g_hash_table_insert (self->shared.events, g_strdup (event_id), g_object_ref (event));
|
g_hash_table_insert (self->shared.events, g_strdup (event_id), g_object_ref (event));
|
||||||
g_signal_emit (self, signals[EVENT_UPDATED], 0, old_event, event);
|
g_ptr_array_add (old_events, g_steal_pointer (&old_event));
|
||||||
|
g_ptr_array_add (new_events, event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_assert (old_events->len == new_events->len);
|
||||||
|
|
||||||
|
if (new_events->len > 0)
|
||||||
|
self->listener->update_events (self, old_events, new_events, self->listener_user_data);
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1098,6 +1106,7 @@ static gboolean
|
|||||||
remove_events_from_timeline_in_idle_cb (gpointer user_data)
|
remove_events_from_timeline_in_idle_cb (gpointer user_data)
|
||||||
{
|
{
|
||||||
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
g_autoptr (GRWLockWriterLocker) writer_locker = NULL;
|
||||||
|
g_autoptr (GPtrArray) events_to_remove = NULL;
|
||||||
g_autoptr (GPtrArray) event_ids = NULL;
|
g_autoptr (GPtrArray) event_ids = NULL;
|
||||||
GcalCalendarMonitor *self;
|
GcalCalendarMonitor *self;
|
||||||
IdleData *idle_data;
|
IdleData *idle_data;
|
||||||
@@ -1109,6 +1118,8 @@ remove_events_from_timeline_in_idle_cb (gpointer user_data)
|
|||||||
event_ids = g_steal_pointer (&idle_data->event_ids);
|
event_ids = g_steal_pointer (&idle_data->event_ids);
|
||||||
g_assert (idle_data->events == NULL);
|
g_assert (idle_data->events == NULL);
|
||||||
|
|
||||||
|
events_to_remove = g_ptr_array_new_full (event_ids->len, g_object_unref);
|
||||||
|
|
||||||
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
writer_locker = g_rw_lock_writer_locker_new (&self->shared.lock);
|
||||||
|
|
||||||
for (guint i = 0; i < event_ids->len; i++)
|
for (guint i = 0; i < event_ids->len; i++)
|
||||||
@@ -1121,14 +1132,15 @@ remove_events_from_timeline_in_idle_cb (gpointer user_data)
|
|||||||
|
|
||||||
if (event)
|
if (event)
|
||||||
{
|
{
|
||||||
/* Keep the event alive until the signal is emitted */
|
/* Keep the event alive until the listener process it*/
|
||||||
g_object_ref (event);
|
g_ptr_array_add (events_to_remove, g_object_ref (event));
|
||||||
|
|
||||||
g_hash_table_remove (self->shared.events, event_id);
|
g_hash_table_remove (self->shared.events, event_id);
|
||||||
g_signal_emit (self, signals[EVENT_REMOVED], 0, event);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (events_to_remove->len > 0)
|
||||||
|
self->listener->remove_events (self, events_to_remove, self->listener_user_data);
|
||||||
|
|
||||||
GCAL_RETURN (G_SOURCE_REMOVE);
|
GCAL_RETURN (G_SOURCE_REMOVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1250,31 +1262,6 @@ gcal_calendar_monitor_class_init (GcalCalendarMonitorClass *klass)
|
|||||||
object_class->get_property = gcal_calendar_monitor_get_property;
|
object_class->get_property = gcal_calendar_monitor_get_property;
|
||||||
object_class->set_property = gcal_calendar_monitor_set_property;
|
object_class->set_property = gcal_calendar_monitor_set_property;
|
||||||
|
|
||||||
signals[EVENT_ADDED] = g_signal_new ("event-added",
|
|
||||||
GCAL_TYPE_CALENDAR_MONITOR,
|
|
||||||
G_SIGNAL_RUN_FIRST,
|
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
1,
|
|
||||||
GCAL_TYPE_EVENT);
|
|
||||||
|
|
||||||
signals[EVENT_UPDATED] = g_signal_new ("event-updated",
|
|
||||||
GCAL_TYPE_CALENDAR_MONITOR,
|
|
||||||
G_SIGNAL_RUN_FIRST,
|
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
2,
|
|
||||||
GCAL_TYPE_EVENT,
|
|
||||||
GCAL_TYPE_EVENT);
|
|
||||||
|
|
||||||
signals[EVENT_REMOVED] = g_signal_new ("event-removed",
|
|
||||||
GCAL_TYPE_CALENDAR_MONITOR,
|
|
||||||
G_SIGNAL_RUN_FIRST,
|
|
||||||
0, NULL, NULL, NULL,
|
|
||||||
G_TYPE_NONE,
|
|
||||||
1,
|
|
||||||
GCAL_TYPE_EVENT);
|
|
||||||
|
|
||||||
properties[PROP_CALENDAR] = g_param_spec_object ("calendar",
|
properties[PROP_CALENDAR] = g_param_spec_object ("calendar",
|
||||||
"Calendar",
|
"Calendar",
|
||||||
"Calendar to be monitored",
|
"Calendar to be monitored",
|
||||||
@@ -1304,11 +1291,23 @@ gcal_calendar_monitor_init (GcalCalendarMonitor *self)
|
|||||||
}
|
}
|
||||||
|
|
||||||
GcalCalendarMonitor*
|
GcalCalendarMonitor*
|
||||||
gcal_calendar_monitor_new (GcalCalendar *calendar)
|
gcal_calendar_monitor_new (GcalCalendar *calendar,
|
||||||
|
const GcalCalendarMonitorListener *listener,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
return g_object_new (GCAL_TYPE_CALENDAR_MONITOR,
|
g_autoptr (GcalCalendarMonitor) monitor = NULL;
|
||||||
"calendar", calendar,
|
|
||||||
NULL);
|
g_assert (calendar != NULL && GCAL_IS_CALENDAR (calendar));
|
||||||
|
g_assert (listener != NULL);
|
||||||
|
|
||||||
|
monitor = g_object_new (GCAL_TYPE_CALENDAR_MONITOR,
|
||||||
|
"calendar", calendar,
|
||||||
|
NULL);
|
||||||
|
|
||||||
|
monitor->listener = listener;
|
||||||
|
monitor->listener_user_data = user_data;
|
||||||
|
|
||||||
|
return g_steal_pointer (&monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -30,7 +30,24 @@ G_BEGIN_DECLS
|
|||||||
#define GCAL_TYPE_CALENDAR_MONITOR (gcal_calendar_monitor_get_type())
|
#define GCAL_TYPE_CALENDAR_MONITOR (gcal_calendar_monitor_get_type())
|
||||||
G_DECLARE_FINAL_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, GCAL, CALENDAR_MONITOR, GObject)
|
G_DECLARE_FINAL_TYPE (GcalCalendarMonitor, gcal_calendar_monitor, GCAL, CALENDAR_MONITOR, GObject)
|
||||||
|
|
||||||
GcalCalendarMonitor* gcal_calendar_monitor_new (GcalCalendar *calendar);
|
typedef struct {
|
||||||
|
void (*add_events) (GcalCalendarMonitor *self,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
void (*update_events) (GcalCalendarMonitor *self,
|
||||||
|
GPtrArray *old_events,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
|
void (*remove_events) (GcalCalendarMonitor *self,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data);
|
||||||
|
} GcalCalendarMonitorListener;
|
||||||
|
|
||||||
|
GcalCalendarMonitor* gcal_calendar_monitor_new (GcalCalendar *calendar,
|
||||||
|
const GcalCalendarMonitorListener *listener,
|
||||||
|
gpointer user_data);
|
||||||
|
|
||||||
void gcal_calendar_monitor_set_range (GcalCalendarMonitor *self,
|
void gcal_calendar_monitor_set_range (GcalCalendarMonitor *self,
|
||||||
GcalRange *range);
|
GcalRange *range);
|
||||||
|
|||||||
+125
-90
@@ -473,97 +473,135 @@ update_calendar_monitor_filters (GcalTimeline *self)
|
|||||||
gcal_calendar_monitor_set_filter (monitor, self->filter);
|
gcal_calendar_monitor_set_filter (monitor, self->filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GcalCalendarMonitorListener events
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
calendar_monitor_add_events_cb (GcalCalendarMonitor *monitor,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GcalTimeline *self;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
self = GCAL_TIMELINE (user_data);
|
||||||
|
|
||||||
|
for (guint i = 0; i < events->len; i++)
|
||||||
|
{
|
||||||
|
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
||||||
|
GcalRange *event_range;
|
||||||
|
GcalEvent *event;
|
||||||
|
|
||||||
|
event = g_ptr_array_index (events, i);
|
||||||
|
event_range = gcal_event_get_range (event);
|
||||||
|
|
||||||
|
/* Add to all subscribers within the event range */
|
||||||
|
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
||||||
|
|
||||||
|
queue_event_data (self, ADD_EVENT, NULL, event, NULL, TRUE);
|
||||||
|
|
||||||
|
for (guint j = 0; subscribers_at_range && j < subscribers_at_range->len; j++)
|
||||||
|
{
|
||||||
|
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, j);
|
||||||
|
|
||||||
|
queue_event_data (self, ADD_EVENT, subscriber, event, NULL, FALSE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
calendar_monitor_update_events_cb (GcalCalendarMonitor *monitor,
|
||||||
|
GPtrArray *old_events,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GcalTimeline *self;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
g_assert (old_events->len == events->len);
|
||||||
|
|
||||||
|
self = GCAL_TIMELINE (user_data);
|
||||||
|
|
||||||
|
for (guint i = 0; i < events->len; i++)
|
||||||
|
{
|
||||||
|
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
||||||
|
GcalRange *event_range;
|
||||||
|
GcalEvent *old_event;
|
||||||
|
GcalEvent *event;
|
||||||
|
|
||||||
|
event = g_ptr_array_index (events, i);
|
||||||
|
old_event = g_ptr_array_index (old_events, i);
|
||||||
|
event_range = gcal_event_get_range (event);
|
||||||
|
|
||||||
|
/* Add to all subscribers within the event range */
|
||||||
|
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
||||||
|
|
||||||
|
queue_event_data (self, UPDATE_EVENT, NULL, event, old_event, TRUE);
|
||||||
|
|
||||||
|
for (guint j = 0; subscribers_at_range && j < subscribers_at_range->len; j++)
|
||||||
|
{
|
||||||
|
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, j);
|
||||||
|
|
||||||
|
queue_event_data (self, UPDATE_EVENT, subscriber, event, old_event, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
calendar_monitor_remove_events_cb (GcalCalendarMonitor *monitor,
|
||||||
|
GPtrArray *events,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GcalTimeline *self;
|
||||||
|
|
||||||
|
GCAL_ENTRY;
|
||||||
|
|
||||||
|
self = GCAL_TIMELINE (user_data);
|
||||||
|
|
||||||
|
for (guint i = 0; i < events->len; i++)
|
||||||
|
{
|
||||||
|
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
||||||
|
GcalRange *event_range;
|
||||||
|
GcalEvent *event;
|
||||||
|
|
||||||
|
event = g_ptr_array_index (events, i);
|
||||||
|
event_range = gcal_event_get_range (event);
|
||||||
|
|
||||||
|
/* Add to all subscribers within the event range */
|
||||||
|
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
||||||
|
|
||||||
|
for (guint j = 0; subscribers_at_range && j < subscribers_at_range->len; j++)
|
||||||
|
{
|
||||||
|
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, j);
|
||||||
|
|
||||||
|
queue_event_data (self, REMOVE_EVENT, subscriber, event, NULL, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
queue_event_data (self, REMOVE_EVENT, NULL, event, NULL, TRUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
GCAL_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GcalCalendarMonitorListener monitor_listener = {
|
||||||
|
calendar_monitor_add_events_cb,
|
||||||
|
calendar_monitor_update_events_cb,
|
||||||
|
calendar_monitor_remove_events_cb,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Callbacks
|
* Callbacks
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void
|
|
||||||
on_calendar_monitor_event_added_cb (GcalCalendarMonitor *monitor,
|
|
||||||
GcalEvent *event,
|
|
||||||
GcalTimeline *self)
|
|
||||||
{
|
|
||||||
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
|
||||||
GcalRange *event_range;
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
event_range = gcal_event_get_range (event);
|
|
||||||
|
|
||||||
/* Add to all subscribers within the event range */
|
|
||||||
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
|
||||||
|
|
||||||
queue_event_data (self, ADD_EVENT, NULL, event, NULL, TRUE);
|
|
||||||
|
|
||||||
for (i = 0; subscribers_at_range && i < subscribers_at_range->len; i++)
|
|
||||||
{
|
|
||||||
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, i);
|
|
||||||
|
|
||||||
queue_event_data (self, ADD_EVENT, subscriber, event, NULL, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_calendar_monitor_event_updated_cb (GcalCalendarMonitor *monitor,
|
|
||||||
GcalEvent *old_event,
|
|
||||||
GcalEvent *event,
|
|
||||||
GcalTimeline *self)
|
|
||||||
{
|
|
||||||
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
|
||||||
GcalRange *event_range;
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
/* Add the updated event to the (potentially new) range */
|
|
||||||
event_range = gcal_event_get_range (event);
|
|
||||||
|
|
||||||
/* Add to all subscribers within the event range */
|
|
||||||
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
|
||||||
|
|
||||||
queue_event_data (self, UPDATE_EVENT, NULL, event, old_event, TRUE);
|
|
||||||
|
|
||||||
for (i = 0; subscribers_at_range && i < subscribers_at_range->len; i++)
|
|
||||||
{
|
|
||||||
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, i);
|
|
||||||
|
|
||||||
queue_event_data (self, UPDATE_EVENT, subscriber, event, old_event, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_calendar_monitor_event_removed_cb (GcalCalendarMonitor *monitor,
|
|
||||||
GcalEvent *event,
|
|
||||||
GcalTimeline *self)
|
|
||||||
{
|
|
||||||
g_autoptr (GPtrArray) subscribers_at_range = NULL;
|
|
||||||
GcalRange *event_range;
|
|
||||||
gint i;
|
|
||||||
|
|
||||||
GCAL_ENTRY;
|
|
||||||
|
|
||||||
event_range = gcal_event_get_range (event);
|
|
||||||
|
|
||||||
/* Add to all subscribers within the event range */
|
|
||||||
subscribers_at_range = gcal_range_tree_get_data_at_range (self->subscriber_ranges, event_range);
|
|
||||||
|
|
||||||
for (i = 0; subscribers_at_range && i < subscribers_at_range->len; i++)
|
|
||||||
{
|
|
||||||
GcalTimelineSubscriber *subscriber = g_ptr_array_index (subscribers_at_range, i);
|
|
||||||
|
|
||||||
queue_event_data (self, REMOVE_EVENT, subscriber, event, NULL, FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
queue_event_data (self, REMOVE_EVENT, NULL, event, NULL, TRUE);
|
|
||||||
|
|
||||||
GCAL_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_calendar_monitor_completed_cb (GcalCalendarMonitor *monitor,
|
on_calendar_monitor_completed_cb (GcalCalendarMonitor *monitor,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
@@ -933,10 +971,7 @@ gcal_timeline_add_calendar (GcalTimeline *self,
|
|||||||
|
|
||||||
GCAL_TRACE_MSG ("Adding calendar '%s' to timeline %p", gcal_calendar_get_name (calendar), self);
|
GCAL_TRACE_MSG ("Adding calendar '%s' to timeline %p", gcal_calendar_get_name (calendar), self);
|
||||||
|
|
||||||
monitor = gcal_calendar_monitor_new (calendar);
|
monitor = gcal_calendar_monitor_new (calendar, &monitor_listener, self);
|
||||||
g_signal_connect (monitor, "event-added", G_CALLBACK (on_calendar_monitor_event_added_cb), self);
|
|
||||||
g_signal_connect (monitor, "event-updated", G_CALLBACK (on_calendar_monitor_event_updated_cb), self);
|
|
||||||
g_signal_connect (monitor, "event-removed", G_CALLBACK (on_calendar_monitor_event_removed_cb), self);
|
|
||||||
g_signal_connect (monitor, "notify::complete", G_CALLBACK (on_calendar_monitor_completed_cb), self);
|
g_signal_connect (monitor, "notify::complete", G_CALLBACK (on_calendar_monitor_completed_cb), self);
|
||||||
g_hash_table_insert (self->calendars, calendar, g_object_ref (monitor));
|
g_hash_table_insert (self->calendars, calendar, g_object_ref (monitor));
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user