Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/modules/questsystem/notifications/NotificationQueue.cc @ 6126

Last change on this file since 6126 was 5929, checked in by rgrieder, 15 years ago

Merged core5 branch back to the trunk.
Key features include clean level unloading and an extended XML event system.

Two important notes:
Delete your keybindings.ini files! * or you will still get parser errors when loading the key bindings.
Delete build_dir/lib/modules/libgamestates.module! * or orxonox won't start.
Best thing to do is to delete the build folder ;)

  • 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().registerListener(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(); //TODO: 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 << reinterpret_cast<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        container->overlay->destroy();
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(); //TODO: Needed?
446        }
447    }
448
449}
Note: See TracBrowser for help on using the repository browser.