voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
sender.hpp
1 #ifndef SYNC_SENDER_HPP
2 #define SYNC_SENDER_HPP
3 
4 #include "blub/core/globals.hpp"
5 #include "blub/core/signal.hpp"
6 #include "blub/math/octree/container.hpp"
7 #include "blub/math/octree/search.hpp"
8 #include "blub/async/strand.hpp"
9 
10 #include "boost/function/function2.hpp"
11 #include "boost/function/function3.hpp"
12 
13 
14 namespace blub
15 {
16 namespace sync
17 {
18 
19 
20 template <typename syncType, typename receiverType>
21 class sender
22 {
23 public:
24  typedef syncType t_sync;
25  typedef receiverType t_receiver;
26 
27  typedef octree::container<t_sync> t_syncTree;
28  typedef octree::container<t_receiver> t_receiverTree;
29 
30  typedef hashMap<t_receiver, vector3> t_receiverPosMap;
31  typedef hashMap<t_sync, vector3> t_syncPosMap;
32 
33  typedef hashList<t_sync> t_syncList;
34  typedef hashList<t_receiver> t_receiverList;
35 
36  typedef hashMap<t_receiver, t_syncList> t_receiverToSyncsMap;
37  typedef hashMap<t_sync, t_receiverList> t_syncToReceiversMap;
38 
39  // callbacks
40  typedef boost::function<bool (t_receiver, vector3, typename t_syncTree::t_nodePtr)> t_callbackInSyncRangeReceiver;
41  typedef boost::function<bool (t_sync, vector3, typename t_receiverTree::t_nodePtr)> t_callbackInSyncRangeSync;
42 
43 
44  sender(blub::async::dispatcher &worker, const vector3int32& treeSize)
45  : m_master(worker)
46  , m_syncTree(treeSize)
47  , m_receiverTree(treeSize)
48  {
49 
50  }
51  virtual ~sender()
52  {
53  ;
54  }
55 
56  // to "send sync"
57  void addSync(const t_sync toSync, const vector3& pos)
58  {
59  m_master.dispatch(boost::bind(&sender::addSyncMaster, this, toSync, pos));
60  }
61  void updateSync(const t_sync toSync, const vector3& pos)
62  {
63  m_master.dispatch(boost::bind(&sender::updateSyncMaster, this, toSync, pos));
64  }
65  void removeSync(const t_sync toSync)
66  {
67  m_master.dispatch(boost::bind(&sender::removeSyncMaster, this, toSync));
68  }
69 
70  // add/update/remove sync-reveiver
71  void addReceiver(t_receiver receiver, const vector3& pos)
72  {
73  m_master.dispatch(boost::bind(&sender::addReceiverMaster, this, receiver, pos));
74  }
75  void updateReceiver(t_receiver receiver, const vector3& pos)
76  {
77  m_master.dispatch(boost::bind(&sender::updateReceiverMaster, this, receiver, pos));
78  }
79  void removeReceiver(t_receiver receiver)
80  {
81  m_master.dispatch(boost::bind(&sender::removeReceiverMaster, this, receiver));
82  }
83 
84  void addSyncMaster(const t_sync toSync, const vector3& pos)
85  {
86  BASSERT(m_syncPosMap.find(toSync) == m_syncPosMap.cend());
87  BASSERT(m_syncReceivers.find(toSync) == m_syncReceivers.cend());
88  BASSERT(m_syncTree.getNodes(toSync).empty());
89 
90  m_syncPosMap.insert(toSync, pos);
91 
92  m_syncReceivers.insert(toSync, t_receiverList());
93 
94 #ifdef BLUB_DEBUG
95  bool result =
96 #endif
97  m_syncTree.insert(toSync, pos);
98  BASSERT(result);
99 
100  updateLinkSyncReceiverMaster(toSync);
101  }
102  void updateSyncMaster(const t_sync toSync, const vector3& pos)
103  {
104  BASSERT(m_syncPosMap.find(toSync) != m_syncPosMap.cend());
105  BASSERT(m_syncReceivers.find(toSync) != m_syncReceivers.cend());
106  BASSERT(!m_syncTree.getNodes(toSync).empty());
107 
108  m_syncPosMap.insert(toSync, pos);
109 
110  if (!m_syncTree.update(toSync, pos))
111  {
112  // nothing changed
113  return;
114  }
115 
116  updateLinkSyncReceiverMaster(toSync);
117  }
118  void removeSyncMaster(const t_sync toSync)
119  {
120  BASSERT(m_syncPosMap.find(toSync) != m_syncPosMap.cend());
121  BASSERT(m_syncReceivers.find(toSync) != m_syncReceivers.cend());
122  BASSERT(!m_syncTree.getNodes(toSync).empty());
123 
124  {
125  m_syncPosMap.erase(m_syncPosMap.find(toSync));
126  }
127 
128  {
129 #ifdef BLUB_DEBUG
130  bool result =
131 #endif
132  m_syncTree.remove(toSync);
133  BASSERT(result);
134  }
135 
136  {
137  typename t_syncToReceiversMap::iterator it = m_syncReceivers.find(toSync);
138  BASSERT(it != m_syncReceivers.cend());
139  const t_receiverList& accordingReceivers(it->second);
140  while (!accordingReceivers.empty())
141  {
142  removeLinkSyncReceiverMaster(*accordingReceivers.cbegin(), toSync);
143  }
144  m_syncReceivers.erase(it);
145  }
146  }
147 
148  void addReceiverMaster(t_receiver receiver, const vector3& pos)
149  {
150  BASSERT(m_receiverPosMap.find(receiver) == m_receiverPosMap.cend());
151  BASSERT(m_receiverSyncs.find(receiver) == m_receiverSyncs.cend());
152  BASSERT(m_receiverTree.getNodes(receiver).empty());
153 
154  m_receiverPosMap.insert(receiver, pos);
155 
156  m_receiverSyncs.insert(receiver, t_syncList());
157 
158 #ifdef BLUB_DEBUG
159  bool result =
160 #endif
161  m_receiverTree.insert(receiver, pos);
162  BASSERT(result);
163 
164  updateLinkReceiverSyncMaster(receiver);
165  }
166  void updateReceiverMaster(t_receiver receiver, const vector3& pos)
167  {
168  BASSERT(m_receiverPosMap.find(receiver) != m_receiverPosMap.cend());
169  BASSERT(m_receiverSyncs.find(receiver) != m_receiverSyncs.cend());
170  BASSERT(!m_receiverTree.getNodes(receiver).empty());
171 
172  m_receiverPosMap.insert(receiver, pos);
173 
174  if (!m_receiverTree.update(receiver, pos))
175  {
176  // no update in tree, nothing to resync
177  // nothing changed
178  return;
179  }
180 
181  updateLinkReceiverSyncMaster(receiver);
182  }
183  void removeReceiverMaster(t_receiver receiver)
184  {
185  BASSERT(m_receiverPosMap.find(receiver) != m_receiverPosMap.cend());
186  BASSERT(m_receiverSyncs.find(receiver) != m_receiverSyncs.cend());
187  BASSERT(!m_receiverTree.getNodes(receiver).empty());
188 
189  {
190  m_receiverPosMap.erase(m_receiverPosMap.find(receiver));
191  }
192 
193  {
194 #ifdef BLUB_DEBUG
195  bool result =
196 #endif
197  m_receiverTree.remove(receiver);
198  BASSERT(result);
199  }
200 
201  {
202  typename t_receiverToSyncsMap::iterator it = m_receiverSyncs.find(receiver);
203  BASSERT(it != m_receiverSyncs.cend());
204  const t_syncList& accordingSyncs(it->second);
205  while (!accordingSyncs.empty())
206  {
207  removeLinkSyncReceiverMaster(receiver, *accordingSyncs.cbegin());
208  }
209  m_receiverSyncs.erase(it);
210  }
211  }
212 
213  blub::async::strand &getMaster()
214  {
215  return m_master;
216  }
217 
218  void setCallbackInSyncRangeReceiver(t_callbackInSyncRangeReceiver toSet)
219  {
220  m_callbackInSyncRangeReceiver = toSet;
221  }
222  void setCallbackInSyncRangeSync(t_callbackInSyncRangeSync toSet)
223  {
224  m_callbackInSyncRangeSync = toSet;
225  }
226 
228  t_sigAdd* signalAdd()
229  {
230  return &m_sigAdd;
231  }
232  typedef blub::signal<void (t_receiver, t_sync)> t_sigRemove;
233  t_sigRemove* signalRemove()
234  {
235  return &m_sigRemove;
236  }
237 
238 protected:
239  void updateLinkReceiverSyncMaster(t_receiver receiver)
240  {
241  auto leafs(m_receiverTree.getNodes(receiver));
242  BASSERT(leafs.size() == 1);
243  auto leaf(*leafs.begin());
244  vector3int32 centerLeaf(leaf->getPosition()+m_receiverTree.getMinNodeSize()/2);
245 
246  auto callbackForOctree(boost::bind(&sender<t_sync, t_receiver>::isInSyncRangeReceiver, this, receiver, vector3(centerLeaf.x, centerLeaf.y, centerLeaf.z), _1));
247  const typename octree::search<t_sync>::t_dataList result(octree::search<t_sync>::getDataByUserDefinedFunction(m_syncTree, callbackForOctree));
248 
249  typename t_receiverToSyncsMap::const_iterator it = m_receiverSyncs.find(receiver);
250  BASSERT(it != m_receiverSyncs.cend());
251 
252  // check for removed syncs
253  const t_syncList syncs(it->second);
254  {
255  for (t_sync sync : syncs)
256  {
257  if (result.find(sync) == result.cend())
258  {
259  removeLinkSyncReceiverMaster(receiver, sync);
260  }
261  }
262  }
263  // check for add sync
264  {
265  for (t_sync sync : result)
266  {
267  if (syncs.find(sync) == syncs.cend())
268  {
269  addLinkSyncReceiverMaster(receiver, sync);
270  }
271  }
272  }
273  }
274 
275  void updateLinkSyncReceiverMaster(t_sync sync)
276  {
277  if (m_receiverPosMap.empty()) // nothing to sync
278  {
279  return;
280  }
281 
282  auto leafs(m_syncTree.getNodes(sync));
283  BASSERT(leafs.size() == 1);
284  auto leaf(*leafs.begin());
285  vector3int32 centerLeaf(leaf->getPosition()+m_receiverTree.getMinNodeSize()/2);
286 
287  auto callbackForOctree(boost::bind(&sender<t_sync, t_receiver>::isInSyncRangeSync, this, sync, vector3(centerLeaf.x, centerLeaf.y, centerLeaf.z), _1));
288  const typename octree::search<t_receiver>::t_dataList result(octree::search<t_receiver>::getDataByUserDefinedFunction(m_receiverTree, callbackForOctree));
289 
290  typename t_syncToReceiversMap::const_iterator it = m_syncReceivers.find(sync);
291  BASSERT(it != m_syncReceivers.cend());
292 
293  // check for removed syncs
294  const t_receiverList receivers(it->second);
295  {
296  for (t_receiver receiver : receivers)
297  {
298  if (result.find(receiver) == result.cend())
299  {
300  removeLinkSyncReceiverMaster(receiver, sync);
301  }
302  }
303  }
304  // check for add sync
305  {
306  for (t_receiver receiver : result)
307  {
308  if (receivers.find(receiver) == receivers.cend())
309  {
310  addLinkSyncReceiverMaster(receiver, sync);
311  }
312  }
313  }
314  }
315 
316  void addLinkSyncReceiverMaster(const t_receiver receiver, const t_sync sync)
317  {
318  {
319  typename t_syncToReceiversMap::iterator itSync = m_syncReceivers.find(sync);
320  BASSERT(itSync != m_syncReceivers.cend());
321  BASSERT(itSync->second.find(receiver) == itSync->second.cend());
322  itSync->second.insert(receiver);
323  }
324  {
325  typename t_receiverToSyncsMap::iterator itReceiver = m_receiverSyncs.find(receiver);
326  BASSERT(itReceiver != m_receiverSyncs.cend());
327  BASSERT(itReceiver->second.find(sync) == itReceiver->second.cend());
328  itReceiver->second.insert(sync);
329  }
330  addSyncReceiver(receiver, sync);
331  }
332  void removeLinkSyncReceiverMaster(const t_receiver receiver, const t_sync sync)
333  {
334  {
335  typename t_syncToReceiversMap::iterator itSync = m_syncReceivers.find(sync);
336  BASSERT(itSync != m_syncReceivers.cend());
337  typename t_receiverList::const_iterator itReceiver = itSync->second.find(receiver);
338  BASSERT(itReceiver != itSync->second.cend());
339  itSync->second.erase(itReceiver);
340  }
341  {
342  typename t_receiverToSyncsMap::iterator itReceiver = m_receiverSyncs.find(receiver);
343  BASSERT(itReceiver != m_receiverSyncs.cend());
344  typename t_syncList::const_iterator itSync = itReceiver->second.find(sync);
345  BASSERT(itSync != itReceiver->second.cend());
346  itReceiver->second.erase(itSync);
347  }
348  removeSyncReceiver(receiver, sync);
349  }
350 
351  virtual bool isInSyncRangeReceiver(const t_receiver receiver, const vector3& posOfReceiverLeafCenter, const typename t_syncTree::t_nodePtr& octreeNode)
352  {
353  return m_callbackInSyncRangeReceiver(receiver, posOfReceiverLeafCenter, octreeNode);
354  }
355 
356  virtual bool isInSyncRangeSync(const t_sync sync, const vector3& posOfSyncLeafCenter, const typename t_receiverTree::t_nodePtr& octreeNode)
357  {
358  return m_callbackInSyncRangeSync(sync, posOfSyncLeafCenter, octreeNode);
359  }
360 
361  virtual void addSyncReceiver(const t_receiver receiver, const t_sync sync)
362  {
363  m_sigAdd(receiver, sync);
364  }
365 
366  virtual void removeSyncReceiver(const t_receiver receiver, const t_sync sync)
367  {
368  m_sigRemove(receiver, sync);
369  }
370 
371 protected:
372  async::strand m_master;
373 
374  t_syncTree m_syncTree;
375  t_syncToReceiversMap m_syncReceivers;
376  t_syncPosMap m_syncPosMap;
377 
378  t_receiverTree m_receiverTree;
379  t_receiverToSyncsMap m_receiverSyncs;
380  t_receiverPosMap m_receiverPosMap;
381 
382  t_callbackInSyncRangeReceiver m_callbackInSyncRangeReceiver;
383  t_callbackInSyncRangeSync m_callbackInSyncRangeSync;
384 
385  t_sigAdd m_sigAdd;
386  t_sigRemove m_sigRemove;
387 
388 };
389 
390 
391 
392 }
393 }
394 
395 
396 #endif // SYNC_SENDER_HPP
Definition: strand.hpp:16
Definition: dispatcher.hpp:29
Definition: deadlineTimer.hpp:10