diff Framework/Messages/IObservable.h @ 267:89d02de83c03 am-2

added declaretion of messages handled/emitted
author am@osimis.io
date Wed, 22 Aug 2018 14:59:20 +0200
parents c9cf95b49a86
children 5bd4161bf11b
line wrap: on
line diff
--- a/Framework/Messages/IObservable.h	Tue Aug 21 18:14:22 2018 +0200
+++ b/Framework/Messages/IObservable.h	Wed Aug 22 14:59:20 2018 +0200
@@ -21,17 +21,35 @@
 
 #pragma once
 
+#include <set>
+#include <assert.h>
+#include <algorithm>
+#include <iostream>
+
 #include "MessageBroker.h"
-#include <set>
+#include "MessageType.h"
+#include "IObserver.h"
 
 namespace OrthancStone {
 
+  class MessageNotDeclaredException : public std::logic_error
+  {
+    MessageType messageType_;
+  public:
+    MessageNotDeclaredException(MessageType messageType)
+      : std::logic_error("Message not declared by observer."),
+        messageType_(messageType)
+    {
+    }
+  };
+
   class IObservable : public boost::noncopyable
   {
   protected:
     MessageBroker&                     broker_;
 
     std::set<IObserver*>              observers_;
+    std::set<MessageType>             emittableMessages_;
 
   public:
 
@@ -45,11 +63,17 @@
 
     void EmitMessage(const IMessage& message) const
     {
+      if (emittableMessages_.find(message.GetType()) == emittableMessages_.end())
+      {
+        throw MessageNotDeclaredException(message.GetType());
+      }
+
       broker_.EmitMessage(*this, observers_, message);
     }
 
     void RegisterObserver(IObserver& observer)
     {
+      CheckObserverDeclaredAllObservableMessages(observer);
       observers_.insert(&observer);
     }
 
@@ -57,6 +81,31 @@
     {
       observers_.erase(&observer);
     }
+
+    const std::set<MessageType>& GetEmittableMessages() const
+    {
+      return emittableMessages_;
+    }
+
+  protected:
+
+    void DeclareEmittableMessage(MessageType messageType)
+    {
+      emittableMessages_.insert(messageType);
+    }
+
+    void CheckObserverDeclaredAllObservableMessages(IObserver& observer)
+    {
+      for (std::set<MessageType>::const_iterator it = emittableMessages_.begin(); it != emittableMessages_.end(); it++)
+      {
+        // the observer must have "declared" all observable messages
+        if (observer.GetHandledMessages().find(*it) == observer.GetHandledMessages().end()
+            && observer.GetIgnoredMessages().find(*it) == observer.GetIgnoredMessages().end())
+        {
+          throw MessageNotDeclaredException(*it);
+        }
+      }
+    }
   };
 
 }