[libshumate] network-tile-source: Reorder async callbacks
- From: Marcus Lundblad <mlundblad src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate] network-tile-source: Reorder async callbacks
- Date: Sat, 17 Apr 2021 21:35:02 +0000 (UTC)
commit f6d4e8f712f11993f579a37ffd7ee510866ecdf0
Author: James Westman <james jwestman net>
Date: Thu Apr 8 00:31:57 2021 -0500
network-tile-source: Reorder async callbacks
fill_tile_async() is a pretty complicated async function, so it's helpful to
put all the callbacks in the order they are called.
shumate/shumate-network-tile-source.c | 305 +++++++++++++++++-----------------
1 file changed, 150 insertions(+), 155 deletions(-)
---
diff --git a/shumate/shumate-network-tile-source.c b/shumate/shumate-network-tile-source.c
index 94d7870..2b41e12 100644
--- a/shumate/shumate-network-tile-source.c
+++ b/shumate/shumate-network-tile-source.c
@@ -82,28 +82,6 @@ G_DEFINE_TYPE_WITH_PRIVATE (ShumateNetworkTileSource, shumate_network_tile_sourc
#define MAX_CONNS_DEFAULT 2
-typedef struct {
- ShumateNetworkTileSource *self;
- ShumateTile *tile;
- GBytes *bytes;
- char *etag;
- SoupMessage *msg;
- GDateTime *modtime;
-} FillTileData;
-
-static void
-fill_tile_data_free (FillTileData *data)
-{
- g_clear_object (&data->self);
- g_clear_object (&data->tile);
- g_clear_pointer (&data->bytes, g_bytes_unref);
- g_clear_pointer (&data->etag, g_free);
- g_clear_object (&data->msg);
- g_clear_pointer (&data->modtime, g_date_time_unref);
- g_free (data);
-}
-
-
static void fill_tile_async (ShumateMapSource *map_source,
ShumateTile *tile,
GCancellable *cancellable,
@@ -669,149 +647,42 @@ get_tile_uri (ShumateNetworkTileSource *tile_source,
return token;
}
+static void on_file_cache_get_tile (GObject *source_object, GAsyncResult *res, gpointer user_data);
+static void on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data);
static void fetch_from_network (GTask *task);
+static void on_message_sent (GObject *source_object, GAsyncResult *res, gpointer user_data);
+static void on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data);
-static gboolean
-tile_is_expired (GDateTime *modified_time)
-{
- g_autoptr(GDateTime) now = g_date_time_new_now_utc ();
- GTimeSpan diff = g_date_time_difference (now, modified_time);
-
- return diff > 7 * G_TIME_SPAN_DAY; /* Cache expires in 7 days */
-}
-
-
-/* Fill the tile from the pixbuf, created from the network response. Begin
- * storing the data in the cache (but don't wait for that to finish). Then
- * return. */
-static void
-on_pixbuf_created (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
-{
- g_autoptr(GTask) task = user_data;
- FillTileData *data = g_task_get_task_data (task);
- ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (data->self);
- GCancellable *cancellable = g_task_get_cancellable (task);
- GError *error = NULL;
- g_autoptr(GdkPixbuf) pixbuf = NULL;
- g_autoptr(GdkTexture) texture = NULL;
- g_autofree char *buffer = NULL;
- gsize buffer_size;
-
- pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
- if (error != NULL)
- {
- g_task_return_error (task, error);
- return;
- }
-
- if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &buffer_size, "png", &error, NULL))
- {
- g_warning ("Unable to export tile: %s", error->message);
- g_clear_pointer (&error, g_error_free);
- }
- else
- {
- g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&buffer), buffer_size);
- shumate_file_cache_store_tile_async (priv->file_cache, data->tile, bytes, data->etag, cancellable,
NULL, NULL);
- }
-
- texture = gdk_texture_new_for_pixbuf (pixbuf);
- shumate_tile_set_texture (data->tile, texture);
- shumate_tile_set_fade_in (data->tile, TRUE);
-
- shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
- g_task_return_boolean (task, TRUE);
-}
+typedef struct {
+ ShumateNetworkTileSource *self;
+ ShumateTile *tile;
+ GBytes *bytes;
+ char *etag;
+ SoupMessage *msg;
+ GDateTime *modtime;
+} FillTileData;
-/* Fill the tile from the pixbuf, created from the cache. Then, if the cache
- * data is potentially out of date, fetch from the network. */
static void
-on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data)
+fill_tile_data_free (FillTileData *data)
{
- g_autoptr(GTask) task = user_data;
- FillTileData *data = g_task_get_task_data (task);
- g_autoptr(GdkTexture) texture = NULL;
- g_autoptr(GdkPixbuf) pixbuf = NULL;
- GError *error = NULL;
-
- pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
-
- if (error != NULL)
- {
- g_task_return_error (task, error);
- return;
- }
-
- texture = gdk_texture_new_for_pixbuf (pixbuf);
- shumate_tile_set_texture (data->tile, texture);
- shumate_tile_set_fade_in (data->tile, TRUE);
-
- if (data->bytes != NULL && !tile_is_expired (data->modtime))
- {
- shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
- g_task_return_boolean (task, TRUE);
- }
- else
- fetch_from_network (task);
+ g_clear_object (&data->self);
+ g_clear_object (&data->tile);
+ g_clear_pointer (&data->bytes, g_bytes_unref);
+ g_clear_pointer (&data->etag, g_free);
+ g_clear_object (&data->msg);
+ g_clear_pointer (&data->modtime, g_date_time_unref);
+ g_free (data);
}
-
-/* Receive the response from the network. If the tile hasn't been modified,
- * return; otherwise, parse the data into a pixbuf. */
-static void
-on_message_sent (GObject *source_object,
- GAsyncResult *res,
- gpointer user_data)
+static gboolean
+tile_is_expired (GDateTime *modified_time)
{
- g_autoptr(GTask) task = user_data;
- FillTileData *data = g_task_get_task_data (task);
- GCancellable *cancellable = g_task_get_cancellable (task);
- g_autoptr(GInputStream) input_stream = NULL;
- GError *error = NULL;
- ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (data->self);
-
- input_stream = soup_session_send_finish (priv->soup_session, res, &error);
- if (error != NULL)
- {
- g_task_return_error (task, error);
- return;
- }
-
- DEBUG ("Got reply %d", data->msg->status_code);
-
- if (data->msg->status_code == SOUP_STATUS_NOT_MODIFIED)
- {
- /* The tile has already been filled from the cache, and the server says
- * it doesn't have a newer one. Just update the cache, mark the tile as
- * DONE, and return. */
-
- shumate_file_cache_mark_up_to_date (priv->file_cache, data->tile);
-
- shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
- g_task_return_boolean (task, TRUE);
- return;
- }
-
- if (!SOUP_STATUS_IS_SUCCESSFUL (data->msg->status_code))
- {
- g_task_return_new_error (task, SHUMATE_NETWORK_SOURCE_ERROR,
- SHUMATE_NETWORK_SOURCE_ERROR_BAD_RESPONSE,
- "Unable to download tile: HTTP %s",
- soup_status_get_phrase (data->msg->status_code));
- return;
- }
-
- /* Verify if the server sent an etag and save it */
- g_clear_pointer (&data->etag, g_free);
- data->etag = g_strdup (soup_message_headers_get_one (data->msg->response_headers, "ETag"));
- DEBUG ("Received ETag %s", etag);
+ g_autoptr(GDateTime) now = g_date_time_new_now_utc ();
+ GTimeSpan diff = g_date_time_difference (now, modified_time);
- gdk_pixbuf_new_from_stream_async (input_stream, cancellable, on_pixbuf_created, g_object_ref (task));
+ return diff > 7 * G_TIME_SPAN_DAY; /* Cache expires in 7 days */
}
-
static char *
get_modified_time_string (GDateTime *modified_time)
{
@@ -821,7 +692,6 @@ get_modified_time_string (GDateTime *modified_time)
return g_date_time_format (modified_time, "%a, %d %b %Y %T %Z");
}
-static void on_file_cache_get_tile (GObject *source_object, GAsyncResult *res, gpointer user_data);
static void
fill_tile_async (ShumateMapSource *self,
@@ -884,6 +754,38 @@ on_file_cache_get_tile (GObject *source_object, GAsyncResult *res, gpointer user
}
}
+/* Fill the tile from the pixbuf, created from the cache. Then, if the cache
+ * data is potentially out of date, fetch from the network. */
+static void
+on_pixbuf_created_from_cache (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GTask) task = user_data;
+ FillTileData *data = g_task_get_task_data (task);
+ g_autoptr(GdkTexture) texture = NULL;
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ GError *error = NULL;
+
+ pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
+
+ if (error != NULL)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ texture = gdk_texture_new_for_pixbuf (pixbuf);
+ shumate_tile_set_texture (data->tile, texture);
+ shumate_tile_set_fade_in (data->tile, TRUE);
+
+ if (data->bytes != NULL && !tile_is_expired (data->modtime))
+ {
+ shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
+ g_task_return_boolean (task, TRUE);
+ }
+ else
+ fetch_from_network (task);
+}
+
/* Fetch the tile from the network. */
static void
fetch_from_network (GTask *task)
@@ -931,6 +833,99 @@ fetch_from_network (GTask *task)
soup_session_send_async (priv->soup_session, data->msg, cancellable, on_message_sent, g_object_ref (task));
}
+/* Receive the response from the network. If the tile hasn't been modified,
+ * return; otherwise, parse the data into a pixbuf. */
+static void
+on_message_sent (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GTask) task = user_data;
+ FillTileData *data = g_task_get_task_data (task);
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ g_autoptr(GInputStream) input_stream = NULL;
+ GError *error = NULL;
+ ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (data->self);
+
+ input_stream = soup_session_send_finish (priv->soup_session, res, &error);
+ if (error != NULL)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ DEBUG ("Got reply %d", data->msg->status_code);
+
+ if (data->msg->status_code == SOUP_STATUS_NOT_MODIFIED)
+ {
+ /* The tile has already been filled from the cache, and the server says
+ * it doesn't have a newer one. Just update the cache, mark the tile as
+ * DONE, and return. */
+
+ shumate_file_cache_mark_up_to_date (priv->file_cache, data->tile);
+
+ shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
+ g_task_return_boolean (task, TRUE);
+ return;
+ }
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (data->msg->status_code))
+ {
+ g_task_return_new_error (task, SHUMATE_NETWORK_SOURCE_ERROR,
+ SHUMATE_NETWORK_SOURCE_ERROR_BAD_RESPONSE,
+ "Unable to download tile: HTTP %s",
+ soup_status_get_phrase (data->msg->status_code));
+ return;
+ }
+
+ /* Verify if the server sent an etag and save it */
+ g_clear_pointer (&data->etag, g_free);
+ data->etag = g_strdup (soup_message_headers_get_one (data->msg->response_headers, "ETag"));
+ DEBUG ("Received ETag %s", etag);
+
+ gdk_pixbuf_new_from_stream_async (input_stream, cancellable, on_pixbuf_created, g_object_ref (task));
+}
+
+/* Fill the tile from the pixbuf, created from the network response. Begin
+ * storing the data in the cache (but don't wait for that to finish). Then
+ * return. */
+static void
+on_pixbuf_created (GObject *source_object, GAsyncResult *res, gpointer user_data)
+{
+ g_autoptr(GTask) task = user_data;
+ FillTileData *data = g_task_get_task_data (task);
+ ShumateNetworkTileSourcePrivate *priv = shumate_network_tile_source_get_instance_private (data->self);
+ GCancellable *cancellable = g_task_get_cancellable (task);
+ GError *error = NULL;
+ g_autoptr(GdkPixbuf) pixbuf = NULL;
+ g_autoptr(GdkTexture) texture = NULL;
+ g_autofree char *buffer = NULL;
+ gsize buffer_size;
+
+ pixbuf = gdk_pixbuf_new_from_stream_finish (res, &error);
+ if (error != NULL)
+ {
+ g_task_return_error (task, error);
+ return;
+ }
+
+ if (!gdk_pixbuf_save_to_buffer (pixbuf, &buffer, &buffer_size, "png", &error, NULL))
+ {
+ g_warning ("Unable to export tile: %s", error->message);
+ g_clear_pointer (&error, g_error_free);
+ }
+ else
+ {
+ g_autoptr(GBytes) bytes = g_bytes_new_take (g_steal_pointer (&buffer), buffer_size);
+ shumate_file_cache_store_tile_async (priv->file_cache, data->tile, bytes, data->etag, cancellable,
NULL, NULL);
+ }
+
+ texture = gdk_texture_new_for_pixbuf (pixbuf);
+ shumate_tile_set_texture (data->tile, texture);
+ shumate_tile_set_fade_in (data->tile, TRUE);
+
+ shumate_tile_set_state (data->tile, SHUMATE_STATE_DONE);
+ g_task_return_boolean (task, TRUE);
+}
+
/**
* shumate_network_source_error_quark:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]