Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/notifications/src/modules/notifications/NotificationManager.cc @ 7338

Last change on this file since 7338 was 7338, checked in by dafrick, 14 years ago

Changing from OrxonoxOverlays to CEGUI as means of displaying Notifications.
Still messy and not working completely but it's a start.

  • Property svn:eol-style set to native
File size: 11.2 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Damian 'Mozork' Frick
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @brief Implementation of the NotificationManager class.
32*/
33
34#include "NotificationManager.h"
35
36#include <set>
37
38#include "util/ScopedSingletonManager.h"
39#include "core/CoreIncludes.h"
40#include "Notification.h"
41#include "interfaces/NotificationListener.h"
42#include "core/GUIManager.h"
43#include "NotificationQueue.h"
44
45namespace orxonox
46{
47
48    const std::string NotificationManager::ALL("all");
49    const std::string NotificationManager::NONE("none");
50
51    ManageScopedSingleton(NotificationManager, ScopeID::Graphics, false);
52
53    /**
54    @brief
55        Constructor. Registers the Object.
56    */
57    NotificationManager::NotificationManager()
58    {
59        RegisterRootObject(NotificationManager);
60
61        this->highestIndex_ = 0;
62
63        //TODO: What if no graphics?
64        GUIManager::getInstance().loadGUI("NotificationLayer");
65        // Create first queue:
66        NotificationQueue* queue = new NotificationQueue("general");
67    }
68
69    /**
70    @brief
71        Destructor.
72    */
73    NotificationManager::~NotificationManager()
74    {
75
76    }
77
78    /**
79    @brief
80        Registers a Notification within the NotificationManager and makes sure that the Notification is sent to all the NotificationListeners associated with its sender.
81    @param notification
82        The Notification to be registered.
83    @return
84        Returns true if successful.
85    */
86    bool NotificationManager::registerNotification(Notification* notification)
87    {
88
89        if(notification == NULL) //!< A NULL-Notification cannot be registered.
90            return false;
91
92        std::time_t time = std::time(0); //TODO: Doesn't this expire? //!< Get current time.
93
94        this->allNotificationsList_.insert(std::pair<std::time_t,Notification*>(time,notification));
95
96        if(notification->getSender() == NONE) //!< If the sender has no specific name, then the Notification is only added to the list of all Notifications.
97            return true;
98
99        bool all = false;
100        if(notification->getSender() == ALL) //!< If all are the sender, then the Notifications is added to every NotificationListener.
101            all = true;
102
103        //!< Insert the notification in all listeners that have its sender as target.
104        for(std::map<NotificationListener*,int>::iterator it = this->listenerList_.begin(); it != this->listenerList_.end(); it++) //!< Iterate through all listeners.
105        {
106            std::set<std::string> set = it->first->getTargetsSet();
107            if(all || set.find(notification->getSender()) != set.end() || set.find(ALL) != set.end()) //TODO: Make sure this works.
108            {
109                this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); //!< Insert the Notification in the Notifications list of the current NotificationListener.
110                it->first->update(notification, time); //!< Update the listener.
111                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(notification);
112                if(counterIt == this->listenerCounter_.end())
113                    this->listenerCounter_[notification] = 1;
114                else
115                    this->listenerCounter_[notification] = counterIt->second + 1;
116            }
117        }
118
119        COUT(4) << "Notification registered with the NotificationManager." << std::endl;
120
121        return true;
122    }
123
124    /**
125    @brief
126        Unregisters a Notification within the NotificationManager.
127    @param notification
128        A pointer to the Notification to be unregistered.
129    @param listener
130        A pointer to the NotificationListener the Notification is unregistered for.
131    */
132    void NotificationManager::unregisterNotification(Notification* notification, NotificationListener* listener)
133    {
134        assert(notification);
135        assert(listener);
136
137        // If the Notification was removed from the list of Notifications of the input NotificationListener, the counter for the Notification of the number of NotificationListeners it is present in is decremented.
138        if(this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second)))
139            this->listenerCounter_[notification] = this->listenerCounter_[notification] - 1;
140
141        // If the Notification is no longer present in any of the NotificationListeners it can be removed from the map of all Notifications and be destroyed.
142        if(this->listenerCounter_[notification] == (unsigned int) 0)
143        {
144            this->removeNotification(notification, this->allNotificationsList_);
145            this->listenerCounter_.erase(notification);
146            notification->destroy();
147        }
148
149        COUT(4) << "Notification unregistered with the NotificationManager." << std::endl;
150    }
151
152    /**
153    @brief
154        Helper method that removes an input notification form an input map.
155    @param notification
156        A pointer to the notification to be removed.
157    @param map
158        The map the notification should be removed from.
159    @return
160        Returns true if successful.
161    */
162    bool NotificationManager::removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map)
163    {
164        // Iterates through all items in the map until the Notification is found.
165        //TODO: Do more efficiently?
166        for(std::multimap<std::time_t, Notification*>::iterator it = map.begin(); it != map.end(); it++)
167        {
168            if(it->second == notification)
169            {
170                map.erase(it);
171                return true;
172            }
173        }
174        return false;
175    }
176
177    /**
178    @brief
179        Registers a NotificationListener within the NotificationManager.
180    @param listener
181        The NotificationListener to be registered.
182    @return
183        Returns true if successful.
184    */
185    bool NotificationManager::registerListener(NotificationListener* listener)
186    {
187        this->highestIndex_ += 1;
188        int index = this->highestIndex_;
189
190        this->listenerList_[listener] = index; //!< Add the NotificationListener to the list of listeners.
191
192        std::set<std::string> set = listener->getTargetsSet(); //TODO: Does this work?
193
194        //! If all senders are the target of the listener, then the list of notification for that specific listener is te same as the list of all Notifications.
195        if(set.find(ALL) != set.end())
196        {
197            this->notificationLists_[index] = &this->allNotificationsList_;
198            COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
199            return true;
200        }
201
202        this->notificationLists_[index] = new std::multimap<std::time_t,Notification*>;
203        std::multimap<std::time_t,Notification*> map = *this->notificationLists_[index];
204
205        //! Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationListener.
206        for(std::multimap<std::time_t,Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
207        {
208            if(set.find(it->second->getSender()) != set.end()) //!< Checks whether the overlay has the sender of the current notification as target.
209            {
210                map.insert(std::pair<std::time_t, Notification*>(it->first, it->second));
211                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(it->second);
212                if(counterIt == this->listenerCounter_.end())
213                    this->listenerCounter_[it->second] = 1;
214                else
215                    this->listenerCounter_[it->second] = counterIt->second + 1;
216            }
217        }
218
219        listener->update(); //!< Update the listener.
220
221        COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
222
223        return true;
224    }
225
226    /**
227    @brief
228        Unregisters a NotificationListener withing the NotificationManager.
229    */
230    void NotificationManager::unregisterListener(NotificationListener* listener)
231    {
232        assert(listener);
233
234        int identifier = this->listenerList_.find(listener)->second;
235        std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
236
237        // Make sure all Notifications are removed.
238        std::multimap<std::time_t, Notification*>::iterator it = map->begin();
239        while(it != map->end())
240        {
241            this->unregisterNotification(it->second, listener);
242            it = map->begin();
243        }
244
245        this->listenerList_.erase(listener);
246        this->notificationLists_.erase(identifier);
247
248        // If the map is not the map of all notifications, delete it.
249        if(map != &this->allNotificationsList_)
250            delete map;
251
252        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
253    }
254
255    /**
256    @brief
257        Fetches the Notifications for a specific NotificationListener in a specified timeframe.
258    @param listener
259        The NotificationListener the Notifications are fetched for.
260    @param map
261        A multimap, in which the notifications are stored.
262    @param timeFrameStart
263        The start time of the timeframe.
264    @param timeFrameEnd
265        The end time of the timeframe.
266    @return
267        Returns true if successful.
268    */
269    bool NotificationManager::getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
270    {
271        if(listener == NULL || map == NULL)
272            return false;
273
274        std::multimap<std::time_t,Notification*>* notifications = this->notificationLists_[this->listenerList_[listener]]; //!< The Notifications for the input NotificationListener.
275
276        if(notifications == NULL) //!< Returns NULL, if there are no Notifications.
277            return true;
278
279        std::multimap<std::time_t,Notification*>::iterator it, itLowest, itHighest;
280        itLowest = notifications->lower_bound(timeFrameStart);
281        itHighest = notifications->upper_bound(timeFrameStart);
282
283        for(it = itLowest; it != itHighest; it++) //!< Iterate through the Notifications from the start of the time Frame to the end of it.
284        {
285            map->insert(std::pair<std::time_t,Notification*>(it->first,it->second)); //!< Add the found Notifications to the map.
286        }
287
288        return true;
289    }
290
291}
Note: See TracBrowser for help on using the repository browser.