Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Some documenting and adjustment.

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