diff Resources/Archives/MessageWithDestination.cpp @ 281:e5402c368b21

reorganization
author Sebastien Jodogne <s.jodogne@gmail.com>
date Mon, 10 Dec 2012 17:49:14 +0100
parents UnitTests/MessageWithDestination.cpp@24681d35bad9
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Resources/Archives/MessageWithDestination.cpp	Mon Dec 10 17:49:14 2012 +0100
@@ -0,0 +1,171 @@
+#include "../Core/IDynamicObject.h"
+
+#include "../Core/OrthancException.h"
+
+#include <stdint.h>
+#include <memory>
+#include <map>
+#include <gtest/gtest.h>
+#include <string>
+#include <boost/thread.hpp>
+#include <boost/date_time/posix_time/posix_time_types.hpp>
+
+namespace Orthanc
+{
+  class SharedMessageQueue
+  {
+  private:
+    typedef std::list<IDynamicObject*>  Queue;
+
+    unsigned int maxSize_;
+    Queue queue_;
+    boost::mutex mutex_;
+    boost::condition_variable elementAvailable_;
+
+  public:
+    SharedMessageQueue(unsigned int maxSize = 0)
+    {
+      maxSize_ = maxSize;
+    }
+
+    ~SharedMessageQueue()
+    {
+      for (Queue::iterator it = queue_.begin(); it != queue_.end(); it++)
+      {
+        delete *it;
+      }
+    }
+
+    void Enqueue(IDynamicObject* message)
+    {
+      boost::mutex::scoped_lock lock(mutex_);
+
+      if (maxSize_ != 0 && queue_.size() > maxSize_)
+      {
+        // Too many elements in the queue: First remove the oldest
+        delete queue_.front();
+        queue_.pop_front();
+      }
+
+      queue_.push_back(message);
+      elementAvailable_.notify_one();
+    }
+
+    IDynamicObject* Dequeue(int32_t timeout)
+    {
+      boost::mutex::scoped_lock lock(mutex_);
+
+      // Wait for a message to arrive in the FIFO queue
+      while (queue_.empty())
+      {
+        if (timeout == 0)
+        {
+          elementAvailable_.wait(lock);
+        }
+        else
+        {
+          bool success = elementAvailable_.timed_wait
+            (lock, boost::posix_time::milliseconds(timeout));
+          if (!success)
+          {
+            throw OrthancException(ErrorCode_Timeout);
+          }
+        }
+      }
+
+      std::auto_ptr<IDynamicObject> message(queue_.front());
+      queue_.pop_front();
+
+      return message.release();
+    }
+
+    IDynamicObject* Dequeue()
+    {
+      return Dequeue(0);
+    }
+  };
+
+
+  /**
+   * This class represents a message that is to be sent to some destination.
+   **/
+  class MessageToDispatch : public boost::noncopyable
+  {
+  private:
+    IDynamicObject* message_;
+    std::string destination_;
+
+  public:
+    /**
+     * Create a new message with a destination.
+     * \param message The content of the message (takes the ownership)
+     * \param destination The destination of the message
+     **/
+    MessageToDispatch(IDynamicObject* message,
+                      const char* destination)
+    {
+      message_ = message;
+      destination_ = destination;
+    }
+
+    ~MessageToDispatch()
+    {
+      if (message_)
+      {
+        delete message_;
+      }
+    }
+  };
+
+
+  class IDestinationContext : public IDynamicObject
+  {
+  public:
+    virtual void Handle(const IDynamicObject& message) = 0;
+  };
+
+
+  class IDestinationContextFactory : public IDynamicObject
+  {
+  public:
+    virtual IDestinationContext* Construct(const char* destination) = 0;
+  };
+
+
+  class MessageDispatcher
+  {
+  private:
+    typedef std::map<std::string, IDestinationContext*>  ActiveContexts;
+
+    std::auto_ptr<IDestinationContextFactory> factory_;
+    ActiveContexts activeContexts_;
+    SharedMessageQueue queue_;
+
+  public:
+    MessageDispatcher(IDestinationContextFactory* factory)  // takes the ownership
+    {
+      factory_.reset(factory);
+    }
+
+    ~MessageDispatcher()
+    {
+      for (ActiveContexts::iterator it = activeContexts_.begin(); 
+           it != activeContexts_.end(); it++)
+      {
+        delete it->second;
+      }
+    }
+  };
+}
+
+
+
+#include "../Core/DicomFormat/DicomString.h"
+
+using namespace Orthanc;
+
+TEST(MessageToDispatch, A)
+{
+  MessageToDispatch a(new DicomString("coucou"), "pukkaj");
+}
+