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…

Location:
code/trunk/src/orxonox/overlays
Files:
2 added
9 edited

Legend:

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

    r2890 r2909  
    113113    }
    114114
     115    /**
     116    @brief
     117        Removes an element from the map.
     118    @param element
     119        The element that is to be removed.
     120    @return
     121        Returns true if there was such an element to remove, false if not.
     122    */
     123    bool OverlayGroup::removeElement(OrxonoxOverlay* element)
     124    {
     125        if(this->hudElements_.erase(element) == 0)
     126            return false;
     127        return true;
     128    }
     129
    115130    //! Returns a different element as long as index < hudElements_.size().
    116131    OrxonoxOverlay* OverlayGroup::getElement(unsigned int index)
  • code/trunk/src/orxonox/overlays/OverlayGroup.h

    r2890 r2909  
    3838
    3939#include <set>
     40#include <string>
    4041#include <OgrePrerequisites.h>
    4142#include "core/BaseObject.h"
     
    8687
    8788        void addElement(OrxonoxOverlay* element);
     89        bool removeElement(OrxonoxOverlay* element);
    8890        OrxonoxOverlay* getElement(unsigned int index);
    8991
  • code/trunk/src/orxonox/overlays/notifications/CMakeLists.txt

    r2710 r2909  
    22  Notification.cc
    33  NotificationManager.cc
     4  NotificationOverlay.cc
    45  NotificationQueue.cc
    56)
  • code/trunk/src/orxonox/overlays/notifications/Notification.cc

    r2662 r2909  
    2727 */
    2828
     29/**
     30    @file Notification.cc
     31    @brief Implementation of the Notification class.
     32*/
     33
    2934#include "OrxonoxStableHeaders.h"
    3035#include "Notification.h"
    3136
    3237#include "core/CoreIncludes.h"
     38#include "util/Exception.h"
    3339
    3440#include "NotificationManager.h"
     
    3642namespace orxonox
    3743{
     44
     45    /**
     46    @brief
     47        Default constructor. Initializes the object.
     48    */
    3849    Notification::Notification(BaseObject* creator) : BaseObject(creator)
    3950    {
    40         RegisterObject(Notification);
     51        this->initialize();
    4152    }
    4253   
    43     Notification::Notification(BaseObject* creator, const std::string & message, const std::string & title, float time) : BaseObject(creator)
     54    /**
     55    @brief
     56        Constructor. Creates a Notification with the input message.
     57    @param message
     58        The message of the Notification.
     59    */
     60    Notification::Notification(const std::string & message) : BaseObject(this)
    4461    {
    45         this->title_ = title;
    4662        this->message_ = message;
    47         if(time > 0)
    48             this->displayTime_ = time;
    4963    }
    5064   
     65    /**
     66    @brief
     67        Destructor.
     68    */
    5169    Notification::~Notification()
    5270    {
    5371    }
    5472   
     73    /**
     74    @brief
     75        Registers the object and sets some default values.
     76    */
    5577    void Notification::initialize(void)
    5678    {
    5779        RegisterObject(Notification);
    5880       
    59         this->title_ = "";
    6081        this->message_ = "";
    61         this->displayTime_ = NOTIFICATION_DISPLAY_TIME;
     82        this->sender_ = NotificationManager::NONE;
    6283        this->sent_ = false;
    6384    }
    6485   
     86    /**
     87    @brief
     88        Sends the Notification to the Notificationmanager, with sender NetificationManager::NONE.
     89    @return
     90        Returns true if successful.
     91    */
    6592    bool Notification::send(void)
    6693    {
    67         bool successful = NotificationManager::insertNotification(this);
    68         if(successful)
    69             this->sent_ = true;
    70         return successful;
     94        return this->send(NotificationManager::NONE);
    7195    }
    7296   
    73     bool Notification::setTitle(const std::string & title)
     97    /**
     98    @brief
     99        Sends the Notification to the Notificationmanager, which then in turn distributes it to the different NotificationQueues.
     100    @param sender
     101        The sender the Notification was sent by. Used by the NotificationManager to distributes the notification to the correct NotificationQueues.
     102    @return
     103        Returns true if successful.
     104    */
     105    bool Notification::send(const std::string & sender)
    74106    {
    75         if(this->isSent())
     107        this->sender_ = sender;
     108        bool successful = NotificationManager::getInstance().registerNotification(this);
     109        if(!successful)
    76110            return false;
    77         this->title_ = title;
     111        this->sent_ = true;
     112       
     113        COUT(3) << "Notification \"" << this->getMessage() << "\" sent." << std::endl;
     114       
    78115        return true;
    79116    }
    80117   
     118    /**
     119    @brief
     120        Sets the message of the notification.
     121    @param message
     122        The message to be set.
     123    @return
     124        Returns true if successful.
     125    */
    81126    bool Notification::setMessage(const std::string & message)
    82127    {
    83         if(this->isSent())
     128        if(this->isSent()) //!< The message cannot be changed if the message has already been sent.
    84129            return false;
    85130        this->message_ = message;
    86131        return true;
    87132    }
    88    
    89     bool Notification::setDisplayTime(float time)
    90     {
    91         if(this->isSent())
    92         {
    93             return false;
    94         }
    95         if(time > 0)
    96         {
    97             this->displayTime_ = time;
    98             return true;
    99         }
    100         return false;
    101     }
     133
    102134}
  • code/trunk/src/orxonox/overlays/notifications/Notification.h

    r2662 r2909  
    2727 */
    2828
     29/**
     30    @file Notification.h
     31    @brief Definition of the Notification class.
     32*/
     33
    2934#ifndef _Notification_H__
    3035#define _Notification_H__
     
    3843namespace orxonox
    3944{
    40     static const float NOTIFICATION_DISPLAY_TIME = 4.0;
    4145
    4246    /**
    4347    @brief
    44         This is rather temporary, so don't start relying on it, some better version will come soon but the Interface will not likely be the same.
     48        A Notification is a short message used to inform the player about something that just happened. A Notification can be sent from any part of orxonox and is then displayed in the proper NotificationQueue (depending on which senders the specific NotificationQueue accepts).
    4549    @author
    4650        Damian 'Mozork' Frick
     
    4852    class _OrxonoxExport Notification : public BaseObject
    4953    {
    50     public:
    51         Notification(BaseObject* creator);
    52         Notification(BaseObject* creator, const std::string & message, const std::string & title = "", float time = NOTIFICATION_DISPLAY_TIME);
    53         virtual ~Notification();
    54        
    55         bool send(void);
    56        
    57         inline bool isSent(void) const
    58             { return this->sent_; }
    59         inline const std::string & getTitle(void) const
    60             { return this->title_; }
    61         inline const std::string & getMessage(void) const
    62             { return this->message_; }
    63         inline const float getDisplayTime(void) const
    64             { return displayTime_; }
    65        
    66         bool setTitle(const std::string & title);
    67         bool setMessage(const std::string & message);
    68         bool setDisplayTime(float time);
    69        
    70     private:
    71         std::string title_; //!< The title of the Notification.
    72         std::string message_; //!< The Notification message.
    73         float displayTime_; //!< The time duration the Notification is displayed in seconds.
    74         bool sent_; //!< Whether Notification has been sent, if so it cannot be changed.
    75        
    76         void initialize(void);
     54        public:
     55            Notification(BaseObject* creator);
     56            Notification(const std::string & message);
     57            virtual ~Notification();
     58           
     59            bool send(void); //!< Sends the Notification to the Notificationmanager, with sender NotificationManager::NONE;
     60            bool send(const std::string & sender); //!< Sends the Notification to the Notificationmanager.
     61           
     62            /**
     63            @brief Checks whether the Notification was sent.
     64            @return Returns true if the Notification was sent already.
     65            */
     66            inline bool isSent(void) const
     67                { return this->sent_; }
     68            /**
     69            @brief Returns the message of the Notification.
     70            @return Returns the message of the Notification.
     71            */
     72            inline const std::string & getMessage(void) const
     73                { return this->message_; }
     74               
     75            inline const std::string & getSender(void) const
     76                { return this->sender_; }
     77           
     78            bool setMessage(const std::string & message); //!< Sets the message of the notification.
     79           
     80        private:
     81            std::string message_; //!< The Notification message.
     82            std::string sender_; //!< The sender of the notification.
     83            bool sent_; //!< Whether Notification has been sent, if so it cannot be changed.
     84           
     85            void initialize(void);
     86       
    7787    };
     88
    7889}
    7990
  • code/trunk/src/orxonox/overlays/notifications/NotificationManager.cc

    r2662 r2909  
    2727 */
    2828
     29/**
     30    @file NotificationManager.cc
     31    @brief Implementation of the NotificationManager class.
     32*/
     33
    2934#include "OrxonoxStableHeaders.h"
    3035#include "NotificationManager.h"
     
    3237#include "core/CoreIncludes.h"
    3338
     39#include <set>
     40
    3441#include "Notification.h"
    35 
    3642#include "NotificationQueue.h"
    3743
    3844namespace orxonox
    3945{
    40     std::list<NotificationContainer*> NotificationManager::notifications_s;
    41 
    42     NotificationManager::NotificationManager(BaseObject* creator) : BaseObject(creator)
    43     {
    44         RegisterObject(NotificationManager);
    45     }
    46 
     46
     47    const std::string NotificationManager::ALL = "all";
     48    const std::string NotificationManager::NONE = "none";
     49
     50    NotificationManager* NotificationManager::singletonRef_s = NULL;
     51
     52    /**
     53    @brief
     54        Constructor. Registers the Object.
     55    */
     56    NotificationManager::NotificationManager()
     57    {
     58        RegisterRootObject(NotificationManager);
     59
     60        assert(singletonRef_s == 0);
     61        singletonRef_s = this;
     62
     63        this->highestIndex_ = 0;
     64    }
     65
     66    /**
     67    @brief
     68        Destructor.
     69    */
    4770    NotificationManager::~NotificationManager()
    4871    {
    49         //TDO: Destroy the containers
    50     }
    51 
    52     void NotificationManager::tick(float dt)
    53     {
    54         bool update = false;
    55 
    56         for (std::list<NotificationContainer*>::iterator notification = notifications_s.begin(); notification != notifications_s.end(); ++notification)
    57         {
    58             NotificationContainer* container = *notification;
    59             if(container->remainingTime == 0)
     72    }
     73
     74    /**
     75    @brief
     76        Returns the current (and single) instance of the NotificationManager. Creates one, if there isn't one to begin with.
     77    @return
     78        Returns a reference to the single instance of the NotificationManager.
     79    */
     80    /*static*/ NotificationManager & NotificationManager::getInstance()
     81    {
     82        assert(singletonRef_s);
     83        return *singletonRef_s;
     84    }
     85   
     86    /**
     87    @brief
     88        Registers a Notification within the NotificationManager and makes sure that the Notification is displayed in all the NotificationQueues associated with its sender.
     89    @param notification
     90        The Notification to be registered.
     91    @return
     92        Returns true if successful.
     93    */
     94    bool NotificationManager::registerNotification(Notification* notification)
     95    {
     96   
     97        if(notification == NULL) //!< A NULL-Notification cannot be registered.
     98            return false;
     99       
     100        std::time_t time = std::time(0); //TDO: Doesn't this expire? //!< Get current time.
     101       
     102        this->allNotificationsList_.insert(std::pair<std::time_t,Notification*>(time,notification));
     103       
     104        if(notification->getSender() == NONE) //!< If the sender has no specific name, then the Notification is only added to the list of all Notifications.
     105            return true;
     106       
     107        bool all = false;
     108        if(notification->getSender() == ALL) //!< If all are the sender, then the Notifications is added to every NotificationQueue.
     109            all = true;
     110       
     111        //!< Insert the notification in all queues that have its sender as target.
     112        for(std::map<NotificationQueue*,int>::iterator it = this->queueList_.begin(); it != this->queueList_.end(); it++) //!< Iterate through all queues.
     113        {
     114            std::set<std::string> set = it->first->getTargetsSet();
     115            if(all || set.find(notification->getSender()) != set.end() || set.find(ALL) != set.end()) //TDO: Make sure this works.
    60116            {
    61                 continue;
     117                this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); //!< Insert the Notification in the Notifications list of the current NotificationQueue.
     118                it->first->update(notification, time); //!< Update the queue.
    62119            }
    63             else if(container->remainingTime - dt <= 0)
     120        }
     121       
     122        COUT(3) << "Notification registered with the NotificationManager." << std::endl;
     123       
     124        return true;
     125    }
     126   
     127    /**
     128    @brief
     129        Registers a NotificationQueue within the NotificationManager.
     130    @param queue
     131        The NotificationQueue to be registered.
     132    @return
     133        Returns true if successful.
     134    */
     135    bool NotificationManager::registerQueue(NotificationQueue* queue)
     136    {
     137        this->highestIndex_ += 1;
     138        int index = this->highestIndex_;
     139       
     140        this->queueList_[queue] = index; //!< Add the NotificationQueue to the list of queues.
     141       
     142        std::set<std::string> set = queue->getTargetsSet(); //TDO: Works this?
     143       
     144        //! If all senders are the target of the queue, then the list of notification for that specific queue is te same as the list of all Notifications.
     145        if(set.find(ALL) != set.end())
     146        {
     147            this->notificationLists_[index] = &this->allNotificationsList_;
     148            COUT(3) << "NotificationQueue registered with the NotificationManager." << std::endl;
     149            return true;
     150        }
     151       
     152        this->notificationLists_[index] = new std::multimap<std::time_t,Notification*>;
     153        std::multimap<std::time_t,Notification*> map = *this->notificationLists_[index];
     154       
     155        //! Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationQueue.
     156        for(std::multimap<std::time_t,Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
     157        {
     158            if(set.find(it->second->getSender()) != set.end()) //!< Checks whether the overlay has the sender of the current notification as target.
    64159            {
    65                 container->remainingTime = 0;
    66                 update = true;
     160                map.insert(std::pair<std::time_t,Notification*>(it->first, it->second));
    67161            }
    68             else
    69             {
    70                 container->remainingTime = container->remainingTime -dt;
    71             }
    72         }
    73 
    74         if(update)
    75             updateQueue();
    76     }
    77 
    78     bool NotificationManager::insertNotification(Notification* notification)
    79     {
    80         if(notification == NULL)
     162        }
     163       
     164        queue->update(); //!< Update the queue.
     165
     166        COUT(3) << "NotificationQueue registered with the NotificationManager." << std::endl;
     167       
     168        return true;
     169    }
     170   
     171    /**
     172    @brief
     173        Fetches the Notifications for a specific NotificationQueue in a specified timeframe.
     174    @param queue
     175        The NotificationQueue the Notifications are fetched for.
     176    @param map
     177        A multimap, in which the notifications are stored.
     178    @param timeFrameStart
     179        The start time of the timeframe.
     180    @param timeFrameEnd
     181        The end time of the timeframe.
     182    @return
     183        Returns true if successful.
     184    */
     185    bool NotificationManager::getNotifications(NotificationQueue* queue, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
     186    {
     187        if(queue == NULL || map == NULL)
    81188            return false;
    82189
    83         NotificationContainer* container = new NotificationContainer;
    84         container->notification = notification;
    85         container->remainingTime = notification->getDisplayTime();
    86         notifications_s.push_front(container);
    87 
    88         updateQueue();
    89 
    90         COUT(4) << "Notification inserted. Title: " << notification->getTitle() << std::endl;
    91 
     190        std::multimap<std::time_t,Notification*>* notifications = this->notificationLists_[this->queueList_[queue]]; //!< The Notifications for the input NotificationQueue.
     191       
     192        if(notifications == NULL) //!< Returns NULL, if there are no Notifications.
     193            return true;
     194   
     195        std::multimap<std::time_t,Notification*>::iterator it, itLowest, itHighest;
     196        itLowest = notifications->lower_bound(timeFrameStart);
     197        itHighest = notifications->upper_bound(timeFrameStart);
     198       
     199        for(it = itLowest; it != itHighest; it++) //!< Iterate through the Notifications from the start of the time Frame to the end of it.
     200        {
     201            map->insert(std::pair<std::time_t,Notification*>(it->first,it->second)); //!< Add the found Notifications to the map.
     202        }
     203       
    92204        return true;
    93205    }
    94206
    95     void NotificationManager::updateQueue(void)
    96     {
    97         std::string text = "";
    98 
    99         if (!NotificationQueue::queue_s)
    100             return;
    101 
    102         int i = NotificationQueue::queue_s->getLength();
    103         for (std::list<NotificationContainer*>::iterator notification = notifications_s.begin(); notification != notifications_s.end() && i > 0; ++notification)
    104         {
    105             i--;
    106             NotificationContainer* container = *notification;
    107             if(container->remainingTime == 0.0)
    108                 continue;
    109 
    110             text = text + "\n\n\n------------\n\n" + clipMessage(container->notification->getTitle()) + "\n\n" + clipMessage(container->notification->getMessage());
    111         }
    112 
    113         NotificationQueue::queue_s->setQueueText(text);
    114     }
    115 
    116     const std::string NotificationManager::clipMessage(const std::string & str)
    117     {
    118 
    119         std::string message = str;
    120         unsigned int i = 0;
    121 
    122         unsigned int found = message.find("\\n", i);
    123         while(found != std::string::npos)
    124         {
    125             message.replace(found, 2, "\n");
    126             i = found+2;
    127             found = message.find("\\n", i);
    128         }
    129 
    130         std::string clippedMessage = "";
    131         int wordLength = 0;
    132         i = 0;
    133         int widthLeft = NotificationQueue::queue_s->getWidth();
    134         while(i < message.length())
    135         {
    136             while(i < message.length() && message[i] != ' ' && message[i] != '\n')
    137             {
    138                 i++;
    139                 wordLength++;
    140             }
    141 
    142             if(wordLength <= widthLeft)
    143             {
    144                 clippedMessage = clippedMessage + message.substr(i-wordLength, wordLength);
    145                 if(i < message.length())
    146                 {
    147                     clippedMessage = clippedMessage + message.substr(i,1);
    148                 }
    149                 widthLeft -= (wordLength+1);
    150                 if(message[i] == '\n')
    151                 {
    152                     widthLeft = NotificationQueue::queue_s->getWidth() - (wordLength+1);
    153                 }
    154                 wordLength = 0;
    155                 i++;
    156             }
    157             else
    158             {
    159                 clippedMessage.push_back('\n');
    160                 clippedMessage = clippedMessage + message.substr(i-wordLength, wordLength);
    161                 if(i < message.length())
    162                 {
    163                     clippedMessage = clippedMessage + message.substr(i,1);
    164                 }
    165                 widthLeft = NotificationQueue::queue_s->getWidth() - (wordLength+1);
    166                 i++;
    167                 wordLength = 0;
    168             }
    169         }
    170 
    171         return clippedMessage;
    172     }
    173 
    174207}
  • code/trunk/src/orxonox/overlays/notifications/NotificationManager.h

    r2662 r2909  
    2727 */
    2828
     29/**
     30    @file NotificationManager.h
     31    @brief Definition of the NotificationManager class.
     32*/
     33
    2934#ifndef _NotificationManager_H__
    3035#define _NotificationManager_H__
     
    3237#include "OrxonoxPrereqs.h"
    3338
    34 #include "core/BaseObject.h"
     39#include "core/OrxonoxClass.h"
    3540
    36 #include <list>
     41#include <map>
    3742#include <string>
     43#include <ctime>
     44
     45#include "NotificationOverlay.h"
    3846
    3947namespace orxonox
    4048{
    41     struct NotificationContainer
    42     {
    43         Notification* notification;
    44         float remainingTime;
    45     };
    4649
    4750    /**
    4851    @brief
    49        
     52        The Singleton NotificationManager functions as a gateway between Notifications and NotificationQueues.
     53        It receives, organizes Notifications and the redistributes them to the specific NotificationQueues.
    5054    @author
    5155        Damian 'Mozork' Frick
    5256    */
    53     class _OrxonoxExport NotificationManager : public BaseObject
     57    class _OrxonoxExport NotificationManager : public OrxonoxClass
    5458    {
    55    
    56     public:
    57         NotificationManager(BaseObject* creator);
    58         virtual ~NotificationManager();
     59        public:
     60            NotificationManager();
     61            virtual ~NotificationManager();
     62               
     63            static const std::string ALL;
     64            static const std::string NONE;
     65         
     66            static NotificationManager & getInstance(); //! Returns a reference to the single instance of the NotificationManager.
     67
     68            bool registerNotification(Notification* notification); //!< Registers a Notification within the NotificationManager.
     69            bool registerQueue(NotificationQueue* queue); //!< Registers a NotificationQueue within the NotificationManager.
     70           
     71            bool getNotifications(NotificationQueue* queue, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd); //!< Returns the Notifications for a specific NotificationQueue in a specified timeframe.
     72           
     73            /**
     74            @brief Fetches the Notifications for a specific NotificationQueue starting at a specified time.
     75            @param queue The NotificationQueue the Notifications are fetched for.
     76            @param map A multimap, in which the notifications are stored.
     77            @param timeFrameStart The start time the Notifications are fetched from.
     78            @return Returns true if successful.
     79            */
     80            bool getNotifications(NotificationQueue* queue, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart)
     81                { return this->getNotifications(queue, map, timeFrameStart, std::time(0)); }
     82            /**
     83            @brief Fetches the Notifications for a specific NotificationQueue starting at a specified timespan before now.
     84            @param queue The NotificationQueue the Notifications are fetched for.
     85            @param map A multimap, in which the notifications are stored.
     86            @param timeDelay The timespan.
     87            @return Returns true if successful.
     88            */
     89            bool getNotifications(NotificationQueue* queue, std::multimap<std::time_t,Notification*>* map, int timeDelay)
     90                { return this->getNotifications(queue, map, std::time(0)-timeDelay, std::time(0)); }
     91     
     92        private:
     93            static NotificationManager* singletonRef_s;
     94
     95            int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that  no key appears twice.
    5996       
    60         static bool insertNotification(Notification* notification);
    61        
    62         static void tick(float dt);
    63        
    64     private:
    65         static std::list<NotificationContainer*> notifications_s;
    66        
    67         static void updateQueue(void);
    68         static const std::string clipMessage(const std::string & message);
     97            std::multimap<std::time_t,Notification*> allNotificationsList_; //!< Container where all notifications are stored (together with their respecive timestamps).
     98            std::map<NotificationQueue*,int> queueList_; //!< Container where all NotificationQueues are stored with a number as identifier.
     99            std::map<int,std::multimap<std::time_t,Notification*>*> notificationLists_; //!< Container where all Notifications, for each identifier (associated with a NotificationQueue), are stored.
     100           
    69101
    70102    };
  • 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}
  • code/trunk/src/orxonox/overlays/notifications/NotificationQueue.h

    r2662 r2909  
    2727 */
    2828
     29/**
     30    @file NotificationQueue.h
     31    @brief Definition of the NotificationQueue class.
     32*/
     33
    2934#ifndef _NotificationOueue_H__
    3035#define _NotificationOueue_H__
    3136
    3237#include "OrxonoxPrereqs.h"
     38
     39#include <string>
     40#include <set>
     41#include <OgreOverlayManager.h>
    3342#include <OgreTextAreaOverlayElement.h>
    34 
    35 #include "orxonox/overlays/OverlayText.h"
     43#include <OgrePanelOverlayElement.h>
     44#include <map>
     45#include <ctime>
     46
     47#include "orxonox/overlays/OverlayGroup.h"
    3648#include "orxonox/objects/Tickable.h"
    3749
    38 #include <string>
     50#include "NotificationManager.h"
    3951
    4052namespace orxonox
    4153{
     54
     55    //! Container to allow easy handling.
     56    struct NotificationOverlayContainer
     57    {
     58        NotificationOverlay* overlay; //!< Pointer to the NotificationOverlay, everything is about.
     59        Notification* notification; //!< The Notification displayed by the overlay.
     60        time_t time; //!< The time the Notification was sent and thus first displayed.
     61        std::string name; //!< The name of the overlay.
     62    };
     63   
     64    //! Struct to allow ordering of NotificationOverlayContainers.
     65    struct NotificationOverlayContainerCompare {
     66        bool operator() (const NotificationOverlayContainer* const & a, const NotificationOverlayContainer* const & b) const
     67            { return a->time < b->time; } //!< Ordered by time.
     68    };
     69
    4270    /**
    4371    @brief
    44 
     72        Displays Notifications from specific senders.
     73        Beware! The NotificationQueue is an OverlayGruop and thus cannot be be a sub-element of an OverlayGroup (at least no for now.)
     74
     75        Creating a NotificationQueue through XML goes as follows:
     76        <NotificationQueue
     77            name = "SuperQueue" //Name of your OverlayQueue.
     78            maxSize = "5" //The maximum size of Notifications displayed.
     79            notificationLength = "64" //The maximum number of characters of a Notification, that are displayed. (Default is 5)
     80            displayTime = "30" //The time a Notification is displayed in seconds. (Default is 30)
     81            targets = "target1, target2" //The senders this NotificationQueue displays Notifications from. (all, if all Notifications should be displayed.)
     82            font = "VeraMono" //The font (Default is VeraMono)
     83            fontSize = '0.4' //The font size. (Default is 0.025)
     84            position = "0.0, .0.0" //The position of the NotificationQueue. (Default is 0.0,0.0)
     85        />
    4586    @author
    4687        Damian 'Mozork' Frick
    4788    */
    48     class _OrxonoxExport NotificationQueue : public OverlayText, public Tickable
     89
     90    class _OrxonoxExport NotificationQueue : public OverlayGroup, public Tickable
    4991    {
    50     public:
    51         NotificationQueue(BaseObject* creator);
    52         virtual ~NotificationQueue();
    53 
    54         static NotificationQueue* queue_s; //TDO Singleton? oder im level.
    55 
    56         virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode);
    57 
    58         virtual void tick(float dt);
    59 
    60         void update(void);
    61 
    62         int getLength(void) const
    63                 { return this->length_; }
    64         int getWidth(void) const
    65                 { return this->width_; }
    66 
    67         void setQueueText(const std::string & text);
    68         bool setLength(int length);
    69         bool setWidth(int width);
    70 
    71     private:
    72         Ogre::UTFString queueText_;
    73         int length_;
    74         int width_;
    75 
     92   
     93        public:
     94            NotificationQueue(BaseObject* creator);
     95            virtual ~NotificationQueue();
     96           
     97            virtual void XMLPort(Element& xmlElement, XMLPort::Mode mode); //!< Method for creating a NotificationQueue object through XML.
     98           
     99            virtual void tick(float dt); //!< To update from time to time.
     100           
     101            void update(void); //!< Updates the queue.
     102            void update(Notification* notification, const std::time_t & time); //!< Adds a Notification to the queue.
     103           
     104            /**
     105            @brief Returns the maximum number of Notifications displayed.
     106            @return Returns maximum size.
     107            */
     108            inline int getMaxSize() const
     109                { return this->maxSize_; }
     110            /**
     111            @brief Returns the current number of Notifications displayed.
     112            @return Returns the size of the queue.
     113            */
     114            inline int getSize() const
     115                { return this->size_; }
     116            /**
     117            @brief Returns the maximum length in characters a Notification message is allowed to have.
     118            @return Returns the maximum Notification length.
     119            */
     120            inline int getNotificationLength() const
     121                { return this->notificationLength_; }
     122            /**
     123            @brief Returns the time interval the Notification is displayed.
     124            @return Returns the display time.
     125            */
     126            inline int getDisplayTime() const
     127                { return this->displayTime_; }
     128            /**
     129            @brief Returns the position of the NotificationQueue.
     130            @return Returns the position.
     131            */
     132            inline const Vector2 & getPosition() const
     133                { return this->position_; }
     134            /**
     135            @brief Returns the font size used to display the Notifications.
     136            @return  Returns the font size.
     137            */
     138            inline float getFontSize() const
     139                { return this->fontSize_; }
     140            /**
     141            @brief Returns the font used to display the Notifications.
     142            @return Returns the font.
     143            */
     144            inline const std::string & getFont() const
     145                { return this->font_; }
     146               
     147            /**
     148            @brief Returns the targets of this queue, reps. the senders which Notifications are displayed in this queue.
     149            @return Retuns a set of string holding the different targets.
     150            */
     151            inline const std::set<std::string> & getTargetsSet()
     152                { return this->targets_; }
     153            bool getTargets(std::string* string) const; //!< Returns a string consisting of the concatination of the targets.
     154           
     155            /**
     156            @brief Sets the position of the NotificationQueue.
     157            @param pos The position.
     158            */
     159            inline void setPosition(Vector2 pos)
     160                { this->position_ = pos; this->positionChanged(); }
     161
     162            void scroll(const Vector2 pos); //!< Scrolls the NotificationQueue, meaning all NotificationOverlays are moved the input vector.
     163           
     164        private:
     165            static const int DEFAULT_SIZE = 5; //!< The default maximum number of Notifications displayed.
     166            static const int DEFAULT_LENGTH = 64; //!< The default maximum number of Notifications displayed.
     167            static const int DEFAULT_DISPLAY_TIME = 30; //!< The default display time.
     168            static const float DEFAULT_FONT_SIZE = 0.025; //!< The default font size.
     169
     170            static const std::string DEFAULT_FONT; //!< The default font.
     171            static const Vector2 DEFAULT_POSITION; //!< the default position.
     172       
     173            int maxSize_; //!< The maximal number of Notifications displayed.
     174            int size_; //!< The number of Notifications displayed.
     175            int notificationLength_; //!< The maximal number of characters a Notification-message is allowed to have.
     176            int displayTime_; //!< The time a Notification is displayed.
     177            Vector2 position_; //!< The position of the NotificationQueue.
     178           
     179            std::set<std::string> targets_; //!< The targets the Queue displays Notifications of.
     180           
     181            float fontSize_; //!< The font size.
     182            std::string font_; //!< The font.
     183           
     184            std::multiset<NotificationOverlayContainer*, NotificationOverlayContainerCompare> containers_; //!< Multiset, because the ordering is based on, not necessarily unique, timestamps.
     185            std::map<Notification*, NotificationOverlayContainer*> overlays_; //!< Mapping notifications to their corresponding overlay containers, for easier association and finding.
     186           
     187            float tickTime_; //!< Helper variable, to not have to check for overlays that have been displayed too long, every tick.
     188            NotificationOverlayContainer timeLimit_; //!< Helper object to check against to determine whether Notifications have expired.
     189           
     190            void initialize(void); //!< Initializes the object.
     191            void setDefaults(void); //!< Helper method to set the default values.
     192           
     193            bool setMaxSize(int size); //!< Sets the maximum number of displayed Notifications.
     194            bool setNotificationLength(int length); //!< Sets the maximum number of characters a Notification message displayed by this queue is allowed to have.
     195            bool setDisplayTime(int time); //!< Sets the maximum number of seconds a Notification is displayed.
     196           
     197            bool setTargets(const std::string & targets); //!< Set the targets of this queue.
     198           
     199            bool setFontSize(float size); //!< Set the font size.
     200            bool setFont(const std::string & font); //!< Set the font.
     201
     202            void positionChanged(void); //!< Aligns all the Notifications to the position of the NotificationQueue.
     203           
     204            void addNotification(Notification* notification, const std::time_t & time); //!< Add a notification to the queue.
     205            bool removeContainer(NotificationOverlayContainer* container); //!< Remove a container from the queue.
     206           
     207            void clear(void); //!< Clear the queue.
     208   
    76209    };
    77210
Note: See TracChangeset for help on using the changeset viewer.