Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 2786 was 2785, checked in by dafrick, 16 years ago

Made QuestManager and NotificationManager to Singletons. Fixed/Changed som other stuff I don't remember…

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