Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/questsystem5/src/orxonox/overlays/notifications/NotificationQueue.cc @ 2961

Last change on this file since 2961 was 2908, checked in by dafrick, 16 years ago

Reverted to revision 2906 (because I'm too stupid to merge correctly, 2nd try will follow shortly. ;))

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