Fix retain cycles
This commit is contained in:
@@ -24,6 +24,8 @@ public class Repository : DBusServiceProxy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void connect_to_repository() {
|
private void connect_to_repository() {
|
||||||
|
GLib.info("Connecting to repository");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.dbus_repository = Bus.get_proxy_sync<DBusService.Repository>(BusType.SESSION, DBUS_NAME, DBUS_PATH);
|
this.dbus_repository = Bus.get_proxy_sync<DBusService.Repository>(BusType.SESSION, DBUS_NAME, DBUS_PATH);
|
||||||
this.dbus_repository.conversations_updated.connect(() => {
|
this.dbus_repository.conversations_updated.connect(() => {
|
||||||
|
|||||||
@@ -5,8 +5,8 @@ public class MessageListModel : Object, ListModel
|
|||||||
{
|
{
|
||||||
public signal void messages_changed();
|
public signal void messages_changed();
|
||||||
|
|
||||||
public SortedSet<Message> messages {
|
public ArrayList<Message> messages {
|
||||||
owned get { return _messages.read_only_view; }
|
get { return _messages; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool is_group_chat {
|
public bool is_group_chat {
|
||||||
@@ -17,19 +17,34 @@ public class MessageListModel : Object, ListModel
|
|||||||
|
|
||||||
public string conversation_guid { get; private set; }
|
public string conversation_guid { get; private set; }
|
||||||
|
|
||||||
private SortedSet<Message> _messages;
|
private ArrayList<Message> _messages;
|
||||||
private HashSet<string> participants = new HashSet<string>();
|
private HashSet<string> participants = new HashSet<string>();
|
||||||
|
private ulong handler_id = 0;
|
||||||
|
|
||||||
public MessageListModel(string conversation_guid) {
|
public MessageListModel(string conversation_guid) {
|
||||||
_messages = new TreeSet<Message>((a, b) => {
|
_messages = new ArrayList<Message>();
|
||||||
// Sort by date in descending order (newest first)
|
|
||||||
return a.date.compare(b.date);
|
|
||||||
});
|
|
||||||
|
|
||||||
Repository.get_instance().messages_updated.connect(got_messages_updated);
|
|
||||||
this.conversation_guid = conversation_guid;
|
this.conversation_guid = conversation_guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~MessageListModel() {
|
||||||
|
// NOTE: this won't actually get destructed automatically because of a retain cycle with the signal handler.
|
||||||
|
// unwatch_updates() should be called explicitly when the model is no longer needed.
|
||||||
|
unwatch_updates();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void watch_updates() {
|
||||||
|
if (this.handler_id == 0) {
|
||||||
|
this.handler_id = Repository.get_instance().messages_updated.connect(got_messages_updated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void unwatch_updates() {
|
||||||
|
if (this.handler_id != 0) {
|
||||||
|
Repository.get_instance().disconnect(this.handler_id);
|
||||||
|
this.handler_id = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void load_messages() {
|
public void load_messages() {
|
||||||
try {
|
try {
|
||||||
Message[] messages = Repository.get_instance().get_messages(conversation_guid);
|
Message[] messages = Repository.get_instance().get_messages(conversation_guid);
|
||||||
@@ -82,6 +97,6 @@ public class MessageListModel : Object, ListModel
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Object? get_item(uint position) {
|
public Object? get_item(uint position) {
|
||||||
return _messages.to_array()[position];
|
return _messages.get((int)position);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@ private class TranscriptDrawingArea : Widget
|
|||||||
{
|
{
|
||||||
public bool show_sender = true;
|
public bool show_sender = true;
|
||||||
|
|
||||||
private SortedSet<Message> _messages = new TreeSet<Message>();
|
private ArrayList<Message> _messages = new ArrayList<Message>();
|
||||||
private ArrayList<ChatItemLayout> _chat_items = new ArrayList<ChatItemLayout>();
|
private ArrayList<ChatItemLayout> _chat_items = new ArrayList<ChatItemLayout>();
|
||||||
|
|
||||||
private const float bubble_margin = 18.0f;
|
private const float bubble_margin = 18.0f;
|
||||||
@@ -14,7 +14,7 @@ private class TranscriptDrawingArea : Widget
|
|||||||
add_css_class("transcript-drawing-area");
|
add_css_class("transcript-drawing-area");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set_messages(SortedSet<Message> messages) {
|
public void set_messages(ArrayList<Message> messages) {
|
||||||
_messages = messages;
|
_messages = messages;
|
||||||
recompute_message_layouts();
|
recompute_message_layouts();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,16 +9,25 @@ public class TranscriptView : Adw.Bin
|
|||||||
return _model;
|
return _model;
|
||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
|
if (_model != null) {
|
||||||
|
_model.disconnect(messages_changed_handler_id);
|
||||||
|
_model.unwatch_updates();
|
||||||
|
}
|
||||||
|
|
||||||
_model = value;
|
_model = value;
|
||||||
|
|
||||||
if (model != null) {
|
if (value != null) {
|
||||||
// Reset scroll position
|
// Reset scroll position
|
||||||
scrolled_window.vadjustment = new Gtk.Adjustment(0, 0, 0, 0, 0, 0);
|
scrolled_window.vadjustment = new Gtk.Adjustment(0, 0, 0, 0, 0, 0);
|
||||||
|
|
||||||
model.messages_changed.connect(reload_messages);
|
weak TranscriptView self = this;
|
||||||
model.load_messages();
|
messages_changed_handler_id = value.messages_changed.connect(() => {
|
||||||
|
self.reload_messages();
|
||||||
|
});
|
||||||
|
|
||||||
|
value.load_messages();
|
||||||
} else {
|
} else {
|
||||||
transcript_drawing_area.set_messages(new TreeSet<Message>());
|
transcript_drawing_area.set_messages(new ArrayList<Message>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,10 +43,9 @@ public class TranscriptView : Adw.Bin
|
|||||||
|
|
||||||
private TranscriptDrawingArea transcript_drawing_area = new TranscriptDrawingArea();
|
private TranscriptDrawingArea transcript_drawing_area = new TranscriptDrawingArea();
|
||||||
private ScrolledWindow scrolled_window = new ScrolledWindow();
|
private ScrolledWindow scrolled_window = new ScrolledWindow();
|
||||||
|
private ulong messages_changed_handler_id = 0;
|
||||||
|
|
||||||
public TranscriptView(MessageListModel? model = null) {
|
public TranscriptView() {
|
||||||
this.model = model;
|
|
||||||
|
|
||||||
container = new Adw.ToolbarView();
|
container = new Adw.ToolbarView();
|
||||||
set_child(container);
|
set_child(container);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user