Design Pattern Examples
Overview of object-oriented design patterns
HandlerChain_Class.h
Go to the documentation of this file.
1
6
7#pragma once
8#ifndef __HANDLERCHAIN_CLASS_H__
9#define __HANDLERCHAIN_CLASS_H__
10
11#include <algorithm>
12#include <list>
13#include <memory>
14#include <mutex>
15#include <sstream>
16#include <string>
17
18#include "helpers/formatstring.h"
19
21{
22 struct Message; // forward declaration
23
30 {
34 using shared_ptr_t = std::shared_ptr<IMessageHandler>;
35
39 virtual ~IMessageHandler() { }
40
45 virtual int ID() = 0;
46
55 virtual bool ProcessMessage(Message* message) = 0;
56
61 virtual std::string ToString() = 0;
62 };
63
64
65
66 //========================================================================
67 //========================================================================
68 //========================================================================
69
70
71
78 {
79 public:
80 using unique_ptr_t = std::unique_ptr<HandlerChain>;
81
82 private:
86 std::list<IMessageHandler::shared_ptr_t> _messageHandlers;
87
93
94 public:
100 void SendMessage(Message* message)
101 {
102 // We make a copy of the handlers so our processing of handlers
103 // is not impacted by updates to the master handler list.
104 std::list<IMessageHandler::shared_ptr_t> copyof_MessageHandlers(_messageHandlers.size());
105 {
106 std::lock_guard<std::mutex> guard(_messageHandlersLock);
107 std::copy(std::begin(_messageHandlers), std::end(_messageHandlers), std::begin(copyof_MessageHandlers));
108 }
109
110 for(IMessageHandler::shared_ptr_t& window : copyof_MessageHandlers)
111 {
112 if (window->ProcessMessage(message))
113 {
114 break;
115 }
116 }
117 }
118
119
129 {
130 std::lock_guard<std::mutex> guard(_messageHandlersLock);
131 // Add the handler if not already in the list.
132 std::list<IMessageHandler::shared_ptr_t>::iterator foundIter;
133 foundIter = std::find_if(std::begin(_messageHandlers),
134 std::end(_messageHandlers),
135 [window](IMessageHandler::shared_ptr_t w) { return w->ID() == window->ID(); });
136
137 if (foundIter == std::end(_messageHandlers))
138 {
139 _messageHandlers.push_back(window);
140 }
141 }
142
143
153 {
154 std::lock_guard<std::mutex> guard(_messageHandlersLock);
155 _messageHandlers.remove_if([window](IMessageHandler::shared_ptr_t w) { return w->ID() == window->ID(); });
156 }
157
167 {
168 std::lock_guard<std::mutex> guard(_messageHandlersLock);
169 _messageHandlers.remove_if([window](IMessageHandler::shared_ptr_t w) { return w->ID() == window->ID(); });
170 }
171
172
179 std::string ToString()
180 {
181 std::ostringstream output;
182
183 std::list<IMessageHandler::shared_ptr_t> copyof_MessageHandlers(_messageHandlers.size());
184 {
185 std::lock_guard<std::mutex> guard(_messageHandlersLock);
186 std::copy(std::begin(_messageHandlers), std::end(_messageHandlers), std::begin(copyof_MessageHandlers));
187 }
188
189 for(IMessageHandler::shared_ptr_t& window : copyof_MessageHandlers)
190 {
191 output << Helpers::formatstring(" %s", window->ToString().c_str()) << std::endl;
192 }
193 return output.str();
194 }
195 };
196
197} // end namespace
198
199#endif // __HANDLERCHAIN_CLASS_H__
200
Represents a list of handlers that all implement the IMessageHandler interface. This list can be dyna...
void SendMessage(Message *message)
Send a message to each of the handlers in the list, protected by a multi-threading lock.
std::string ToString()
Convert this HandlerChain to a string, protected by a multi-threading lock.
std::unique_ptr< HandlerChain > unique_ptr_t
std::list< IMessageHandler::shared_ptr_t > _messageHandlers
The list of message handlers.
std::mutex _messageHandlersLock
Object used to lock access to the message handlers list for multi-threaded support.
void AddHandler(IMessageHandler::shared_ptr_t window)
Add an instance of the IMessageHandler interface to end of the list of handlers, protected by a multi...
void RemoveHandler(IMessageHandler *window)
Remove an instance of the IMessageHandler interface from the list, protected by a multi-threading loc...
void RemoveHandler(IMessageHandler::shared_ptr_t window)
Remove an instance of the IMessageHandler interface from the list, protected by a multi-threading loc...
The namespace containing all Design Pattern Examples implemented in C++.
std::string formatstring(const char *fmt,...)
Use the given string and arguments to return a buffer containing the formatted string....
Represents a handler in a chain of handlers. All objects that participate in the HandlerChain class m...
virtual int ID()=0
ID of the window. This is used to uniquely identify a window in the collection.
virtual std::string ToString()=0
Convert the handler to a string.
std::shared_ptr< IMessageHandler > shared_ptr_t
Alias to make it easier when using a shared pointer.
virtual bool ProcessMessage(Message *message)=0
Called with a message on each window.
virtual ~IMessageHandler()
Virtual destructor (required for interfaces in C++)
Represents a message sent to the windows. A message contains a type and a position.
Represents a message sent to the windows. A message contains a type and a position.