summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Presence/PresenceOracle.cpp')
-rw-r--r--Swiften/Presence/PresenceOracle.cpp89
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
14namespace Swift { 18namespace Swift {
15 19
16PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) { 20PresenceOracle::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
113struct 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
147typedef std::priority_queue<Presence::ref, std::vector<Presence::ref>, PresenceAccountCmp> PresenceAccountPriorityQueue;
148
149Presence::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
191Presence::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
109Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const { 198Presence::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 }