Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Changing from OrxonoxOverlays to CEGUI as means of displaying Notifications.
Still messy and not working completely but it's a start.

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