Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Re-adding enterEditMode method to NotificationManager.

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