1 //
2 //  SuperTuxKart - a fun racing game with go-kart
3 //  Copyright (C) 2013-2015 Glenn De Jonghe
4 //
5 //  This program is free software; you can redistribute it and/or
6 //  modify it under the terms of the GNU General Public License
7 //  as published by the Free Software Foundation; either version 3
8 //  of the License, or (at your option) any later version.
9 //
10 //  This program is distributed in the hope that it will be useful,
11 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //  GNU General Public License for more details.
14 //
15 //  You should have received a copy of the GNU General Public License
16 //  along with this program; if not, write to the Free Software
17 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 #ifndef HEADER_ONLINE_PROFILE_HPP
20 #define HEADER_ONLINE_PROFILE_HPP
21 
22 #include "utils/types.hpp"
23 #include "utils/ptr_vector.hpp"
24 
25 #include "irrString.h"
26 
27 #include <atomic>
28 #include <map>
29 #include <string>
30 
31 class XMLNode;
32 
33 namespace Online
34 {
35 /** Class that represents an online profile. It manages the online profile
36  *  for any user on this system, but also for users for which information
37  *  is requested (e.g. to see the achievements of friends). All those profiles
38  *  are managed by the ProfileManager.
39  * \ingroup online
40  */
41 class OnlineProfile
42 {
43 public:
44     enum ConstructorType
45     {
46         C_DEFAULT = 1,
47         C_RELATION_INFO
48     };
49 
50     // ========================================================================
51     class RelationInfo
52     {
53     private:
54         bool m_is_online;
55         bool m_is_pending;
56         bool m_is_asker;
57         irr::core::stringw m_date;
58 
59     public:
60         RelationInfo(const irr::core::stringw & date, bool is_online,
61                      bool is_pending, bool is_asker = false);
62         void setOnline(bool online);
63 
64         // --------------------------------------------------------------------
isPending() const65         bool isPending() const { return m_is_pending; }
66 
67         // --------------------------------------------------------------------
isAsker() const68         bool isAsker()  const { return m_is_asker; }
69 
70         // --------------------------------------------------------------------
getDate() const71         const irr::core::stringw & getDate() const { return m_date; }
72 
73         // --------------------------------------------------------------------
isOnline() const74         bool isOnline() const { return m_is_online; }
75     };  // class RelationInfo
76     // ========================================================================
77 
78     typedef std::vector<uint32_t> IDList;
79 private:
80 
81     /** The profile can either be fetching data, or be ready. */
82     enum State
83     {
84         S_FETCHING_ACHIEVEMENTS = 0x01,
85         S_FETCHING_FRIENDS      = 0x02,
86     };
87 
88     State                           m_state;
89     bool                            m_is_current_user;
90     uint32_t                        m_id;
91     irr::core::stringw              m_username;
92     /** information about the relation with the current user */
93     RelationInfo *                  m_relation_info;
94     /** Whether or not the user of this profile, is a friend of the current user */
95     bool                            m_is_friend;
96 
97     std::atomic_bool                m_has_fetched_friends;
98 
99     /** List of user id's that are friends with the user of this profile.
100      * In case this profile is of the current user, this list also contains
101      * any id's of users that still have a friend request pending. */
102     std::vector<uint32_t>           m_friends;
103 
104     bool                            m_has_fetched_achievements;
105     std::vector<uint32_t>           m_achievements;
106     std::map<uint32_t, irr::core::stringw> m_friend_server_map;
107     bool                            m_cache_bit;
108 
109     void storeFriends(const XMLNode * input);
110     void storeAchievements(const XMLNode * input);
111 
112 public:
113     OnlineProfile(const uint32_t           & userid,
114                   const irr::core::stringw & username,
115                   bool is_current_user = false       );
116     OnlineProfile(const XMLNode * xml, ConstructorType type = C_DEFAULT);
117     ~OnlineProfile();
118     void fetchFriends();
119     const IDList&   getFriends();
120     void fetchAchievements();
121     void removeFriend(const uint32_t id);
122     void addFriend(const uint32_t id);
123     void deleteRelationalInfo();
124     const IDList&   getAchievements();
125     void merge(OnlineProfile * profile);
126     // ------------------------------------------------------------------------
getFriendServerMap()127     std::map<uint32_t, irr::core::stringw>& getFriendServerMap()
128                                                 { return m_friend_server_map; }
129     // ------------------------------------------------------------------------
130     /** Returns true if the achievements for this profile have been fetched. */
hasFetchedAchievements() const131     bool hasFetchedAchievements() const  { return m_has_fetched_achievements; }
132 
133     // ------------------------------------------------------------------------
134     /** Unsets the flag that all friends of this profile are in cache. Used
135      *  when a profile is pushed out of cache. */
unsetHasFetchedFriends()136     void unsetHasFetchedFriends() { m_has_fetched_friends.store(false);  }
137     // ------------------------------------------------------------------------
138     /** Returns true if the friend list for this profile has been fetched. */
hasFetchedFriends() const139     bool hasFetchedFriends() const { return m_has_fetched_friends.load(); }
140 
141     // ------------------------------------------------------------------------
142     /** True if the profile has fetched friends. */
finishedFetchingFriends() const143     bool finishedFetchingFriends() const
144     {
145         return (m_state & S_FETCHING_FRIENDS) == 0;
146     }   // finishedFetchingFriends
147 
148     // ------------------------------------------------------------------------
149     /** True if the profile has fetched friends. */
finishedFetchingAchievements() const150     bool finishedFetchingAchievements() const
151     {
152         return (m_state & S_FETCHING_ACHIEVEMENTS) == 0;
153     }   // hasFetchedAchievements
154 
155     // ------------------------------------------------------------------------
156     /** Returns true if this item is the current user. */
isCurrentUser() const157     bool isCurrentUser() const { return m_is_current_user; }
158 
159     // ------------------------------------------------------------------------
isFriend() const160     bool isFriend() const { return m_is_friend; }
161 
162     // ------------------------------------------------------------------------
setFriend()163     void setFriend()  { m_is_friend = true; }
164 
165     // ------------------------------------------------------------------------
getRelationInfo()166     RelationInfo* getRelationInfo() { return m_relation_info; }
167 
168     // ------------------------------------------------------------------------
setRelationInfo(RelationInfo * r)169     void setRelationInfo(RelationInfo * r)
170     {
171         delete m_relation_info; m_relation_info = r;
172     }   // setRelationInfo
173 
174     // ------------------------------------------------------------------------
175     /** Sets the cache bit of this profile. Used by the cache eviction
176      *  algorithm. */
setCacheBit(bool cache_bit)177     void setCacheBit(bool cache_bit)  { m_cache_bit = cache_bit; }
178 
179     // ------------------------------------------------------------------------
180     /** Returns the cache bit for this profile. Used by the cache eviction
181      *  algorithm. */
getCacheBit() const182     bool getCacheBit() const { return m_cache_bit; }
183 
184     // ------------------------------------------------------------------------
185     /** Returns the online id of this profile. */
getID() const186     uint32_t getID() const { return m_id; }
187 
188     // ------------------------------------------------------------------------
189     /** Returns the user name of this profile. */
getUserName() const190     const irr::core::stringw& getUserName() const { return m_username; }
191 };   // class OnlineProfile
192 } // namespace Online
193 #endif // HEADER_ONLINE_PROFILE_HPP
194