Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/notifications/src/modules/notifications/NotificationQueue.cc @ 7342

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

Some documenting, cleaning up. Also: Now the NotificationQueue has a height corresponding to its input size.

  • Property svn:eol-style set to native
File size: 11.6 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 NotificationQueue.cc
31    @brief Implementation of the NotificationQueue class.
32*/
33
34#include "NotificationQueue.h"
35
36#include <algorithm>
37
38#include "util/Convert.h"
39#include "core/CoreIncludes.h"
40#include "core/GUIManager.h"
41#include "core/LuaState.h"
42#include "Notification.h"
43
44namespace orxonox
45{
46
47    const Vector2 NotificationQueue::DEFAULT_POSITION(0.0,0.0);
48
49    /**
50    @brief
51        Constructor. Creates and initializes the object.
52    */
53    NotificationQueue::NotificationQueue(const std::string& name, const std::string& senders, unsigned int size, const Vector2& position, unsigned int displayTime)
54    {
55        this->registered_ = false;
56
57        RegisterRootObject(NotificationQueue);
58
59        this->initialize();
60
61        this->setTargets(senders);
62        this->name_ = name;
63        this->maxSize_ = size;
64        this->position_ = position;
65        this->setDisplayTime(displayTime);
66
67        this->create();
68        this->positionChanged();
69
70        NotificationManager::getInstance().registerListener(this);
71        this->registered_ = true;
72
73        COUT(3) << "NotificationQueue '" << this->getName() << "' created." << std::endl;
74    }
75
76    /**
77    @brief
78        Destructor.
79    */
80    NotificationQueue::~NotificationQueue()
81    {
82        this->targets_.clear();
83        this->clear();
84
85        if(this->registered_)
86            NotificationManager::getInstance().unregisterListener(this);
87    }
88
89    /**
90    @brief
91        Initializes the object.
92        Registers the object, initializes variables, sets default values and registers the queue with the NotificationManager.
93    */
94    void NotificationQueue::initialize(void)
95    {
96        this->size_ = 0;
97        this->tickTime_ = 0.0;
98    }
99
100    /**
101    @brief
102        Creates the NotificationQueue in lua.
103    */
104    void NotificationQueue::create(void)
105    {
106        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.createQueue(\"" + this->getName() + "\", " + multi_cast<std::string>(this->getMaxSize()) + ")");
107    }
108
109    /**
110    @brief
111        Updates the queue from time to time.
112    @param dt
113        The time interval that has passed since the last tick.
114    */
115    void NotificationQueue::tick(float dt)
116    {
117        this->tickTime_ += dt; // Add the time interval that has passed to the time counter.
118        if(this->tickTime_ >= 1.0) // If the time counter is greater than 1s all Notifications that have expired are removed, if it is smaller we wait to the next tick.
119        {
120            this->timeLimit_.time = std::time(0)-this->displayTime_; // Container containig the current time.
121
122            std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator it = this->ordering_.begin();
123            while(it != this->ordering_.upper_bound(&this->timeLimit_)) // Iterate through all elements whose creation time is smaller than the current time minus the display time.
124            {
125                NotificationContainer* temp = *it;
126                it++;
127                this->remove(temp);
128            }
129
130            this->tickTime_ = this->tickTime_ - (int)this->tickTime_; // Reset time counter.
131        }
132    }
133
134    /**
135    @brief
136        Updates the NotificationQueue.
137        Updates by clearing the queue and requesting all relevant Notifications from the NotificationManager and inserting them into the queue.
138    */
139    void NotificationQueue::update(void)
140    {
141        this->clear();
142
143        std::multimap<std::time_t, Notification*>* notifications = new std::multimap<std::time_t, Notification*>;
144        if(!NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_)) // Get the Notifications sent in the interval form now to minus the display time.
145        {
146            COUT(1) << "NotificationQueue update failed due to undetermined cause." << std::endl;
147            return;
148        }
149
150        if(notifications->empty())
151            return;
152
153        for(std::multimap<std::time_t, Notification*>::iterator it = notifications->begin(); it != notifications->end(); it++) // Add all Notifications.
154            this->push(it->second, it->first);
155
156        delete notifications;
157
158        COUT(4) << "NotificationQueue '" << this->getName() << "' updated." << std::endl;
159    }
160
161    /**
162    @brief
163        Updates the NotificationQueue by adding an new Notification.
164    @param notification
165        Pointer to the Notification.
166    @param time
167        The time the Notification was sent.
168    */
169    void NotificationQueue::update(Notification* notification, const std::time_t & time)
170    {
171        this->push(notification, time);
172
173        COUT(4) << "NotificationQueue '" << this->getName() << "' updated. A new Notification has been added." << std::endl;
174    }
175
176    /**
177    @brief
178        Adds a Notification, to the queue.
179        It inserts it into the storage containers, creates a corresponding container and pushes the Notification message to the GUI.
180    @param notification
181        The Notification.
182    @param time
183        The time.
184    */
185    void NotificationQueue::push(Notification* notification, const std::time_t & time)
186    {
187        NotificationContainer* container = new NotificationContainer;
188        container->notification = notification;
189        container->time = time;
190
191        // If the maximum size of the NotificationQueue has been reached the last (least recently added) Notification is removed.
192        if(this->getSize() >= this->getMaxSize())
193            this->pop();
194
195        this->size_++;
196
197        this->ordering_.insert(container);
198        this->notifications_.insert(this->notifications_.begin(), container);
199
200        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.pushNotification(\"" + this->getName() + "\", \"" + notification->getMessage() + "\")");
201    }
202
203    /**
204    @brief
205        Removes the least recently added Notification form the NotificationQueue.
206    */
207    void NotificationQueue::pop(void)
208    {
209        NotificationContainer* container = this->notifications_.back();
210        this->ordering_.erase(container);
211        this->notifications_.pop_back();
212        this->size_--;
213        delete container;
214        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.popNotification(\"" + this->getName() + "\")");
215    }
216
217    /**
218    @brief
219        Removes the Notification that is stored in the input container.
220    @param container
221        The NotificationContainer with the Notification to be removed.
222    */
223    void NotificationQueue::remove(NotificationContainer* container)
224    {
225        std::vector<NotificationContainer*>::iterator it = std::find(this->notifications_.begin(), this->notifications_.end(), container);
226        std::vector<NotificationContainer*>::difference_type index = it - this->notifications_.begin ();
227        this->ordering_.erase(container);
228        this->notifications_.erase(it);
229        this->size_--;
230        delete container;
231        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.removeNotification(\"" + this->getName() + "\", " + multi_cast<std::string>(index) + ")");
232    }
233
234    /**
235    @brief
236        Clears the queue by removing all containers.
237    */
238    void NotificationQueue::clear(void)
239    {
240        this->ordering_.clear();
241        for(std::vector<NotificationContainer*>::iterator it = this->notifications_.begin(); it != this->notifications_.end(); it++)
242        {
243            delete *it;
244        }
245        this->notifications_.clear();
246        this->size_ = 0;
247        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.clearQueue(\"" + this->getName() + "\")");
248    }
249
250    /**
251    @brief
252        Sets the name of the NotificationQueue.
253    @param name
254        The name to be set.
255    @return
256        returns true if successful.
257    */
258    bool NotificationQueue::setName(const std::string& name)
259    {
260        //TODO: Test uniqueness of name.
261        this->name_ = name;
262        return true;
263    }
264
265    /**
266    @brief
267        Sets the maximum number of displayed Notifications.
268    @param size
269        The size to be set.
270    @return
271        Returns true if successful.
272    */
273    void NotificationQueue::setMaxSize(unsigned int size)
274    {
275        this->maxSize_ = size;
276        this->update();
277    }
278
279    /**
280    @brief
281        Sets the maximum number of seconds a Notification is displayed.
282    @param time
283        The number of seconds the Notifications is displayed.
284    @return
285        Returns true if successful.
286    */
287    void NotificationQueue::setDisplayTime(unsigned int time)
288    {
289        this->displayTime_ = time;
290        this->update();
291    }
292
293    /**
294    @brief
295        Produces all targets concatinated as string, with kommas (',') as seperators.
296    @param string
297        Pointer to a string which will be used by the method to fill with the concatination of the targets.
298    @return
299        Returns true if successful.
300    */
301    bool NotificationQueue::getTargets(std::string* string) const
302    {
303        if(string == NULL)
304        {
305            COUT(4) << "Input string must have memory allocated." << std::endl;
306            return false;
307        }
308        string->clear();
309        bool first = true;
310        for(std::set<std::string>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++) //!< Iterate through the set of targets.
311        {
312            if(!first)
313            {
314                *string += ',';
315            }
316            else
317            {
318                first = false;
319            }
320            *string += *it;
321        }
322
323        return true;
324    }
325
326    /**
327    @brief
328        Sets the targets of the queue.
329        The targets are the senders whose Notifications are displayed in this queue.
330    @param targets
331        Accepts a string of targets, each seperated by commas (','), spaces are ignored.
332    @return
333        Returns true if successful.
334    */
335    bool NotificationQueue::setTargets(const std::string & targets)
336    {
337        this->targets_.clear();
338
339        std::string* pTemp;
340        unsigned int index = 0;
341        while( index < targets.size() ) //!< Go through the string, character by character until the end is reached.
342        {
343            pTemp = new std::string();
344            while(index < targets.size() && targets[index] != ',' && targets[index] != ' ')
345            {
346                *pTemp += targets[index];
347                index++;
348            }
349            index++;
350            this->targets_.insert(*pTemp);
351        }
352
353        return true;
354    }
355
356    /**
357    @brief
358        Aligns all the Notifications to the position of the NotificationQueue.
359    */
360    void NotificationQueue::positionChanged(void)
361    {
362        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.changePosition(\"" + this->getName() + "\", " + multi_cast<std::string>(this->getPosition().x) + ", " + multi_cast<std::string>(this->getPosition().y) + ")");
363    }
364
365}
Note: See TracBrowser for help on using the repository browser.