[Orxonox-commit 2228] r6944 - in code/branches/presentation3: data/levels src/modules/questsystem/notifications

dafrick at orxonox.net dafrick at orxonox.net
Thu May 20 21:43:46 CEST 2010


Author: dafrick
Date: 2010-05-20 21:43:45 +0200 (Thu, 20 May 2010)
New Revision: 6944

Modified:
   code/branches/presentation3/data/levels/quest_test.oxw
   code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.cc
   code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.h
   code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.cc
   code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.h
Log:
No more seg-faults when restarting a game, quests still not working properly the second thime, though.
Also replaced QuestListener mode 'receive' with 'start' in quest_test, which appears to be the correct term.


Modified: code/branches/presentation3/data/levels/quest_test.oxw
===================================================================
--- code/branches/presentation3/data/levels/quest_test.oxw	2010-05-20 19:04:46 UTC (rev 6943)
+++ code/branches/presentation3/data/levels/quest_test.oxw	2010-05-20 19:43:45 UTC (rev 6944)
@@ -16,24 +16,22 @@
 
 <?lua
     dofile("includes/CuboidSpaceStation.lua")
-?>
-
-<NotificationQueue
-	 name     = "notification"
-	 position = "0.40, 0.05"
-	 font     = "VeraMono"
-	 textsize = 0.020
-	 length   = 3
-	 width    = 50
-/>
+?>	
 	
-	
-	
 <Level
 name="Dani's Testlevel"
 description="Erste Versuche mit den Quests"
 >
 
+    <NotificationQueue
+	     name     = "notification"
+	     position = "0.40, 0.05"
+	     font     = "VeraMono"
+	     textsize = 0.020
+	     length   = 3
+	     width    = 50
+    />
+
     <Scene
         ambientlight = "0.3, 0.3, 0.3"
         skybox       = "Orxonox/skypanoramagen1"
@@ -261,7 +259,7 @@
 		  <EventTrigger invert=true>
 		    <events>
 		      <trigger>
-		        <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="recieve" />
+		        <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="start" />
 		      </trigger>
 		    </events>
 		  </EventTrigger>
@@ -270,7 +268,7 @@
 	            <EventTrigger invert=true>
 		    <events>
 		      <trigger>
-                             <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="recieve" />
+                             <QuestListener questId="dbd02b4c-ab7c-46fd-bdaf-fd4c19ac1551" mode="start" />
 		      </trigger>
 		    </events>
 		  </EventTrigger>
@@ -361,4 +359,4 @@
 		
 		
 	</Scene>
-</Level>
\ No newline at end of file
+</Level>

