Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/netp6/src/orxonox/overlays/notifications/NotificationQueue.cc @ 3254

Last change on this file since 3254 was 3196, checked in by rgrieder, 15 years ago

Merged pch branch back to trunk.

  • Property svn:eol-style set to native
File size: 14.1 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 NotificationQueue class.
32*/
33
34#include "NotificationQueue.h"
35
36#include <sstream>
37
38#include "core/CoreIncludes.h"
39#include "core/XMLPort.h"
40#include "NotificationOverlay.h"
41#include "NotificationManager.h"
42
43namespace orxonox
44{
45
46    CreateFactory(NotificationQueue);
47
48    const std::string NotificationQueue::DEFAULT_FONT = "VeraMono";
49    const Vector2 NotificationQueue::DEFAULT_POSITION = Vector2(0.0,0.0);
50    const float NotificationQueue::DEFAULT_FONT_SIZE  = 0.025f;
51
52    /**
53    @brief
54        Constructor. Creates and initializes the object.
55    */
56    NotificationQueue::NotificationQueue(BaseObject* creator) : OverlayGroup(creator)
57    {
58        RegisterObject(NotificationQueue);
59        this->initialize();
60    }
61
62    /**
63    @brief
64        Destructor.
65    */
66    NotificationQueue::~NotificationQueue()
67    {
68        this->targets_.clear();
69        this->clear();
70    }
71
72    /**
73    @brief
74        Initializes the object.
75        Registers the object, initializes variables, sets default values and registers the queue with the NotificationManager.
76    */
77    void NotificationQueue::initialize(void)
78    {
79        this->size_ = 0;
80        this->tickTime_ = 0.0;
81
82        NotificationManager::getInstance().registerQueue(this);
83    }
84
85    /**
86    @brief
87        Sets the defaults.
88    */
89    void NotificationQueue::setDefaults(void)
90    {
91        this->setMaxSize(DEFAULT_SIZE);
92        this->setNotificationLength(DEFAULT_LENGTH);
93        this->setDisplayTime(DEFAULT_DISPLAY_TIME);
94        this->setPosition(DEFAULT_POSITION);
95
96        this->setTargets(NotificationManager::ALL);
97
98        this->setFontSize(DEFAULT_FONT_SIZE);
99        this->setFont(DEFAULT_FONT);
100    }
101
102    /**
103    @brief
104        Method for creating a NotificationQueue object through XML.
105    */
106    void NotificationQueue::XMLPort(Element& xmlElement, XMLPort::Mode mode)
107    {
108        SUPER(NotificationQueue, XMLPort, xmlElement, mode);
109
110        this->setDefaults();
111
112        XMLPortParam(NotificationQueue, "maxSize", setMaxSize, getMaxSize, xmlElement, mode);
113        XMLPortParam(NotificationQueue, "notificationLength", setNotificationLength, getNotificationLength, xmlElement, mode);
114        XMLPortParam(NotificationQueue, "displayTime", setDisplayTime, getDisplayTime, xmlElement, mode);
115        XMLPortParam(NotificationQueue, "targets", setTargets, getTargets, xmlElement, mode);
116        XMLPortParam(NotificationQueue, "font", setFont, getFont, xmlElement, mode);
117        XMLPortParam(NotificationQueue, "fontSize", setFontSize, getFontSize, xmlElement, mode);
118        XMLPortParam(NotificationQueue, "position", setPosition, getPosition, xmlElement, mode);
119
120        COUT(3) << "NotificationQueue created." << std::endl;
121    }
122
123    /**
124    @brief
125        Updates the queue from time to time.
126    @param dt
127        The time interval that has passed since the last tick.
128    */
129    void NotificationQueue::tick(float dt)
130    {
131        this->tickTime_ += dt; //!< Add the time interval that has passed to the time counter.
132        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.
133        {
134            this->timeLimit_.time = std::time(0)-this->displayTime_; //!< Container containig the current time.
135
136            std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it;
137            it = this->containers_.begin();
138            while(it != this->containers_.upper_bound(&this->timeLimit_)) //!< Iterate through all elements whose creation time is smaller than the current time minus the display time.
139            {
140                this->removeContainer(*it);
141                this->scroll(Vector2(0.0,-(1.1*this->getFontSize())));
142                it = this->containers_.begin(); //TDO: Needed?
143            }
144
145            this->tickTime_ = 0.0; //!< Reset time counter.
146        }
147    }
148
149    /**
150    @brief
151        Updates the NotificationQueue.
152        Updates by clearing the queue and requesting all relevant Notifications from the NotificationManager and inserting the in the queue.
153    */
154    void NotificationQueue::update(void)
155    {
156        this->clear();
157
158        std::multimap<std::time_t,Notification*>* notifications = new std::multimap<std::time_t,Notification*>;
159        if(!NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_)) //!< Get the Notifications sent in the interval form now to minus the display time.
160        {
161            COUT(1) << "NotificationQueue update failed due to undetermined cause." << std::endl;
162            return;
163        }
164
165        if(notifications->empty())
166            return;
167
168        for(std::multimap<std::time_t,Notification*>::iterator it = notifications->begin(); it != notifications->end(); it++) //!> Add all Notifications.
169        {
170            this->addNotification(it->second, it->first);
171        }
172
173        delete notifications;
174
175        COUT(3) << "NotificationQueue updated." << std::endl;
176    }
177
178    /**
179    @brief
180        Updates the NotificationQueue by adding an new Notification.
181    @param notification
182        Pointer to the Notification.
183    @param time
184        The time the Notification was sent.
185    */
186    void NotificationQueue::update(Notification* notification, const std::time_t & time)
187    {
188        this->addNotification(notification, time);
189
190        std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it;
191        while(this->getSize() > this->getMaxSize())
192        {
193            it = this->containers_.begin();
194            this->removeContainer(*it);
195            this->scroll(Vector2(0.0,-(1.1*this->getFontSize())));
196        }
197
198        COUT(3) << "NotificationQueue updated. A new Notifications has been added." << std::endl;
199    }
200
201    /**
202    @brief
203        Sets the maximum number of displayed Notifications.
204    @param size
205        The size to be set.
206    @return
207        Returns true if successful.
208    */
209    bool NotificationQueue::setMaxSize(int size)
210    {
211        if(size < 0)
212            return false;
213        this->maxSize_ = size;
214        this->update();
215        return true;
216    }
217
218    /**
219    @brief
220        Sets the maximum number of characters a Notification message displayed by this queue is allowed to have.
221    @param length
222        The length to be set.
223    @return
224        Returns true if successful.
225    */
226    bool NotificationQueue::setNotificationLength(int length)
227    {
228        if(length < 0)
229            return false;
230        this->notificationLength_ = length;
231        this->update();
232        return true;
233    }
234
235    /**
236    @brief
237        Sets the maximum number of seconds a Notification is displayed.
238    @param time
239        The number of seconds the Notifications is displayed.
240    @return
241        Returns true if successful.
242    */
243    bool NotificationQueue::setDisplayTime(int time)
244    {
245        if(time < 0)
246            return false;
247        this->displayTime_ = time;
248        this->update();
249        return true;
250    }
251
252    /**
253    @brief
254        Produces all targets concatinated as string, with kommas (',') as seperators.
255    @param string
256        Pointer to a string which will be used by the method to fill with the concatination of the targets.
257    @return
258        Returns true if successful.
259    */
260    bool NotificationQueue::getTargets(std::string* string) const
261    {
262        if(string == NULL)
263        {
264            COUT(4) << "Input string must have memory allocated." << std::endl;
265            return false;
266        }
267        string->clear();
268        bool first = true;
269        for(std::set<std::string>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++) //!< Iterate through the set of targets.
270        {
271            if(!first)
272            {
273                *string += ",";
274            }
275            else
276            {
277                first = false;
278            }
279            *string += *it;
280        }
281
282        return true;
283    }
284
285    /**
286    @brief
287        Sets the targets of the queue.
288        The targets are the senders whose Notifications are displayed in this queue.
289    @param targets
290        Accepts a string of targets, each seperated by commas (','), spaces are ignored.
291    @return
292        Returns true if successful.
293    */
294    bool NotificationQueue::setTargets(const std::string & targets)
295    {
296        this->targets_.clear();
297
298        std::string* pTemp;
299        unsigned int index = 0;
300        while( index < targets.size() ) //!< Go through the string, character by character until the end is reached.
301        {
302            pTemp = new std::string("");
303            while(index < targets.size() && targets[index] != ',' && targets[index] != ' ')
304            {
305                *pTemp += targets[index];
306                index++;
307            }
308            index++;
309            this->targets_.insert(*pTemp);
310        }
311
312        return true;
313    }
314
315    /**
316    @brief
317        Sets the font size.
318    @param size
319        The font size.
320    @return
321        Returns true if successful.
322    */
323    bool NotificationQueue::setFontSize(float size)
324    {
325        if(size <= 0)
326            return false;
327        this->fontSize_ = size;
328        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); it++) //!< Set the font size for each overlay.
329        {
330            it->second->overlay->setFontSize(size);
331        }
332        return true;
333    }
334
335    /**
336    @brief
337        Sets the font.
338    @param font
339        The font.
340    @return
341        Returns true if successful.
342    */
343    bool NotificationQueue::setFont(const std::string & font)
344    {
345        this->font_ = font;
346        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); it++) //!< Set the font for each overlay.
347        {
348            it->second->overlay->setFont(font);
349        }
350        return true;
351    }
352
353    /**
354    @brief
355        Scrolls the NotificationQueue, meaning all NotificationOverlays are moved the input vector.
356    @param pos
357        The vector the NotificationQueue is scrolled.
358    */
359    void NotificationQueue::scroll(const Vector2 pos)
360    {
361        for (std::map<Notification*, NotificationOverlayContainer*>::iterator it = this->overlays_.begin(); it != this->overlays_.end(); ++it) //!< Scroll each overlay.
362        {
363            it->second->overlay->scroll(pos);
364        }
365    }
366
367    /**
368    @brief
369        Aligns all the Notifications to the position of the NotificationQueue.
370    */
371    void NotificationQueue::positionChanged(void)
372    {
373        int counter = 0;
374        for (std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it = this->containers_.begin(); it != this->containers_.end(); it++) //!< Set the position for each overlay.
375        {
376            (*it)->overlay->setPosition(this->getPosition());
377            (*it)->overlay->scroll(Vector2(0.0,(1.1*this->getFontSize())*counter));
378            counter++;
379        }
380    }
381
382    /**
383    @brief
384        Adds a Notification, to the queue.
385        It inserts it into the storage containers, creates an corresponding overlay and a container.
386    @param notification
387        The Notification.
388    @param time
389        The time.
390    */
391    void NotificationQueue::addNotification(Notification* notification, const std::time_t & time)
392    {
393        NotificationOverlayContainer* container = new NotificationOverlayContainer;
394        container->overlay = new NotificationOverlay(this, notification);
395        container->notification = notification;
396        container->time = time;
397        std::string timeString = std::ctime(&time);
398        timeString.erase(timeString.length()-1);
399        std::ostringstream stream;
400        stream << (unsigned long)notification;
401        std::string addressString = stream.str() ;
402        container->name = "NotificationOverlay(" + timeString + ")&" + addressString;
403
404        this->containers_.insert(container);
405        this->overlays_[notification] = container;
406        this->addElement(container->overlay);
407        this->size_= this->size_+1;
408
409        container->overlay->scroll(Vector2(0.0,(1.1*this->getFontSize())*(this->getSize()-1)));
410    }
411
412    /**
413    @brief
414        Removes a container from the queue.
415    @param container
416        A pointer to the container.
417    @return
418        Returns true if successful.
419    */
420    bool NotificationQueue::removeContainer(NotificationOverlayContainer* container)
421    {
422        if(this->size_ == 0) //!< You cannot remove anything if the queue is empty.
423            return false;
424
425        this->removeElement(container->overlay);
426        this->containers_.erase(container);
427        this->overlays_.erase(container->notification);
428        delete container->overlay;
429        delete container;
430        this->size_= this->size_-1;
431
432        return true;
433    }
434
435    /**
436    @brief
437        Clears the queue by removing all containers.
438    */
439    void NotificationQueue::clear(void)
440    {
441        std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare>::iterator it = this->containers_.begin();
442        while(it != this->containers_.end())
443        {
444            this->removeContainer(*it);
445            it = this->containers_.begin(); //TDO: Needed?
446        }
447    }
448
449}
Note: See TracBrowser for help on using the repository browser.