diff options
Diffstat (limited to 'Swiften/Presence/PresenceOracle.cpp')
| -rw-r--r-- | Swiften/Presence/PresenceOracle.cpp | 89 |
1 files changed, 89 insertions, 0 deletions
diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp index e4129fb..8623529 100644 --- a/Swiften/Presence/PresenceOracle.cpp +++ b/Swiften/Presence/PresenceOracle.cpp | |||
| @@ -4,13 +4,17 @@ | |||
| 4 | * See the COPYING file for more information. | 4 | * See the COPYING file for more information. |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #include <Swiften/Presence/PresenceOracle.h> | 7 | #include <Swiften/Presence/PresenceOracle.h> |
| 8 | 8 | ||
| 9 | #include <queue> | ||
| 10 | |||
| 9 | #include <boost/bind.hpp> | 11 | #include <boost/bind.hpp> |
| 10 | 12 | ||
| 13 | #include <Swiften/Base/foreach.h> | ||
| 11 | #include <Swiften/Client/StanzaChannel.h> | 14 | #include <Swiften/Client/StanzaChannel.h> |
| 15 | #include <Swiften/Elements/StatusShow.h> | ||
| 12 | #include <Swiften/Roster/XMPPRoster.h> | 16 | #include <Swiften/Roster/XMPPRoster.h> |
| 13 | 17 | ||
| 14 | namespace Swift { | 18 | namespace Swift { |
| 15 | 19 | ||
| 16 | PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) { | 20 | PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) { |
| @@ -104,10 +108,95 @@ std::vector<Presence::ref> PresenceOracle::getAllPresence(const JID& bareJID) co | |||
| 104 | results.push_back(current); | 108 | results.push_back(current); |
| 105 | } | 109 | } |
| 106 | return results; | 110 | return results; |
| 107 | } | 111 | } |
| 108 | 112 | ||
| 113 | struct PresenceAccountCmp { | ||
| 114 | static int preferenceFromStatusShow(StatusShow::Type showType) { | ||
| 115 | switch (showType) { | ||
| 116 | case StatusShow::FFC: | ||
| 117 | return 5; | ||
| 118 | case StatusShow::Online: | ||
| 119 | return 4; | ||
| 120 | case StatusShow::DND: | ||
| 121 | return 3; | ||
| 122 | case StatusShow::Away: | ||
| 123 | return 2; | ||
| 124 | case StatusShow::XA: | ||
| 125 | return 1; | ||
| 126 | case StatusShow::None: | ||
| 127 | return 0; | ||
| 128 | } | ||
| 129 | assert(false); | ||
| 130 | return -1; | ||
| 131 | } | ||
| 132 | |||
| 133 | bool operator()(const Presence::ref& a, const Presence::ref& b) { | ||
| 134 | int aPreference = preferenceFromStatusShow(a->getShow()); | ||
| 135 | int bPreference = preferenceFromStatusShow(b->getShow()); | ||
| 136 | |||
| 137 | if (aPreference != bPreference) { | ||
| 138 | return aPreference < bPreference; | ||
| 139 | } | ||
| 140 | if (a->getPriority() != b->getPriority()) { | ||
| 141 | return a->getPriority() < b->getPriority(); | ||
| 142 | } | ||
| 143 | return a->getFrom().getResource() < b->getFrom().getResource(); | ||
| 144 | } | ||
| 145 | }; | ||
| 146 | |||
| 147 | typedef std::priority_queue<Presence::ref, std::vector<Presence::ref>, PresenceAccountCmp> PresenceAccountPriorityQueue; | ||
| 148 | |||
| 149 | Presence::ref PresenceOracle::getActivePresence(const std::vector<Presence::ref> presences) { | ||
| 150 | Presence::ref accountPresence; | ||
| 151 | |||
| 152 | PresenceAccountPriorityQueue online; | ||
| 153 | PresenceAccountPriorityQueue away; | ||
| 154 | PresenceAccountPriorityQueue offline; | ||
| 155 | |||
| 156 | foreach(Presence::ref presence, presences) { | ||
| 157 | switch (presence->getShow()) { | ||
| 158 | case StatusShow::Online: | ||
| 159 | online.push(presence); | ||
| 160 | break; | ||
| 161 | case StatusShow::Away: | ||
| 162 | away.push(presence); | ||
| 163 | break; | ||
| 164 | case StatusShow::FFC: | ||
| 165 | online.push(presence); | ||
| 166 | break; | ||
| 167 | case StatusShow::XA: | ||
| 168 | away.push(presence); | ||
| 169 | break; | ||
| 170 | case StatusShow::DND: | ||
| 171 | away.push(presence); | ||
| 172 | break; | ||
| 173 | case StatusShow::None: | ||
| 174 | offline.push(presence); | ||
| 175 | break; | ||
| 176 | } | ||
| 177 | } | ||
| 178 | |||
| 179 | if (!online.empty()) { | ||
| 180 | accountPresence = online.top(); | ||
| 181 | } | ||
| 182 | else if (!away.empty()) { | ||
| 183 | accountPresence = away.top(); | ||
| 184 | } | ||
| 185 | else if (!offline.empty()) { | ||
| 186 | accountPresence = offline.top(); | ||
| 187 | } | ||
| 188 | return accountPresence; | ||
| 189 | } | ||
| 190 | |||
| 191 | Presence::ref PresenceOracle::getAccountPresence(const JID& jid) const { | ||
| 192 | Presence::ref accountPresence; | ||
| 193 | std::vector<Presence::ref> allPresences = getAllPresence(jid.toBare()); | ||
| 194 | accountPresence = getActivePresence(allPresences); | ||
| 195 | return accountPresence; | ||
| 196 | } | ||
| 197 | |||
| 109 | Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const { | 198 | Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const { |
| 110 | PresencesMap::const_iterator i = entries_.find(bareJID); | 199 | PresencesMap::const_iterator i = entries_.find(bareJID); |
| 111 | if (i == entries_.end()) { | 200 | if (i == entries_.end()) { |
| 112 | return Presence::ref(); | 201 | return Presence::ref(); |
| 113 | } | 202 | } |
Swift