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
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 "NotificationQueue.h"
35
36#include <algorithm>
37
38#include "util/Convert.h"
39#include "core/CoreIncludes.h"
40#include "core/GUIManager.h"
41#include "core/LuaState.h"
42#include "Notification.h"
43
44namespace orxonox
45{
46
47    const Vector2 NotificationQueue::DEFAULT_POSITION(0.0,0.0);
48
49    /**
50    @brief
51        Constructor. Creates and initializes the object.
52    */
53    NotificationQueue::NotificationQueue(const std::string& name, const std::string& senders, unsigned int size, const Vector2& position, unsigned int displayTime)
54    {
55        this->registered_ = false;
56
57        RegisterRootObject(NotificationQueue);
58
59        this->initialize();
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();
68        this->positionChanged();
69
70        NotificationManager::getInstance().registerListener(this);
71        this->registered_ = true;
72
73        COUT(3) << "NotificationQueue '" << this->getName() << "' created." << std::endl;
74    }
75
76    /**
77    @brief
78        Destructor.
79    */
80    NotificationQueue::~NotificationQueue()
81    {
82        this->targets_.clear();
83        this->clear();
84
85        if(this->registered_)
86            NotificationManager::getInstance().unregisterListener(this);
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    /**
101    @brief
102        Creates the NotificationQueue in lua.
103    */
104    void NotificationQueue::create(void)
105    {
106        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.createQueue(\"" + this->getName() + "\", " + multi_cast<std::string>(this->getMaxSize()) + ")");
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    {
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.
119        {
120            this->timeLimit_.time = std::time(0)-this->displayTime_; // Container containig the current time.
121
122            std::multiset<NotificationContainer*, NotificationContainerCompare>::iterator it = this->ordering_.begin();
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.
124            {
125                NotificationContainer* temp = *it;
126                it++;
127                this->remove(temp);
128            }
129
130            this->tickTime_ = this->tickTime_ - (int)this->tickTime_; // Reset time counter.
131        }
132    }
133
134    /**
135    @brief
136        Updates the NotificationQueue.
137        Updates by clearing the queue and requesting all relevant Notifications from the NotificationManager and inserting them into the queue.
138    */
139    void NotificationQueue::update(void)
140    {
141        this->clear();
142
143        std::multimap<std::time_t, Notification*>* notifications = new std::multimap<std::time_t, Notification*>;
144        if(!NotificationManager::getInstance().getNotifications(this, notifications, this->displayTime_)) // Get the Notifications sent in the interval form now to minus the display time.
145        {
146            COUT(1) << "NotificationQueue update failed due to undetermined cause." << std::endl;
147            return;
148        }
149
150        if(notifications->empty())
151            return;
152
153        for(std::multimap<std::time_t, Notification*>::iterator it = notifications->begin(); it != notifications->end(); it++) // Add all Notifications.
154            this->push(it->second, it->first);
155
156        delete notifications;
157
158        COUT(4) << "NotificationQueue '" << this->getName() << "' updated." << std::endl;
159    }
160
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)
170    {
171        this->push(notification, time);
172
173        COUT(4) << "NotificationQueue '" << this->getName() << "' updated. A new Notification has been added." << std::endl;
174    }
175
176    /**
177    @brief
178        Adds a Notification to the NotificationQueue.
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
236        Clears the queue by removing all Notifications.
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;
243
244        this->notifications_.clear();
245        this->size_ = 0;
246        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.clearQueue(\"" + this->getName() + "\")");
247    }
248
249    /**
250    @brief
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
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;
271    }
272
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    */
281    void NotificationQueue::setMaxSize(unsigned int size)
282    {
283        this->maxSize_ = size;
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()) + ")");
294        this->update();
295    }
296
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    */
305    void NotificationQueue::setDisplayTime(unsigned int time)
306    {
307        this->displayTime_ = time;
308        this->update();
309    }
310
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;
328        for(std::set<std::string>::const_iterator it = this->targets_.begin(); it != this->targets_.end(); it++) // Iterate through the set of targets.
329        {
330            if(!first)
331                *string += ',';
332            else
333                first = false;
334            *string += *it;
335        }
336
337        return true;
338    }
339
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)
350    {
351        this->targets_.clear();
352
353        std::string* pTemp;
354        unsigned int index = 0;
355        while(index < targets.size()) // Go through the string, character by character until the end is reached.
356        {
357            pTemp = new std::string();
358            while(index < targets.size() && targets[index] != ',' && targets[index] != ' ')
359            {
360                *pTemp += targets[index];
361                index++;
362            }
363            index++;
364            this->targets_.insert(*pTemp);
365        }
366
367        return true;
368    }
369
370}
Note: See TracBrowser for help on using the repository browser.