Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 11, 2010, 10:20:44 AM (14 years ago)
Author:
dafrick
Message:

Merged notifications branch back to trunk.

Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/modules/notifications/NotificationManager.cc

    r7284 r7403  
    2828
    2929/**
    30     @file
     30    @file NotificationManager.cc
    3131    @brief Implementation of the NotificationManager class.
    3232*/
     
    3434#include "NotificationManager.h"
    3535
    36 #include <set>
    37 
     36#include "core/command/ConsoleCommand.h"
     37#include "core/CoreIncludes.h"
     38#include "core/GUIManager.h"
     39#include "core/LuaState.h"
    3840#include "util/ScopedSingletonManager.h"
    39 #include "core/CoreIncludes.h"
     41
     42#include "interfaces/NotificationListener.h"
     43
    4044#include "Notification.h"
    41 #include "interfaces/NotificationListener.h"
     45#include "NotificationQueue.h"
     46
     47#include "ToluaBindNotifications.h"
    4248
    4349namespace orxonox
     
    4753    const std::string NotificationManager::NONE("none");
    4854
    49     ManageScopedSingleton(NotificationManager, ScopeID::Root, false);
     55    // Register tolua_open function when loading the library.
     56    DeclareToluaInterface(Notifications);
     57
     58    ManageScopedSingleton(NotificationManager, ScopeID::Graphics, false);
     59
     60    SetConsoleCommand("enterEditMode", &NotificationManager::enterEditMode);
    5061
    5162    /**
     
    5869
    5970        this->highestIndex_ = 0;
     71
     72        ModifyConsoleCommand("enterEditMode").setObject(this);
     73
     74        COUT(3) << "NotificatioManager created." << std::endl;
    6075    }
    6176
     
    6681    NotificationManager::~NotificationManager()
    6782    {
    68 
     83        ModifyConsoleCommand("enterEditMode").setObject(NULL);
     84
     85        COUT(3) << "NotificationManager destroyed." << std::endl;
     86    }
     87
     88    /**
     89    @brief
     90        Is called before the object is destroyed.
     91    */
     92    void NotificationManager::preDestroy(void)
     93    {
     94        // Destroys all NotificationQueues that have been registered with the NotificationManager.
     95        for(std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.begin(); it != this->queues_.end(); )
     96        {
     97            NotificationQueue* queue = (*it).second;
     98            it++;
     99            queue->destroy();
     100        }
     101        this->queues_.clear();
    69102    }
    70103
     
    79112    bool NotificationManager::registerNotification(Notification* notification)
    80113    {
    81 
    82         if(notification == NULL) //!< A NULL-Notification cannot be registered.
    83             return false;
     114        assert(notification);
    84115
    85116        std::time_t time = std::time(0); //TODO: Doesn't this expire? //!< Get current time.
    86117
    87         this->allNotificationsList_.insert(std::pair<std::time_t,Notification*>(time,notification));
    88 
    89         if(notification->getSender() == NONE) //!< If the sender has no specific name, then the Notification is only added to the list of all Notifications.
     118        // Add the Notification to the list that holds all Notifications.
     119        this->allNotificationsList_.insert(std::pair<std::time_t, Notification*>(time, notification));
     120
     121        if(notification->getSender() == NotificationManager::NONE) // If the sender has no specific name, then the Notification is only added to the list of all Notifications.
    90122            return true;
    91123
    92124        bool all = false;
    93         if(notification->getSender() == ALL) //!< If all are the sender, then the Notifications is added to every NotificationListener.
     125        if(notification->getSender() == NotificationManager::ALL) // If all are the sender, then the Notifications is added to every NotificationListener.
    94126            all = true;
    95127
    96         //!< Insert the notification in all listeners that have its sender as target.
    97         for(std::map<NotificationListener*,int>::iterator it = this->listenerList_.begin(); it != this->listenerList_.end(); it++) //!< Iterate through all listeners.
    98         {
    99             std::set<std::string> set = it->first->getTargetsSet();
    100             if(all || set.find(notification->getSender()) != set.end() || set.find(ALL) != set.end()) //TODO: Make sure this works.
     128        // Insert the Notification in all NotificationListeners that have its sender as target.
     129        for(std::map<NotificationListener*, unsigned int>::iterator it = this->listenerList_.begin(); it != this->listenerList_.end(); it++) // Iterate through all NotificationListeners.
     130        {
     131            std::set<std::string, NotificationListenerStringCompare> set = it->first->getTargetsSet();
     132            bool bAll = set.find(NotificationManager::ALL) != set.end();
     133            // If either the Notification has as sender 'all', the NotificationListener displays all Notifications or the NotificationListener has the sender of the Notification as target.
     134            if(all || bAll || set.find(notification->getSender()) != set.end())
    101135            {
    102                 this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); //!< Insert the Notification in the Notifications list of the current NotificationListener.
    103                 it->first->update(notification, time); //!< Update the listener.
    104                 std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(notification);
    105                 if(counterIt == this->listenerCounter_.end())
    106                     this->listenerCounter_[notification] = 1;
    107                 else
    108                     this->listenerCounter_[notification] = counterIt->second + 1;
     136                if(!bAll)
     137                    this->notificationLists_[it->second]->insert(std::pair<std::time_t, Notification*>(time, notification)); // Insert the Notification in the notifications list of the current NotificationListener.
     138                it->first->update(notification, time); // Update the NotificationListener.
    109139            }
    110140        }
    111141
    112         COUT(4) << "Notification registered with the NotificationManager." << std::endl;
     142        COUT(4) << "Notification (&" << notification << ") registered with the NotificationManager." << std::endl;
    113143
    114144        return true;
     
    117147    /**
    118148    @brief
    119         Unregisters a Notification within the NotificationManager.
     149        Unregisters a Notification within the NotificationManager for a given NotificationListener.
    120150    @param notification
    121151        A pointer to the Notification to be unregistered.
     
    128158        assert(listener);
    129159
    130         // If the Notification was removed from the list of Notifications of the input NotificationListener, the counter for the Notification of the number of NotificationListeners it is present in is decremented.
    131         if(this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second)))
    132             this->listenerCounter_[notification] = this->listenerCounter_[notification] - 1;
    133 
    134         // If the Notification is no longer present in any of the NotificationListeners it can be removed from the map of all Notifications and be destroyed.
    135         if(this->listenerCounter_[notification] == (unsigned int) 0)
    136         {
    137             this->removeNotification(notification, this->allNotificationsList_);
    138             this->listenerCounter_.erase(notification);
    139             notification->destroy();
    140         }
    141 
    142         COUT(4) << "Notification unregistered with the NotificationManager." << std::endl;
    143     }
    144 
    145     /**
    146     @brief
    147         Helper method that removes an input notification form an input map.
     160        // Remove the Notification from the list of Notifications of the input NotificationListener.
     161        this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second));
     162
     163        COUT(4) << "Notification (&" << notification << ") unregistered with the NotificationManager from listener (&" << listener << ")" << std::endl;
     164    }
     165
     166    /**
     167    @brief
     168        Helper method that removes an input Notification form an input map.
    148169    @param notification
    149         A pointer to the notification to be removed.
     170        A pointer to the Notification to be removed.
    150171    @param map
    151         The map the notification should be removed from.
     172        The map the Notification should be removed from.
    152173    @return
    153174        Returns true if successful.
     
    174195        The NotificationListener to be registered.
    175196    @return
    176         Returns true if successful.
     197        Returns true if successful.  Fales if the NotificationListener is already registered.
    177198    */
    178199    bool NotificationManager::registerListener(NotificationListener* listener)
    179200    {
     201        assert(listener);
     202
     203        // If the NotificationListener is already registered.
     204        if(this->listenerList_.find(listener) != this->listenerList_.end())
     205            return false;
     206
    180207        this->highestIndex_ += 1;
    181         int index = this->highestIndex_;
    182 
    183         this->listenerList_[listener] = index; //!< Add the NotificationListener to the list of listeners.
    184 
    185         std::set<std::string> set = listener->getTargetsSet(); //TODO: Does this work?
    186 
    187         //! If all senders are the target of the listener, then the list of notification for that specific listener is te same as the list of all Notifications.
    188         if(set.find(ALL) != set.end())
    189         {
     208        unsigned int index = this->highestIndex_; // An identifier that identifies each registered NotificationListener uniquely.
     209
     210        this->listenerList_[listener] = index; // Add the NotificationListener to the list of NotificationListeners.
     211
     212        std::set<std::string, NotificationListenerStringCompare> set = listener->getTargetsSet();
     213
     214        // If all senders are the target of the NotificationListener, then the list of Notifications for that specific NotificationListener is the same as the list of all Notifications.
     215        bool bAll = set.find(NotificationManager::ALL) != set.end();
     216        std::multimap<std::time_t, Notification*>* map;
     217        if(bAll)
    190218            this->notificationLists_[index] = &this->allNotificationsList_;
    191             COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
    192             return true;
    193         }
    194 
    195         this->notificationLists_[index] = new std::multimap<std::time_t,Notification*>;
    196         std::multimap<std::time_t,Notification*> map = *this->notificationLists_[index];
    197 
    198         //! Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationListener.
    199         for(std::multimap<std::time_t,Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
    200         {
    201             if(set.find(it->second->getSender()) != set.end()) //!< Checks whether the overlay has the sender of the current notification as target.
     219        // Else a new list (resp. multimap) is created and added to the list of Notification lists for NotificationListeners.
     220        else
     221        {
     222            this->notificationLists_[index] = new std::multimap<std::time_t, Notification*>;
     223            map = this->notificationLists_[index];
     224        }
     225
     226        // Iterate through all Notifications to determine whether any of them should belong to the newly registered NotificationListener.
     227        for(std::multimap<std::time_t, Notification*>::iterator it = this->allNotificationsList_.begin(); it != this->allNotificationsList_.end(); it++)
     228        {
     229            if(!bAll && set.find(it->second->getSender()) != set.end()) // Checks whether the listener has the sender of the current Notification as target.
     230                map->insert(std::pair<std::time_t, Notification*>(it->first, it->second));
     231        }
     232
     233        listener->update(); // Update the listener.
     234
     235        COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
     236
     237        return true;
     238    }
     239
     240    /**
     241    @brief
     242        Unregisters a NotificationListener within the NotificationManager.
     243    @param listener
     244        The NotificationListener to be unregistered.
     245    */
     246    void NotificationManager::unregisterListener(NotificationListener* listener)
     247    {
     248        assert(listener);
     249
     250        //TODO: Make unsigned int.
     251        unsigned int identifier = this->listenerList_.find(listener)->second;
     252        std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
     253
     254        // If the map is not the map of all Notifications, make sure all Notifications are unregistered.
     255        std::multimap<std::time_t, Notification*>::iterator it = map->begin();
     256        if(map != &this->allNotificationsList_)
     257        {
     258            while(it != map->end())
    202259            {
    203                 map.insert(std::pair<std::time_t, Notification*>(it->first, it->second));
    204                 std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(it->second);
    205                 if(counterIt == this->listenerCounter_.end())
    206                     this->listenerCounter_[it->second] = 1;
    207                 else
    208                     this->listenerCounter_[it->second] = counterIt->second + 1;
     260                this->unregisterNotification(it->second, listener);
     261                it = map->begin();
    209262            }
    210         }
    211 
    212         listener->update(); //!< Update the listener.
    213 
    214         COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
    215 
    216         return true;
    217     }
    218 
    219     /**
    220     @brief
    221         Unregisters a NotificationListener withing the NotificationManager.
    222     */
    223     void NotificationManager::unregisterListener(NotificationListener* listener)
    224     {
    225         assert(listener);
    226 
    227         int identifier = this->listenerList_.find(listener)->second;
    228         std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
    229 
    230         // Make sure all Notifications are removed.
    231         std::multimap<std::time_t, Notification*>::iterator it = map->begin();
    232         while(it != map->end())
    233         {
    234             this->unregisterNotification(it->second, listener);
    235             it = map->begin();
    236         }
    237 
     263            delete map;
     264        }
     265
     266        // Remove the NotificationListener from the list of NotificationListeners.
    238267        this->listenerList_.erase(listener);
     268        // Remove the Notifications list that was associated with the input NotificationListener.
    239269        this->notificationLists_.erase(identifier);
    240270
    241         // If the map is not the map of all notifications, delete it.
    242         if(map != &this->allNotificationsList_)
    243             delete map;
    244 
    245271        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
    246272    }
     
    248274    /**
    249275    @brief
    250         Fetches the Notifications for a specific NotificationListener in a specified timeframe.
     276        Fetches the Notifications for a specific NotificationListener in a specified timeframe and stores them in the input map.
    251277    @param listener
    252278        The NotificationListener the Notifications are fetched for.
    253279    @param map
    254         A multimap, in which the notifications are stored.
     280        A pointer to a multimap, in which the notifications are stored. The map needs to have been allocated.
    255281    @param timeFrameStart
    256282        The start time of the timeframe.
     
    260286        Returns true if successful.
    261287    */
    262     bool NotificationManager::getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
    263     {
    264         if(listener == NULL || map == NULL)
    265             return false;
    266 
    267         std::multimap<std::time_t,Notification*>* notifications = this->notificationLists_[this->listenerList_[listener]]; //!< The Notifications for the input NotificationListener.
    268 
    269         if(notifications == NULL) //!< Returns NULL, if there are no Notifications.
    270             return true;
     288    void NotificationManager::getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd)
     289    {
     290        assert(listener);
     291        assert(map);
     292
     293        std::multimap<std::time_t, Notification*>* notifications = this->notificationLists_[this->listenerList_[listener]]; // All the Notifications for the input NotificationListener.
    271294
    272295        std::multimap<std::time_t,Notification*>::iterator it, itLowest, itHighest;
     296        // Iterators pointing to the bounds specified by the specified start and end times of the time frame.
    273297        itLowest = notifications->lower_bound(timeFrameStart);
    274         itHighest = notifications->upper_bound(timeFrameStart);
    275 
    276         for(it = itLowest; it != itHighest; it++) //!< Iterate through the Notifications from the start of the time Frame to the end of it.
    277         {
    278             map->insert(std::pair<std::time_t,Notification*>(it->first,it->second)); //!< Add the found Notifications to the map.
    279         }
    280 
    281         return true;
     298        itHighest = notifications->upper_bound(timeFrameEnd);
     299
     300        for(it = itLowest; it != itHighest; it++) // Iterate through the Notifications from the start of the time frame to the end of it.
     301            map->insert(std::pair<std::time_t, Notification*>(it->first, it->second)); // Add the found Notifications to the map.
     302    }
     303
     304    /**
     305    @brief
     306        Enters the edit mode of the NotificationLayer.
     307    */
     308    void NotificationManager::enterEditMode(void)
     309    {
     310        GUIManager::getInstance().hideGUI("NotificationLayer");
     311        GUIManager::getInstance().showGUI("NotificationLayer", false, false);
     312        GUIManager::getInstance().getLuaState()->doString("NotificationLayer.enterEditMode()");
     313    }
     314
     315    /**
     316    @brief
     317        Registers a NotificationQueue.
     318        This makes sure that the NotificationQueue can be attained through lua by name. It also makes sure that the NotificationQueue is destroyed upon destruction of the NotificationManager.
     319    @param queue
     320        A pointer to the NotificationQueue to be registered.
     321    @return
     322        Returns true if successful. If e.g. the a NotificationQueue with that name already exists this returns false.
     323    */
     324    bool NotificationManager::registerQueue(NotificationQueue* queue)
     325    {
     326        return this->queues_.insert(std::pair<const std::string, NotificationQueue*>(queue->getName(), queue)).second;
     327    }
     328
     329    /**
     330    @brief
     331        Unregisters a NotificationQueue.
     332    @param queue
     333        A pointer to the NotificationQueue to be unregistered.
     334    */
     335    void NotificationManager::unregisterQueue(NotificationQueue* queue)
     336    {
     337        this->queues_.erase(queue->getName());
     338    }
     339
     340    /**
     341    @brief
     342        Loads all the NotificationQueues that should exist.
     343    */
     344    void NotificationManager::loadQueues(void)
     345    {
     346        new NotificationQueue("all");
     347    }
     348
     349    /**
     350    @brief
     351        Creates a new NotificationQueue.
     352        This is used in lua.
     353    @param name
     354        The name of the new NotificationQueue.
     355    */
     356    void NotificationManager::createQueue(const std::string& name)
     357    {
     358        new NotificationQueue(name);
     359    }
     360
     361    /**
     362    @brief
     363        Get the NotificationQueue with the input name.
     364    @param name
     365        The name of the NotificationQueue.
     366    @return
     367        Returns a pointer to the NotificationQueue with the input name. Returns NULL if no NotificationQueue with such a name exists.
     368    */
     369    NotificationQueue* NotificationManager::getQueue(const std::string & name)
     370    {
     371        std::map<const std::string, NotificationQueue*>::iterator it = this->queues_.find(name);
     372        // Returns NULL if no such NotificationQueue exists.
     373        if(it == this->queues_.end())
     374            return NULL;
     375
     376        return (*it).second;
    282377    }
    283378
Note: See TracChangeset for help on using the changeset viewer.