Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Apr 8, 2009, 1:07:27 AM (15 years ago)
Author:
dafrick
Message:

Merging the QuestSystem branch to the trunk. Let's hope, this isn't a 'third time's the charm'-thing…

File:
1 edited

Legend:

Unmodified
Added
Removed
  • code/trunk/src/orxonox/overlays/notifications/NotificationQueue.cc

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