VR-Forces Developer's Guide
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
DtKeyedDataManagerTemplate.h
Go to the documentation of this file.
1 /******************************************************************************
2 ** Copyright (c) 2023 MAK Technologies, Inc.
3 ** All rights reserved.
4 ******************************************************************************/
5 
9 
10 #pragma once
11 
12 #include <vrvCore/vrvCore.h>
13 
14 #include <vrvUtil/signalslib.h>
15 
19 
20 #include <tbb/concurrent_hash_map.h>
21 #include <tbb/concurrent_unordered_set.h>
22 #include <tbb/concurrent_vector.h>
23 #include <tbb/concurrent_queue.h>
24 #include <tbb/parallel_for.h>
25 
26 #include <thread>
27 #include <functional>
28 
29 #include <vlutil/vlUtil.h>
30 
31 
32 namespace makVrv
33 {
34  class DtKeyedData;
35 
37  {
38  DtKeyedData* myTcsData = nullptr;
39  bool myCreated = false;
40  };
41 
47  template<typename KeyType, typename KeyTypeHasher>
49  {
50  public:
52  {
53  PRE_TICK = 0, POST_TICK = 1, NONE = 2
54  };
55  public:
56  boost::signalslib::signal<void()> signal_KeysDeleted;
57  public:
59 
62  private:
64  DtKeyedDataManagerTemplate() = delete;
69 
70  public:
72  virtual CreationResult getOrCreate(const KeyType& key);
73 
75  virtual DtKeyedData* find(const KeyType& key) const;
76 
79  virtual void forEachKeyedData(const std::function<void(DtKeyedData*)>& func);
80 
82  virtual void keyedDatas(std::vector<DtKeyedData*>& vecKeyedDatas);
83 
84  template <class T>
86  {
87  T* myTcsUserData = nullptr;
88  bool myCreated = false;
89  };
90 
92  template<class ClassToCreate, class ...ConstructorArgs>
93  TemplatedCreationResult<ClassToCreate> getOrCreateUserData(const KeyType& key, const void* userPointer
94  , DtVirtualBaseClassCreator<ClassToCreate, ConstructorArgs...>* creator, ConstructorArgs&&... constructorArgs)
95  {
96  auto result = getOrCreate(key);
97  DtKeyedData* tcsData = result.myTcsData;
98  if (tcsData == nullptr)
99  {
100  myDe.DT_LOG_WARN << "tcsData == nullptr" << std::endl;
101  return TemplatedCreationResult<ClassToCreate>{nullptr, false};
102  }
103 
104  auto resultUserData = tcsData->getOrCreateUserData(userPointer, creator, std::forward<ConstructorArgs>(constructorArgs)...);
105  ClassToCreate* userData = static_cast<ClassToCreate*>(resultUserData.myTcsUserData);
106  if (userData == nullptr)
107  {
108  myDe.DT_LOG_WARN << "userData == nullptr" << std::endl;
109  }
110 
111  return TemplatedCreationResult<ClassToCreate>{userData, resultUserData.myCreated};
112  }
114  template<class T>
115  T* findUserData(const KeyType& key, const void* userPointer, bool log = true) const
116  {
117  DtKeyedData* tcsData = find(key);
118  if (tcsData == nullptr)
119  {
120  if (log)
121  {
122  myDe.DT_LOG_WARN << "tcsData == nullptr" << std::endl;
123  }
124  return nullptr;
125  }
126  T* userData = static_cast<T*>(tcsData->findUserData(userPointer));
127  if (userData == nullptr)
128  {
129  if (log)
130  {
131  myDe.DT_LOG_WARN << "userData == nullptr" << std::endl;
132  }
133  }
134  return userData;
135  }
136 
137  template <class T>
138  struct FindResult
139  {
140  DtKeyedData* myTcsData = nullptr;
141  T* myTcsUserData = nullptr;
142  };
143 
145  template<class T>
146  FindResult<T> findTcsDataAndUserData(const KeyType& key, const void* userPointer, bool log = true) const
147  {
148  DtKeyedData* tcsData = find(key);
149  if (tcsData == nullptr)
150  {
151  if (log)
152  {
153  myDe.DT_LOG_WARN << "tcsData == nullptr" << std::endl;
154  }
155  return { nullptr, nullptr };
156  }
157  T* userData = static_cast<T*>(tcsData->findUserData(userPointer));
158  if (userData == nullptr)
159  {
160  if (log)
161  {
162  myDe.DT_LOG_WARN << "userData == nullptr" << std::endl;
163  }
164  }
165  return { tcsData, userData };
166  }
167 
170  virtual void deleteTcsData(DtKeyedData* tcsData);
171  protected:
173  virtual void slot_preTick();
174 
176  virtual void slot_postTick();
177 
179  virtual void flushInvalidKeys();
180  protected:
181 
182  typedef tbb::concurrent_hash_map< KeyType, DtKeyedData*, KeyTypeHasher> HashTable;
184 
186 
189 
190  tbb::concurrent_queue<KeyType> myKeysToEraseScratchPad;
191  };
192 
193  template<typename KeyType, typename KeyTypeHasher>
195  : myDe(de)
196  {
197  if (flushLocation == PRE_TICK)
198  {
199  myConnections += myDe.signal_preTick.connect(
201  this));
202  }
203  else if (flushLocation == POST_TICK)
204  {
207  this));
208  }
209  else if (flushLocation == NONE)
210  {
211  // no op
212  }
213  else
214  {
215  myDe.DT_LOG_WARN << "Unknown flush location: " << flushLocation << std::endl;
216  }
217  }
218 
219  template<typename KeyType, typename KeyTypeHasher>
221  {
222  tbb::parallel_for(myHashTable.range(), [](const typename HashTable::range_type& r) {
223  for (auto i = r.begin(); i != r.end(); i++)
224  {
225  DtDELETE(i->second);
226  }
227  });
228  }
229 
230  template<typename KeyType, typename KeyTypeHasher>
232  {
233  tbb::parallel_for(myHashTable.range(), [=](const typename HashTable::range_type& r) {
234  for (auto i = r.begin(); i != r.end(); i++)
235  {
236  func(i->second);
237  }
238  });
239  }
240 
241  template<typename KeyType, typename KeyTypeHasher>
242  void DtKeyedDataManagerTemplate<KeyType, KeyTypeHasher>::keyedDatas(std::vector<DtKeyedData*>& vecKeyedDatas)
243  {
244  tbb::concurrent_queue<DtKeyedData*> queueKeyedDatas;
245  tbb::parallel_for(myHashTable.range(), [&](const typename HashTable::range_type& r) {
246  for (auto i = r.begin(); i != r.end(); i++)
247  {
248  queueKeyedDatas.push(i->second);
249  }
250  });
251 
252  DtKeyedData* keyedData = nullptr;
253  while (queueKeyedDatas.try_pop(keyedData))
254  {
255  vecKeyedDatas.push_back(keyedData);
256  }
257  }
258 
259  template<typename KeyType, typename KeyTypeHasher>
261  {
262  CreationResult result;
263  typename HashTable::accessor accessor;
264  const bool inserted = myHashTable.insert(accessor, key);
265  if (inserted)
266  {
267  auto& entry = accessor->second;
268  entry = new DtKeyedData(myDe, key.myName);
269  }
270 
271  DtKeyedData* tcsData = accessor->second;
272  if (tcsData == nullptr)
273  {
274  myDe.DT_LOG_WARN << "tcsData == nullptr" << std::endl;
275  }
276  return { tcsData, inserted };
277  }
278 
279  template<typename KeyType, typename KeyTypeHasher>
281  {
282  typename HashTable::const_accessor accessor;
283  const bool found = myHashTable.find(accessor, key);
284  if (found == false)
285  {
286  return nullptr;
287  }
288  return accessor->second;
289  }
290 
291  template<typename KeyType, typename KeyTypeHasher>
293  {
294  if (tcsData == nullptr)
295  {
296  myDe.DT_LOG_WARN << "tcsData == nullptr" << std::endl;
297  return;
298  }
299 
300  KeyType keyToErase;
301  std::atomic<bool> found{ false };
302  tbb::parallel_for(myHashTable.range(), [&](const typename HashTable::range_type& r) {
303  for (auto i = r.begin(); i != r.end(); i++)
304  {
305  if (i->second == tcsData)
306  {
307  found = true;
308  keyToErase = i->first;
309  }
310  }
311  });
312 
313  if (!found)
314  {
315  myDe.DT_LOG_WARN << "found == false" << std::endl;
316  return;
317  }
318 
319  myHashTable.erase(keyToErase);
320  DtDELETE(tcsData);
321  }
322 
323  template<typename KeyType, typename KeyTypeHasher>
325  {
326  myKeysToEraseScratchPad.clear();
327  tbb::parallel_for(myHashTable.range(), [&](const typename HashTable::range_type& r) {
328  for (auto i = r.begin(); i != r.end(); i++)
329  {
330  if (!i->first.valid())
331  {
332  myKeysToEraseScratchPad.push(i->first);
333  }
334  }
335  });
336 
337 
338  bool atleastOneDeleted = false;
339  KeyType key;
340  while (myKeysToEraseScratchPad.try_pop(key))
341  {
342  typename HashTable::accessor accessor;
343  bool found = myHashTable.find(accessor, key);
344  if (!found)
345  {
346  myDe.DT_LOG_WARN << "found == false" << std::endl;
347  continue;
348  }
349  DtDELETE(accessor->second);
350  myHashTable.erase(accessor);
351  atleastOneDeleted = true;
352  }
353 
354  if (atleastOneDeleted)
355  {
356  signal_KeysDeleted();
357  }
358  }
359 
360  template<typename KeyType, typename KeyTypeHasher>
362  {
363  flushInvalidKeys();
364  }
365 
366  template<typename KeyType, typename KeyTypeHasher>
368  {
369  flushInvalidKeys();
370  }
371 }
T * myTcsUserData
Definition: DtKeyedDataManagerTemplate.h:141
FlushKeysLocation
Definition: DtKeyedDataManagerTemplate.h:51
Virtual base class. Allows for RTTI and proper virtual destruction. Used by Creators, Factories, Providers, Assemblers and User Interfaces.
Definition: DtVirtualBaseClass.h:19
T * findUserData(const KeyType &key, const void *userPointer, bool log=true) const
find user data for a class T
Definition: DtKeyedDataManagerTemplate.h:115
boost::signalslib::signal< void(DtDe &)> signal_preTick
Signal emitted at the beginning of the tick function. This is useful for executing code before the Di...
Definition: DtDe.h:489
DtDe & myDe
Definition: DtKeyedDataManagerTemplate.h:185
virtual DtKeyedDataUserData * findUserData(const void *userPointer) const
find tc user data
virtual void keyedDatas(std::vector< DtKeyedData * > &vecKeyedDatas)
Get the keyed datas.
Definition: DtKeyedDataManagerTemplate.h:242
DtKeyedData * myTcsData
Definition: DtKeyedDataManagerTemplate.h:140
DtKeyedData * myTcsData
Definition: DtKeyedDataManagerTemplate.h:38
bool myCreated
Definition: DtKeyedDataManagerTemplate.h:39
boost::signalslib::signal< void()> signal_postTick
Signal emitted at the end of the tick function. This is useful for executing code after the Display E...
Definition: DtDe.h:496
tbb::concurrent_hash_map< KeyType, DtKeyedData *, KeyTypeHasher > HashTable
Definition: DtKeyedDataManagerTemplate.h:182
Definition: DtKeyedDataManagerTemplate.h:138
This class is used in conjunction with DtKeyedDataManagerTemplate. It represents data associated with...
Definition: DtKeyedData.h:30
virtual void slot_preTick()
pre tick function
Definition: DtKeyedDataManagerTemplate.h:361
virtual void flushInvalidKeys()
flush cameras that go out of the system
Definition: DtKeyedDataManagerTemplate.h:324
Variadic templated creator class for defining a DtVirtualBaseClass creator that is automatically regi...
Definition: DtVirtualBaseClassCreator.h:22
FindResult< T > findTcsDataAndUserData(const KeyType &key, const void *userPointer, bool log=true) const
find tcs data and user data for a class T
Definition: DtKeyedDataManagerTemplate.h:146
Contains makVrv::DtVirtualBaseClass class.
virtual CreationResult getOrCreate(const KeyType &key)
get or create the keyed data
Definition: DtKeyedDataManagerTemplate.h:260
Definition: DtKeyedDataManagerTemplate.h:85
binderNoArgs< _Fn > bind(const _Fn &_Func, const _Ty &_Left)
Definition: DtSTLUtilities.h:76
Definition: DtKeyedDataManagerTemplate.h:53
Definition: DtKeyedDataManagerTemplate.h:36
virtual ~DtKeyedDataManagerTemplate()
destructor
Definition: DtKeyedDataManagerTemplate.h:220
boost::signalslib::signal< void()> signal_KeysDeleted
Definition: DtKeyedDataManagerTemplate.h:56
HashTable myHashTable
Definition: DtKeyedDataManagerTemplate.h:183
Class to manage disconnection of boost connections on deletion.
Definition: DtSignalConnectionManager.h:20
UserDataCreationResult getOrCreateUserData(const void *userPointer, DtVirtualBaseClassCreator< ClassToCreate, ConstructorArgs...> *creator, ConstructorArgs &&...constructorArgs)
get or create the tcs user data
Definition: DtKeyedData.h:74
Manager for DtKeyedData Used to create/manage DtKeyedData Each entry of DtKeyedData is associated wit...
Definition: DtKeyedDataManagerTemplate.h:48
T * myTcsUserData
Definition: DtKeyedDataManagerTemplate.h:87
Base class to provide boost signal/slot management.
virtual void deleteTcsData(DtKeyedData *tcsData)
Delete tcs data, if it exists. Will also delete the user datas, if any.
Definition: DtKeyedDataManagerTemplate.h:292
virtual DtKeyedData * find(const KeyType &key) const
find tcs data
Definition: DtKeyedDataManagerTemplate.h:280
The DtDe is the core component of any VR-Vantage application. It owns a DtRenderer, DtDeCommunicator, as well as a DtDisplay and other things.
Definition: DtDe.h:72
DtKeyedDataManagerTemplate()=delete
not allowed
bool myCreated
Definition: DtKeyedDataManagerTemplate.h:88
virtual void slot_postTick()
post tick function
Definition: DtKeyedDataManagerTemplate.h:367
Definition: DtKeyedDataManagerTemplate.h:53
TemplatedCreationResult< ClassToCreate > getOrCreateUserData(const KeyType &key, const void *userPointer, DtVirtualBaseClassCreator< ClassToCreate, ConstructorArgs...> *creator, ConstructorArgs &&...constructorArgs)
get or create user data for a class T
Definition: DtKeyedDataManagerTemplate.h:93
DtSignalConnectionManager myConnections
manager for connections
Definition: DtKeyedDataManagerTemplate.h:188
DtKeyedDataManagerTemplate & operator=(const DtKeyedDataManagerTemplate &rhs)=delete
not allowed
tbb::concurrent_queue< KeyType > myKeysToEraseScratchPad
Definition: DtKeyedDataManagerTemplate.h:190
Definition: DtKeyedDataManagerTemplate.h:53
virtual void forEachKeyedData(const std::function< void(DtKeyedData *)> &func)
call a function on each keyed data. Note: the call may happen in a different thread than the thread t...
Definition: DtKeyedDataManagerTemplate.h:231
Contains DLL export macros.

Document ID: Generated on Wed Mar 27 22:49:11 EDT 2024 from SVN revision 264633
Copyright © 2005-2024 MAK Technologies. All Rights Reserved (www.mak.com)