Modified: code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.cc
===================================================================
--- code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.cc	2010-05-20 19:04:46 UTC (rev 6943)
+++ code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.cc	2010-05-20 19:43:45 UTC (rev 6944)
@@ -65,6 +65,7 @@
     */
     NotificationManager::~NotificationManager()
     {
+        
     }
 
     /**
@@ -100,16 +101,58 @@
             {
                 this->notificationLists_[it->second]->insert(std::pair<std::time_t,Notification*>(time,notification)); //!< Insert the Notification in the Notifications list of the current NotificationListener.
                 it->first->update(notification, time); //!< Update the listener.
+                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(notification);
+                if(counterIt == this->listenerCounter_.end())
+                    this->listenerCounter_[notification] = 1;
+                else
+                    this->listenerCounter_[notification] = counterIt->second + 1;
             }
         }
 
-        COUT(3) << "Notification registered with the NotificationManager." << std::endl;
+        COUT(4) << "Notification registered with the NotificationManager." << std::endl;
 
         return true;
     }
 
     /**
     @brief
+        Unregisters a Notification within the NotificationManager.
+    */
+    void NotificationManager::unregisterNotification(Notification* notification, NotificationListener* listener)
+    {
+        assert(notification);
+        assert(listener);
+
+        if(this->removeNotification(notification, *(this->notificationLists_.find(this->listenerList_.find(listener)->second)->second)))
+            this->listenerCounter_[notification] = this->listenerCounter_[notification] - 1;
+        if(this->listenerCounter_[notification] == (unsigned int) 0)
+        {
+            this->removeNotification(notification, this->allNotificationsList_);
+            notification->destroy();
+        }
+
+        COUT(4) << "Notification unregistered with the NotificationManager." << std::endl;
+    }
+
+    /**
+    @brief
+        Helper method that removes an input notification form an input map.
+    */
+    bool NotificationManager::removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map)
+    {
+        for(std::multimap<std::time_t, Notification*>::iterator it = map.begin(); it != map.end(); it++)
+        {
+            if(it->second == notification)
+            {
+                map.erase(it);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    @brief
         Registers a NotificationListener within the NotificationManager.
     @param listener
         The NotificationListener to be registered.
@@ -129,7 +172,7 @@
         if(set.find(ALL) != set.end())
         {
             this->notificationLists_[index] = &this->allNotificationsList_;
-            COUT(3) << "NotificationListener registered with the NotificationManager." << std::endl;
+            COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
             return true;
         }
 
@@ -141,19 +184,50 @@
         {
             if(set.find(it->second->getSender()) != set.end()) //!< Checks whether the overlay has the sender of the current notification as target.
             {
-                map.insert(std::pair<std::time_t,Notification*>(it->first, it->second));
+                map.insert(std::pair<std::time_t, Notification*>(it->first, it->second));
+                std::map<Notification*, unsigned int>::iterator counterIt = this->listenerCounter_.find(it->second);
+                if(counterIt == this->listenerCounter_.end())
+                    this->listenerCounter_[it->second] = 1;
+                else
+                    this->listenerCounter_[it->second] = counterIt->second + 1;
             }
         }
 
         listener->update(); //!< Update the listener.
 
-        COUT(3) << "NotificationListener registered with the NotificationManager." << std::endl;
+        COUT(4) << "NotificationListener registered with the NotificationManager." << std::endl;
 
         return true;
     }
 
     /**
     @brief
+        Unregisters a NotificationListener withing the NotificationManager.
+    */
+    void NotificationManager::unregisterListener(NotificationListener* listener)
+    {
+        assert(listener);
+
+        int identifier = this->listenerList_.find(listener)->second;
+        std::multimap<std::time_t, Notification*>* map = this->notificationLists_.find(identifier)->second;
+        
+        // Make sure all Notifications are removed.
+        std::multimap<std::time_t, Notification*>::iterator it = map->begin();
+        while(it != map->end())
+        {
+            this->unregisterNotification(it->second, listener);
+            it = map->begin();
+        }
+
+        this->listenerList_.erase(listener);
+        this->notificationLists_.erase(identifier);
+        delete map;
+
+        COUT(4) << "NotificationListener unregistered with the NotificationManager." << std::endl;
+    }
+
+    /**
+    @brief
         Fetches the Notifications for a specific NotificationListener in a specified timeframe.
     @param listener
         The NotificationListener the Notifications are fetched for.

Modified: code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.h
===================================================================
--- code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.h	2010-05-20 19:04:46 UTC (rev 6943)
+++ code/branches/presentation3/src/modules/questsystem/notifications/NotificationManager.h	2010-05-20 19:43:45 UTC (rev 6944)
@@ -63,7 +63,9 @@
             static const std::string NONE;
 
             bool registerNotification(Notification* notification); //!< Registers a Notification within the NotificationManager.
+            void unregisterNotification(Notification* notification, NotificationListener* listener); //!< Unregisters a Notification within the NotificationManager.
             bool registerListener(NotificationListener* listener); //!< Registers a NotificationListener within the NotificationManager.
+            void unregisterListener(NotificationListener* listener); //!< Unregisters a NotificationListener withing the NotificationManager.
 
             bool getNotifications(NotificationListener* listener, std::multimap<std::time_t,Notification*>* map, const std::time_t & timeFrameStart, const std::time_t & timeFrameEnd); //!< Returns the Notifications for a specific NotificationListener in a specified timeframe.
 
@@ -89,13 +91,16 @@
         private:
             static NotificationManager* singletonPtr_s;
 
-            int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that  no key appears twice.
+            int highestIndex_; //!< This variable holds the highest index (resp. key) in notificationLists_s, to secure that no key appears twice.
 
-            std::multimap<std::time_t,Notification*> allNotificationsList_; //!< Container where all notifications are stored (together with their respecive timestamps).
+            std::multimap<std::time_t,Notification*> allNotificationsList_; //!< Container where all notifications are stored.
             std::map<NotificationListener*,int> listenerList_; //!< Container where all NotificationListeners are stored with a number as identifier.
             std::map<int,std::multimap<std::time_t,Notification*>*> notificationLists_; //!< Container where all Notifications, for each identifier (associated with a NotificationListener), are stored.
+            std::map<Notification*, unsigned int> listenerCounter_; //!< A container to store the number of NotificationListeners a Notification is registered with.
 
+            bool removeNotification(Notification* notification, std::multimap<std::time_t, Notification*>& map);
 
+
     };
 
 }

Modified: code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.cc
===================================================================
--- code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.cc	2010-05-20 19:04:46 UTC (rev 6943)
+++ code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.cc	2010-05-20 19:43:45 UTC (rev 6944)
@@ -55,6 +55,8 @@
     */
     NotificationQueue::NotificationQueue(BaseObject* creator) : OverlayGroup(creator)
     {
+        this->registered_ = false;
+        
         RegisterObject(NotificationQueue);
         this->initialize();
     }
@@ -67,6 +69,9 @@
     {
         this->targets_.clear();
         this->clear();
+
+        if(this->registered_)
+            NotificationManager::getInstance().unregisterListener(this);
     }
 
     /**
@@ -80,6 +85,7 @@
         this->tickTime_ = 0.0;
 
         NotificationManager::getInstance().registerListener(this);
+        this->registered_ = true;
     }
 
     /**
@@ -422,6 +428,8 @@
         if(this->size_ == 0) //!< You cannot remove anything if the queue is empty.
             return false;
 
+        NotificationManager::getInstance().unregisterNotification(container->notification, this);
+        
         this->removeElement(container->overlay);
         this->containers_.erase(container);
         this->overlays_.erase(container->notification);
@@ -442,7 +450,7 @@
         while(it != this->containers_.end())
         {
             this->removeContainer(*it);
-            it = this->containers_.begin(); //TODO: Needed?
+            it = this->containers_.begin();
         }
     }
 

Modified: code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.h
===================================================================
--- code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.h	2010-05-20 19:04:46 UTC (rev 6943)
+++ code/branches/presentation3/src/modules/questsystem/notifications/NotificationQueue.h	2010-05-20 19:43:45 UTC (rev 6944)
@@ -184,6 +184,8 @@
             float tickTime_; //!< Helper variable, to not have to check for overlays that have been displayed too long, every tick.
             NotificationOverlayContainer timeLimit_; //!< Helper object to check against to determine whether Notifications have expired.
 
+            bool registered_; //!< Helper variable to remember whether the NotificationQueue is registered already.
+
             void initialize(void); //!< Initializes the object.
             void setDefaults(void); //!< Helper method to set the default values.
 




More information about the Orxonox-commit mailing list