using Gee; using Xmpp; using Dino.Entities; namespace Dino { public class StreamInteractor : Object { public signal void account_added(Account account); public signal void account_removed(Account account); public signal void stream_negotiated(Account account, XmppStream stream); public signal void attached_modules(Account account, XmppStream stream); public ModuleManager module_manager; public ConnectionManager connection_manager; private ArrayList modules = new ArrayList(); public StreamInteractor(Database db) { module_manager = new ModuleManager(); connection_manager = new ConnectionManager(module_manager); connection_manager.stream_opened.connect(on_stream_opened); } public void connect_account(Account account) { module_manager.initialize(account); account_added(account); connection_manager.connect_account(account); } public async void disconnect_account(Account account) { yield connection_manager.disconnect_account(account); account_removed(account); } public ArrayList get_accounts() { ArrayList ret = new ArrayList(Account.equals_func); foreach (Account account in connection_manager.get_managed_accounts()) { ret.add(account); } return ret; } public XmppStream? get_stream(Account account) { return connection_manager.get_stream(account); } public void add_module(StreamInteractionModule module) { modules.add(module); } public T? get_module(ModuleIdentity? identity) { if (identity == null) return null; foreach (StreamInteractionModule module in modules) { if (identity.matches(module)) return identity.cast(module); } return null; } public new T? get() { foreach (StreamInteractionModule module in modules) { if (module.get_type() == typeof(T)) return (T?) module; } return null; } private void on_stream_opened(Account account, XmppStream stream) { stream.stream_negotiated.connect( (stream) => { var flag = stream.get_flag(Xep.StreamManagement.Flag.IDENTITY); if (flag == null || flag.resumed == false) { stream_negotiated(account, stream); } }); } } public class ModuleIdentity : Object { public string id { get; private set; } public ModuleIdentity(string id) { this.id = id; } public T? cast(StreamInteractionModule module) { return module.get_type().is_a(typeof(T)) ? (T?) module : null; } public bool matches(StreamInteractionModule module) { return module.id == id; } } public interface StreamInteractionModule : Object { public abstract string id { get; } } }