diff options
Diffstat (limited to 'xmpp-vala/src/module/util.vala')
-rw-r--r-- | xmpp-vala/src/module/util.vala | 59 |
1 files changed, 59 insertions, 0 deletions
diff --git a/xmpp-vala/src/module/util.vala b/xmpp-vala/src/module/util.vala index 365170b0..e6626049 100644 --- a/xmpp-vala/src/module/util.vala +++ b/xmpp-vala/src/module/util.vala @@ -1,3 +1,5 @@ +using Gee; + namespace Xmpp { public string get_bare_jid(string jid) { return jid.split("/")[0]; @@ -20,4 +22,61 @@ namespace Xmpp { uint32 b5_2 = Random.next_int(); return "%08x-%04x-%04x-%04x-%04x%08x".printf(b1, b2, b3, b4, b5_1, b5_2); } + +public abstract class StanzaListener<T> : Object { + public abstract string action_group { get; } + public abstract string[] after_actions { get; } + public abstract async void run(Core.XmppStream stream, T stanza); +} + +public class StanzaListenerHolder<T> : Object { + private Gee.List<StanzaListener<T>> listeners = new ArrayList<StanzaListener<T>>(); + + public new void connect(StanzaListener<T> listener) { + listeners.add(listener); + resort_list(); + } + + public async void run(Core.XmppStream stream, T stanza) { + foreach (StanzaListener<T> l in listeners) { + yield l.run(stream, stanza); + } + } + + private Gee.List<StanzaListener<T>> set_minus(Gee.List<StanzaListener<T>> main_set, Gee.List<StanzaListener<T>> minus) { + Gee.List<StanzaListener<T>> res = new ArrayList<StanzaListener<T>>(); + foreach (StanzaListener<T> l in main_set) { + if (!minus.contains(l)) { + res.add(l); + } + } + return res; + } + + private bool set_contains_action(Gee.List<StanzaListener<T>> s, string[] actions) { + foreach(StanzaListener<T> l in s) { + if (l.action_group in actions) { + return true; + } + } + return false; + } + + private void resort_list() { + Gee.List<StanzaListener<T>> new_list = new ArrayList<StanzaListener<T>>(); + while (listeners.size > new_list.size) { + bool changed = false; + foreach (StanzaListener<T> l in listeners) { + Gee.List<StanzaListener<T>> remaining = set_minus(listeners, new_list); + if (!set_contains_action(remaining, l.after_actions)) { + new_list.add(l); + changed = true; + } + } + if (!changed) warning("Can't sort listeners"); + } + listeners = new_list; + } +} + } |