Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Fixed Esc Problem in MainMenu.

  • 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        if(GameMode::showsGraphics())
64        {
65            GUIManager::getInstance().loadGUI("NotificationLayer");
66
67            // Create first queue:
68            NotificationQueue* queue = new NotificationQueue("all");
69        }
70    }
71
72    /**
73    @brief
74        Destructor.
75    */
76    NotificationManager::~NotificationManager()
77    {
78
79    }
80
81    /**
82    @brief
83        Registers a Notification within the NotificationManager and makes sure that the Notification is sent to all the NotificationListeners associated with its sender.
84    @param notification
85        The Notification to be registered.
86    @return
87        Returns true if successful.
88    */
89    bool NotificationManager::registerNotification(Notification* notification)
90    {
91
92        if(notification == NULL) //!< A NULL-Notification cannot be registered.
93            return false;
94
95        std::time_t time = std::time(0); //TODO: Doesn't this expire? //!< Get current time.
96
97        this->allNotificationsList_.insert(std::pair<std::time_t,Notification*>(time,notification));
98
99        if(notification->getSender() == NONE) // If the sender has no specific name, then the Notification is only added to the list of all Notifications.
100            return true;
101
102        bool all = false;
103        if(notification->getSender() == ALL) // If all are the sender, then the Notifications is added to every NotificationListener.
104            all = true;
105
106        // Insert the notification in all listeners that have its sender as target.
107        for(std::map<NotificationListener*,int>::iterator it = this->listenerList_.begin(); it != this->listenerList_.end(); it++) // Iterate through all listeners.
108        {
109            std::set<std::string> set = it->first->getTargetsSet();
110            if(all || set.find(notification->getSender()) != set.end() || set.find(ALL) != set.end()) //TODO: Make sure this works.
111            {
112                this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); // Insert the Notification in the Notifications list of the current NotificationListener.
113                it->first->update(notification, time); // Update the listener.
114                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(notification);
115                if(counterIt == this->listenerCounter_.end())
116                    this->listenerCounter_[notification] = 1;
117                else
118                    this->listenerCounter_[notification] = counterIt->second + 1;
119            }
120        }
121
122        COUT(4) << "Notification registered with the NotificationManager." << std::endl;
123
124        return true;
125    }
126
127    /**
128    @brief
129        Unregisters a Notification within the NotificationManager.
130    @param notification
131        A pointer to the Notification to be unregistered.
132    @param listener
133        A pointer to the NotificationListener the Notification is unregistered for.
134    */
135    void NotificationManager::unregisterNotification(Notification* notification, NotificationListener* listener)
136    {
137        assert(notification);
138        assert(listener);
139
140        // 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.
141        if(this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second)))
142            this->listenerCounter_[notification] = this->listenerCounter_[notification] - 1;
143
144        // 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.
145        if(this->listenerCounter_[notification] == (unsigned int) 0)
146        {
147            this->removeNotification(notification, this->allNotificationsList_);
148            this->listenerCounter_.erase(notification);
149            notification->destroy();
150        }
151
152        COUT(4) << "Notification unregistered with the NotificationManager." << std::endl;
153    }
154
155    /**
156    @brief
157        Helper method that removes an input notification form an input map.
158    @param notification
159        A pointer to the notification to be removed.
160    @param map
161        The map the notification should be removed from.
162    @return
163        Returns true if successful.
164    */
165    //TODO: Needed?
166    bool NotificationManager::removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map)
167    {
168        // Iterates through all items in the map until the Notification is found.
169        //TODO: Do more efficiently?
170        for(std::multimap<std::time_t, Notification*>::iterator it = map.begin(); it != map.end(); it++)
171        {
172            if(it->second == notification)
173            {
174                map.erase(it);
175                return true;
176            }
177        }
178        return false;
179    }
180
181    /**
182    @brief
183        Registers a NotificationListener within the NotificationManager.
184    @param listener
185        The NotificationListener to be registered.
186    @return
187        Returns true if successful.
188    */
189    bool NotificationManager::registerListener(NotificationListener* listener)
190    {
191        this->highestIndex_ += 1;
192        int index = this->highestIndex_;
193
194        this->listenerList_[listener] = index; // Add the NotificationListener to the list of listeners.
195
196        std::set<std::string> set = listener->getTargetsSet(); //TODO: Does this work?
197
198        // 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.
199        if(set.find(ALL) != set.end())
200        {
201            this->notificationLists_[index] = &this->allNotificationsList_;
202            COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
203            return true;
204        }
205
206        this->notificationLists_[index] = new std::multimap<std::time_t,Notification*>;
207        std::multimap<std::time_t,Notification*> map = *this->notificationLists_[index];
208
209        // Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationListener.
210        for(std::multimap<std::time_t,Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
211        {
212            if(set.find(it->second->getSender()) != set.end()) // Checks whether the overlay has the sender of the current notification as target.
213            {
214                map.insert(std::pair<std::time_t, Notification*>(it->first, it->second));
215                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(it->second);
216                if(counterIt == this->listenerCounter_.end())
217                    this->listenerCounter_[it->second] = 1;
218                else
219                    this->listenerCounter_[it->second] = counterIt->second + 1;
220            }
221        }
222
223        listener->update(); // Update the listener.
224
225        COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
226
227        return true;
228    }
229
230    /**
231    @brief
232        Unregisters a NotificationListener withing the NotificationManager.
233    */
234    void NotificationManager::unregisterListener(NotificationListener* listener)
235    {
236        assert(listener);
237
238        int identifier = this->listenerList_.find(listener)->second;
239        std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
240
241        // Make sure all Notifications are removed.
242        std::multimap<std::time_t, Notification*>::iterator it = map->begin();
243        while(it != map->end())
244        {
245            this->unregisterNotification(it->second, listener);
246            it = map->begin();
247        }
248
249        this->listenerList_.erase(listener);
250        this->notificationLists_.erase(identifier);
251
252        // If the map is not the map of all notifications, delete it.
253        if(map != &this->allNotificationsList_)
254            delete map;
255
256        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
257    }
258
259    /**
260    @brief
261        Fetches the Notifications for a specific NotificationListener in a specified timeframe.
262    @param listener
263        The NotificationListener the Notifications are fetched for.
264    @param map
265        A multimap, in which the notifications are stored.
266    @param timeFrameStart
267        The start time of the timeframe.
268    @param timeFrameEnd
269        The end time of the timeframe.
270    @return
271        Returns true if successful.
272    */
273    bool NotificationManager::getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
274    {
275        if(listener == NULL || map == NULL)
276            return false;
277
278        std::multimap<std::time_t,Notification*>* notifications = this->notificationLists_[this->listenerList_[listener]]; // The Notifications for the input NotificationListener.
279
280        if(notifications == NULL) // Returns NULL, if there are no Notifications.
281            return true;
282
283        std::multimap<std::time_t,Notification*>::iterator it, itLowest, itHighest;
284        itLowest = notifications->lower_bound(timeFrameStart);
285        itHighest = notifications->upper_bound(timeFrameStart);
286
287        for(it = itLowest; it != itHighest; it++) // Iterate through the Notifications from the start of the time Frame to the end of it.
288        {
289            map->insert(std::pair<std::time_t,Notification*>(it->first,it->second)); // Add the found Notifications to the map.
290        }
291
292        return true;
293    }
294
295}
Note: See TracBrowser for help on using the repository browser.