comparison 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
comparison
equal deleted inserted replaced
280:77e526e6fdf8 281:e5402c368b21
1 #include "../Core/IDynamicObject.h"
2
3 #include "../Core/OrthancException.h"
4
5 #include <stdint.h>
6 #include <memory>
7 #include <map>
8 #include <gtest/gtest.h>
9 #include <string>
10 #include <boost/thread.hpp>
11 #include <boost/date_time/posix_time/posix_time_types.hpp>
12
13 namespace Orthanc
14 {
15 class SharedMessageQueue
16 {
17 private:
18 typedef std::list<IDynamicObject*> Queue;
19
20 unsigned int maxSize_;
21 Queue queue_;
22 boost::mutex mutex_;
23 boost::condition_variable elementAvailable_;
24
25 public:
26 SharedMessageQueue(unsigned int maxSize = 0)
27 {
28 maxSize_ = maxSize;
29 }
30
31 ~SharedMessageQueue()
32 {
33 for (Queue::iterator it = queue_.begin(); it != queue_.end(); it++)
34 {
35 delete *it;
36 }
37 }
38
39 void Enqueue(IDynamicObject* message)
40 {
41 boost::mutex::scoped_lock lock(mutex_);
42
43 if (maxSize_ != 0 && queue_.size() > maxSize_)
44 {
45 // Too many elements in the queue: First remove the oldest
46 delete queue_.front();
47 queue_.pop_front();
48 }
49
50 queue_.push_back(message);
51 elementAvailable_.notify_one();
52 }
53
54 IDynamicObject* Dequeue(int32_t timeout)
55 {
56 boost::mutex::scoped_lock lock(mutex_);
57
58 // Wait for a message to arrive in the FIFO queue
59 while (queue_.empty())
60 {
61 if (timeout == 0)
62 {
63 elementAvailable_.wait(lock);
64 }
65 else
66 {
67 bool success = elementAvailable_.timed_wait
68 (lock, boost::posix_time::milliseconds(timeout));
69 if (!success)
70 {
71 throw OrthancException(ErrorCode_Timeout);
72 }
73 }
74 }
75
76 std::auto_ptr<IDynamicObject> message(queue_.front());
77 queue_.pop_front();
78
79 return message.release();
80 }
81
82 IDynamicObject* Dequeue()
83 {
84 return Dequeue(0);
85 }
86 };
87
88
89 /**
90 * This class represents a message that is to be sent to some destination.
91 **/
92 class MessageToDispatch : public boost::noncopyable
93 {
94 private:
95 IDynamicObject* message_;
96 std::string destination_;
97
98 public:
99 /**
100 * Create a new message with a destination.
101 * \param message The content of the message (takes the ownership)
102 * \param destination The destination of the message
103 **/
104 MessageToDispatch(IDynamicObject* message,
105 const char* destination)
106 {
107 message_ = message;
108 destination_ = destination;
109 }
110
111 ~MessageToDispatch()
112 {
113 if (message_)
114 {
115 delete message_;
116 }
117 }
118 };
119
120
121 class IDestinationContext : public IDynamicObject
122 {
123 public:
124 virtual void Handle(const IDynamicObject& message) = 0;
125 };
126
127
128 class IDestinationContextFactory : public IDynamicObject
129 {
130 public:
131 virtual IDestinationContext* Construct(const char* destination) = 0;
132 };
133
134
135 class MessageDispatcher
136 {
137 private:
138 typedef std::map<std::string, IDestinationContext*> ActiveContexts;
139
140 std::auto_ptr<IDestinationContextFactory> factory_;
141 ActiveContexts activeContexts_;
142 SharedMessageQueue queue_;
143
144 public:
145 MessageDispatcher(IDestinationContextFactory* factory) // takes the ownership
146 {
147 factory_.reset(factory);
148 }
149
150 ~MessageDispatcher()
151 {
152 for (ActiveContexts::iterator it = activeContexts_.begin();
153 it != activeContexts_.end(); it++)
154 {
155 delete it->second;
156 }
157 }
158 };
159 }
160
161
162
163 #include "../Core/DicomFormat/DicomString.h"
164
165 using namespace Orthanc;
166
167 TEST(MessageToDispatch, A)
168 {
169 MessageToDispatch a(new DicomString("coucou"), "pukkaj");
170 }
171