Commit e965af7e authored by Christian Hergert's avatar Christian Hergert

buffers: move auto-save into IdeBuffer

It's a bit easier to track this from IdeBuffer, including state
management.
parent b81d3f83
Pipeline #16154 passed with stage
in 17 minutes and 33 seconds
......@@ -65,13 +65,6 @@ struct _IdeBufferManager
guint auto_save : 1;
};
typedef struct
{
IdeBufferManager *self;
IdeBuffer *buffer;
guint source_id;
} AutoSave;
typedef struct
{
IdeBuffer *buffer;
......@@ -131,11 +124,6 @@ enum {
LAST_SIGNAL
};
static void register_auto_save (IdeBufferManager *self,
IdeBuffer *buffer);
static void unregister_auto_save (IdeBufferManager *self,
IdeBuffer *buffer);
static GParamSpec *properties [LAST_PROP];
static guint signals [LAST_SIGNAL];
......@@ -237,8 +225,14 @@ ide_buffer_manager_set_auto_save_timeout (IdeBufferManager *self,
if (self->auto_save_timeout != auto_save_timeout)
{
self->auto_save_timeout = auto_save_timeout;
g_object_notify_by_pspec (G_OBJECT (self),
properties [PROP_AUTO_SAVE_TIMEOUT]);
for (guint i = 0; i < self->buffers->len; i++)
{
IdeBuffer *buffer = g_ptr_array_index (self->buffers, i);
_ide_buffer_set_auto_save (buffer, self->auto_save, auto_save_timeout);
}
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_AUTO_SAVE_TIMEOUT]);
}
}
......@@ -282,24 +276,16 @@ ide_buffer_manager_set_auto_save (IdeBufferManager *self,
if (self->auto_save != auto_save)
{
gsize i;
self->auto_save = auto_save;
for (i = 0; i < self->buffers->len; i++)
for (guint i = 0; i < self->buffers->len; i++)
{
IdeBuffer *buffer;
buffer = g_ptr_array_index (self->buffers, i);
IdeBuffer *buffer = g_ptr_array_index (self->buffers, i);
if (auto_save)
register_auto_save (self, buffer);
else
unregister_auto_save (self, buffer);
_ide_buffer_set_auto_save (buffer, auto_save, self->auto_save_timeout);
}
g_object_notify_by_pspec (G_OBJECT (self),
properties [PROP_AUTO_SAVE]);
g_object_notify_by_pspec (G_OBJECT (self), properties [PROP_AUTO_SAVE]);
}
}
......@@ -346,81 +332,6 @@ ide_buffer_manager_set_focus_buffer (IdeBufferManager *self,
}
}
static gboolean
ide_buffer_manager_auto_save_cb (gpointer data)
{
AutoSave *state = data;
gboolean saved = FALSE;
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (state != NULL);
g_assert (IDE_IS_BUFFER_MANAGER (state->self));
g_assert (IDE_IS_BUFFER (state->buffer));
g_assert (state->source_id > 0);
if (!ide_buffer_get_changed_on_volume (state->buffer))
{
IdeFile *file = ide_buffer_get_file (state->buffer);
if (file != NULL)
{
ide_buffer_manager_save_file_async (state->self,
state->buffer,
file,
NULL,
NULL,
NULL,
NULL);
saved = TRUE;
}
}
if (!saved)
unregister_auto_save (state->self, state->buffer);
return G_SOURCE_REMOVE;
}
static void
ide_buffer_manager_buffer_changed (IdeBufferManager *self,
IdeBuffer *buffer)
{
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_BUFFER_MANAGER (self));
g_return_if_fail (IDE_IS_BUFFER (buffer));
if (self->auto_save)
{
unregister_auto_save (self, buffer);
register_auto_save (self, buffer);
}
}
static void
ide_buffer_manager_track_buffer (IdeBufferManager *self,
IdeBuffer *buffer)
{
IDE_ENTRY;
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_BUFFER_MANAGER (self));
g_assert (IDE_IS_BUFFER (buffer));
if (self->auto_save)
register_auto_save (self, buffer);
g_signal_connect_object (buffer,
"changed",
G_CALLBACK (ide_buffer_manager_buffer_changed),
self,
(G_CONNECT_SWAPPED | G_CONNECT_AFTER));
g_list_model_items_changed (G_LIST_MODEL (self), self->buffers->len - 1, 0, 1);
IDE_EXIT;
}
static void
ide_buffer_manager_save_cursor_position (IdeBufferManager *self,
IdeBuffer *buffer)
......@@ -491,12 +402,6 @@ found:
/* Stealing ownership from self->buffers */
g_ptr_array_remove_index (self->buffers, position);
unregister_auto_save (self, buffer);
g_signal_handlers_disconnect_by_func (buffer,
G_CALLBACK (ide_buffer_manager_buffer_changed),
self);
/*
* Notify anything that needs a pointer to the buffer to cleanup,
* such as language server clients.
......@@ -584,6 +489,7 @@ ide_buffer_manager_load_file__load_cb (GObject *object,
{
g_ptr_array_add (self->buffers, g_object_ref (state->buffer));
DZL_COUNTER_INC (registered);
g_list_model_items_changed (G_LIST_MODEL (self), self->buffers->len - 1, 0, 1);
}
if (!gtk_source_file_loader_load_finish (loader, result, &error))
......@@ -606,9 +512,6 @@ ide_buffer_manager_load_file__load_cb (GObject *object,
gtk_text_buffer_set_modified (GTK_TEXT_BUFFER (state->buffer), FALSE);
if (state->is_new)
ide_buffer_manager_track_buffer (self, state->buffer);
/* try to restore the insertion cursor */
if (g_settings_get_boolean (self->settings, "restore-insert-mark"))
gtk_text_buffer_get_iter_at_line_offset (GTK_TEXT_BUFFER (state->buffer), &iter,
......@@ -641,6 +544,8 @@ ide_buffer_manager_load_file__load_cb (GObject *object,
if (!_ide_context_is_restoring (context))
ide_buffer_manager_set_focus_buffer (self, state->buffer);
_ide_buffer_set_auto_save (state->buffer, self->auto_save, self->auto_save_timeout);
g_signal_emit (self, signals [BUFFER_LOADED], 0, state->buffer);
ide_task_return_pointer (task, g_object_ref (state->buffer), g_object_unref);
......@@ -1251,7 +1156,7 @@ ide_buffer_manager_save_file_async (IdeBufferManager *self,
}
ide_task_return_boolean (task, TRUE);
IDE_GOTO (unmodified);
IDE_EXIT;
}
context = ide_object_get_context (IDE_OBJECT (self));
......@@ -1279,9 +1184,6 @@ ide_buffer_manager_save_file_async (IdeBufferManager *self,
ide_buffer_manager_save_file__load_settings_cb,
g_object_ref (task));
unmodified:
unregister_auto_save (self, buffer);
IDE_EXIT;
}
......@@ -1747,52 +1649,6 @@ ide_buffer_manager_init (IdeBufferManager *self)
g_settings_bind (self->settings, "auto-save-timeout", self, "auto-save-timeout", G_SETTINGS_BIND_GET);
}
static void
register_auto_save (IdeBufferManager *self,
IdeBuffer *buffer)
{
g_return_if_fail (IDE_IS_MAIN_THREAD ());
g_return_if_fail (IDE_IS_BUFFER_MANAGER (self));
g_return_if_fail (IDE_IS_BUFFER (buffer));
g_return_if_fail (!g_hash_table_lookup (self->timeouts, buffer));
g_return_if_fail (self->auto_save_timeout > 0);
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (buffer)))
{
AutoSave *state;
state = g_slice_new0 (AutoSave);
dzl_set_weak_pointer (&state->buffer, buffer);
dzl_set_weak_pointer (&state->self, self);
state->source_id = g_timeout_add_seconds (self->auto_save_timeout,
ide_buffer_manager_auto_save_cb,
state);
g_hash_table_insert (self->timeouts, buffer, state);
}
}
static void
unregister_auto_save (IdeBufferManager *self,
IdeBuffer *buffer)
{
AutoSave *state;
g_assert (IDE_IS_MAIN_THREAD ());
g_assert (IDE_IS_BUFFER_MANAGER (self));
g_assert (IDE_IS_BUFFER (buffer));
state = g_hash_table_lookup (self->timeouts, buffer);
if (state != NULL)
{
g_hash_table_remove (self->timeouts, buffer);
dzl_clear_source (&state->source_id);
dzl_clear_weak_pointer (&state->buffer);
dzl_clear_weak_pointer (&state->self);
g_slice_free (AutoSave, state);
}
}
/**
* ide_buffer_manager_get_buffers:
*
......@@ -1974,7 +1830,7 @@ ide_buffer_manager_create_temporary_buffer (IdeBufferManager *self)
g_ptr_array_add (self->buffers, g_object_ref (buffer));
DZL_COUNTER_INC (registered);
ide_buffer_manager_track_buffer (self, buffer);
g_list_model_items_changed (G_LIST_MODEL (self), self->buffers->len - 1, 0, 1);
g_signal_emit (self, signals [BUFFER_LOADED], 0, buffer);
......
......@@ -41,6 +41,9 @@ void _ide_buffer_set_read_only (IdeBuffer *buffer,
void _ide_buffer_set_failure (IdeBuffer *self,
const GError *error);
IdeHighlightEngine *_ide_buffer_get_highlight_engine (IdeBuffer *self);
void _ide_buffer_set_auto_save (IdeBuffer *self,
gboolean auto_save,
guint auto_save_timeout);
void _ide_buffer_manager_reclaim (IdeBufferManager *self,
IdeBuffer *buffer);
IdeUnsavedFile *_ide_unsaved_file_new (GFile *file,
......
......@@ -107,8 +107,12 @@ typedef struct
guint settling_handler;
guint auto_save_handler;
guint auto_save_timeout;
gsize change_count;
guint auto_save : 1;
guint cancel_cursor_restore : 1;
guint changed_on_volume : 1;
guint highlight_diagnostics : 1;
......@@ -169,6 +173,46 @@ lookup_symbol_task_data_free (LookUpSymbolData *data)
g_slice_free (LookUpSymbolData, data);
}
static gboolean
ide_buffer_auto_save_cb (IdeBuffer *self)
{
IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
IdeBufferManager *bufmgr;
IdeFile *file;
g_assert (IDE_IS_BUFFER (self));
priv->auto_save_handler = 0;
if (priv->context == NULL)
return G_SOURCE_REMOVE;
bufmgr = ide_context_get_buffer_manager (priv->context);
file = ide_buffer_get_file (self);
ide_buffer_manager_save_file_async (bufmgr, self, file, NULL, NULL, NULL, NULL);
return G_SOURCE_REMOVE;
}
static void
ide_buffer_queue_auto_save (IdeBuffer *self)
{
IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
g_assert (IDE_IS_BUFFER (self));
dzl_clear_source (&priv->auto_save_handler);
if (gtk_text_buffer_get_modified (GTK_TEXT_BUFFER (self)))
priv->auto_save_handler =
gdk_threads_add_timeout_seconds_full (G_PRIORITY_DEFAULT,
priv->auto_save_timeout,
(GSourceFunc)ide_buffer_auto_save_cb,
g_object_ref (self),
g_object_unref);
}
static void
lookup_symbol_get_extension (IdeExtensionSetAdapter *set,
PeasPluginInfo *plugin_info,
......@@ -198,6 +242,8 @@ ide_buffer_settled_cb (gpointer user_data)
priv->settling_handler = 0;
g_signal_emit (self, signals [CHANGE_SETTLED], 0);
ide_buffer_queue_auto_save (self);
return G_SOURCE_REMOVE;
}
......@@ -1495,6 +1541,7 @@ ide_buffer_dispose (GObject *object)
ide_buffer_set_diagnostics (self, NULL);
dzl_clear_source (&priv->auto_save_handler);
dzl_clear_source (&priv->settling_handler);
dzl_clear_source (&priv->reclamation_handler);
dzl_clear_source (&priv->check_modified_timeout);
......@@ -1889,6 +1936,7 @@ ide_buffer_init (IdeBuffer *self)
priv->loading = TRUE;
priv->highlight_diagnostics = TRUE;
priv->auto_save_timeout = 60;
priv->file_signals = dzl_signal_group_new (IDE_TYPE_FILE);
dzl_signal_group_connect_object (priv->file_signals,
......@@ -3354,3 +3402,19 @@ _ide_buffer_get_highlight_engine (IdeBuffer *self)
return priv->highlight_engine;
}
void
_ide_buffer_set_auto_save (IdeBuffer *self,
gboolean auto_save,
guint auto_save_timeout)
{
IdeBufferPrivate *priv = ide_buffer_get_instance_private (self);
g_return_if_fail (IDE_IS_BUFFER (self));
g_return_if_fail (auto_save_timeout > 0);
priv->auto_save = !!auto_save;
priv->auto_save_timeout = auto_save_timeout;
ide_buffer_queue_auto_save (self);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment