VR-Forces Development_Version Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
feature.h
Go to the documentation of this file.
1 /******************************************************************************
2  * Copyright (c) 2014 MAK Technologies, Inc.
3  * All rights reserved.
4  ******************************************************************************/
8 
9 #pragma once
10 
13 
14 #include <boost/shared_ptr.hpp>
15 #include <boost/function.hpp>
16 #include <boost/variant.hpp>
17 #include <boost/lexical_cast.hpp>
18 #include <boost/signals2.hpp>
19 
20 #include <tbb/spin_mutex.h>
21 
22 #include <vrfutil/objectCounter.h>
23 
24 #include <vlutil/vlPrint.h>
25 
26 namespace MAKVRinTerra
27 {
38  : private boost::noncopyable
39  , public DtObjectDebugger<DtFeature>
40  {
41  public:
42  static const char* TypeName;
43 
44  typedef boost::shared_ptr<DtFeature> Ptr;
45  typedef boost::shared_ptr<const DtFeature> CPtr;
46 
48  typedef boost::variant<
49  std::string,
50  int,
51  double
53 
55  template <typename T>
56  static boost::optional<T> ConvertAttribute(const Attribute& attr)
57  {
58  return boost::apply_visitor(AttributeConverter<T>(), attr);
59  }
60 
65  {
68  {
69  public:
70  String();
71  String(const std::string&);
72  String(const char*);
73 
75  const char* c_str() const;
76 
78  const std::string& str() const;
79 
80  bool operator==(const String&) const;
81  bool operator!=(const String&) const;
82  bool operator<(const String&) const;
83 
84  private:
85  std::string myString;
86  };
87 
88  Key(const std::string& name, unsigned index = 0);
89  Key(const String& name, unsigned index = 0);
90  Key(const char* name, unsigned index = 0);
91  Key(const Key& key, unsigned index = 0);
92 
93  bool operator== (const Key&) const;
94  bool operator!= (const Key&) const;
95  bool operator< (const Key&) const;
96 
98  unsigned index;
99  };
100 
103  static bool Equal(const Attribute&, const Attribute&);
104  static bool NotEqual(const Attribute&, const Attribute&);
105  static bool Less(const Attribute&, const Attribute&);
106  static bool LessOrEqual(const Attribute&, const Attribute&);
107  static bool Greater(const Attribute&, const Attribute&);
108  static bool GreaterOrEqual(const Attribute&, const Attribute&);
109  static bool Regex(const Attribute& text, const Attribute& pattern);
111 
113  static std::string TypeOfAttribute(const Attribute&);
114 
116  static std::auto_ptr<DtFeature> CreateEmptyFeature();
117 
119  static std::auto_ptr<DtFeature> CreateGeometryFeature(const DtFeatureGeometry&);
120 
123  static std::auto_ptr<DtFeature> CreateGeometryFeature(
124  const DtFeatureGeometry&,
125  unsigned char red, unsigned char green, unsigned char blue);
126 
129  static std::auto_ptr<DtFeature> CreateCopy(const DtFeature& feature);
130 
132  virtual ~DtFeature();
133 
140  virtual DtFeature* clone() const;
141 
147  virtual DtFeatureGeometry geometry() const = 0;
148 
150  typedef boost::function<void (const Key&, const Attribute&)> ForEachFunction;
151 
153  virtual void forEachAttribute(ForEachFunction f) const = 0;
154 
156  virtual unsigned numberOfAttributes(const Key::String &) const = 0;
157 
159  virtual bool hasAttribute(const Key & k) const;
160 
162  virtual boost::optional<Attribute> attribute(const Key &) const = 0;
163 
165  template <typename T>
166  boost::optional<T> attributeAs(const Key& k) const
167  {
168  if (boost::optional<Attribute> attr = attribute(k))
169  return boost::apply_visitor(AttributeConverter<T>(), *attr);
170 
171  return boost::none;
172  }
173 
176  typedef boost::function<void ()> DetachCallback;
177 
179  typedef boost::function<void ()> DeleteCallback;
180 
189  virtual DetachCallback addDeleteCallback(
190  const DeleteCallback& callback) const = 0;
191 
196  virtual bool isDeleted() const = 0;
197 
198  private:
201  template <typename T>
202  struct AttributeConverter : public boost::static_visitor< boost::optional<T> >
203  {
204  template <typename From>
205  boost::optional<T> operator()(const From& from) const
206  {
207  try
208  {
209  return boost::lexical_cast<T>(from);
210  }
211  catch (boost::bad_lexical_cast&)
212  {
213  return boost::optional<T>();
214  }
215  }
216  };
217  };
218 
219  template <typename Feature, typename Inner = Feature>
220  class DtFeatureRefWrapper : public Feature
221  {
222  public:
223  typedef typename Feature::ForEachFunction ForEachFunction;
224  typedef typename Feature::Attribute Attribute;
225  typedef typename Feature::Key Key;
226 
227  typedef typename Inner::DetachCallback DetachCallback;
228 
230  {
231  return myFeature.geometry();
232  }
233 
235  {
236  myFeature.forEachAttribute(func);
237  }
238 
239  unsigned numberOfAttributes(const typename Key::String& str) const
240  {
241  return myFeature.numberOfAttributes(str);
242  }
243 
244  boost::optional<Attribute> attribute(const Key& key) const
245  {
246  return myFeature.attribute(key);
247  }
248 
250  const typename Inner::DeleteCallback& callback) const
251  {
252  return myFeature.addDeleteCallback(callback);
253  }
254 
255  bool isDeleted() const
256  {
257  return myFeature.isDeleted();
258  }
259 
260  Feature* clone() const
261  {
262  return myFeature.clone();
263  }
264 
267  : myFeature(from.myFeature)
268  {
269  }
270 
271  explicit DtFeatureRefWrapper(const Inner& feature)
272  : myFeature(feature)
273  {
274  }
275 
276  //protected:
277  //Inner& wrappedFeature() { return myFeature; }
278  //const Inner& wrappedFeature() const { return myFeature; }
279 
280  protected:
281  const Inner& myFeature;
282  };
283 
291  template <typename Feature, typename Inner = Feature>
292  class DtFeatureWrapper : public Feature
293  {
294  public:
295  typedef boost::shared_ptr<DtFeatureWrapper> Ptr;
296  typedef boost::shared_ptr<const DtFeatureWrapper> CPtr;
297 
298  typedef typename Feature::ForEachFunction ForEachFunction;
299  typedef typename Feature::Attribute Attribute;
300  typedef typename Feature::Key Key;
301 
302  typedef typename Inner::DetachCallback DetachCallback;
303 
305  {
308  myConnection.disconnect();
309  }
310 
312  {
313  return myData->feature->geometry();
314  }
315 
317  {
318  myData->feature->forEachAttribute(func);
319  }
320 
321  unsigned numberOfAttributes(const typename Key::String& str) const
322  {
323  return myData->feature->numberOfAttributes(str);
324  }
325 
326  boost::optional<Attribute> attribute(const Key& key) const
327  {
328  return myData->feature->attribute(key);
329  }
330 
332  : public DtObjectDebugger<DeletedCounter>
333  {
334  const typename Inner::DeleteCallback callback;
335  explicit DeletedCounter(const typename Inner::DeleteCallback& cb) : callback(cb) { }
336  void operator()() const { callback(); }
337  };
338 
340  const typename Inner::DeleteCallback& callback) const
341  {
342  if (!callback)
343  return DetachCallback();
344 
345  Mutex::scoped_lock lock(myData->mutex);
346  if (myData->deleted)
347  {
348  lock.release();
349  callback();
350  return DetachCallback();
351  }
352 
353  Connection conn = mySignal.connect(
354  DeletedCounter(callback), boost::signals2::at_front);
355 
356  return boost::bind(&Connection::disconnect, conn);
357  }
358 
359  bool isDeleted() const
360  {
361  Mutex::scoped_lock lock(myData->mutex);
362  return myData->deleted;
363  }
364 
366  {
367  return new DtFeatureWrapper(*this);
368  }
369 
370  void setDeleted()
371  {
372  typename Data::SPtr d(myData);
373  d->deletedCallback();
374  }
375 
377  explicit DtFeatureWrapper(const DtFeatureWrapper& from)
378  : myData(from.myData)
379  , myConnection()
380  {
381  Mutex::scoped_lock lock(myData->mutex);
382  if (!myData->deleted)
383  myConnection = myData->signal.connect(boost::ref(mySignal), boost::signals2::at_front);
384  }
385 
386  explicit DtFeatureWrapper(const typename Inner::Ptr& f)
387  : myData(new Data(f))
388  , myConnection(myData->signal.connect(boost::ref(mySignal)))
389  {
390  myData->init(myData);
391  }
392 
394  explicit DtFeatureWrapper(Inner* feature)
395  : myData(new Data(typename Inner::Ptr(feature)))
396  , myConnection(myData->signal.connect(boost::ref(mySignal)))
397  {
398  myData->init(myData);
399  }
400 
401  explicit DtFeatureWrapper(const Inner& feature)
402  : myData(new Data(typename Inner::Ptr(feature.clone())))
403  , myConnection(myData->signal.connect(boost::ref(mySignal)))
404  {
405  myData->init(myData);
406  }
407 
408  Inner& wrappedFeature() { return *myData->feature; }
409  const Inner& wrappedFeature() const { return *myData->feature; }
410 
413 
414  private:
415  typedef tbb::spin_mutex Mutex;
416 
417  typedef boost::signals2::signal_type<
418  void (),
419  boost::signals2::keywords::mutex_type<tbb::spin_mutex> >::type Signal;
420 
421  typedef boost::signals2::connection Connection;
422 
424  struct Data : boost::noncopyable
425  {
426  public:
427  typedef boost::shared_ptr<Data> SPtr;
428  typedef boost::weak_ptr<Data> WPtr;
429 
431  {
432  Mutex::scoped_lock lock(mutex);
433  if (!deleted)
434  {
435  deleted = true;
436  DetachCallback localDetacher;
437  swap(localDetacher, detacher);
438 
439  lock.release();
440 
441  try
442  {
443  if (localDetacher)
444  localDetacher();
445 
446  signal();
447  signal.disconnect_all_slots();
448  }
449  catch (...)
450  {
451  DtWarn << "Exception thrown in delete callback" << std::endl;
452  }
453  }
454  }
455 
456  explicit Data(const typename Inner::Ptr& f)
457  : feature(f)
459  {
460  }
461 
463  {
464  if (detacher)
465  detacher();
466  }
467 
468  bool init(const SPtr& This)
469  {
470  assert(!detacher);
471 
472  if (!deleted)
473  detacher = feature->addDeleteCallback(Caller(This));
474 
475  return detacher;
476  }
477 
479  struct Caller
480  {
482  explicit Caller(const SPtr& data) : datawptr(data) { }
483 
484  void operator()() const
485  {
486  SPtr data(datawptr.lock());
487  if (data)
488  data->deletedCallback();
489  }
490  };
491 
492  mutable Mutex mutex;
493  typename Inner::Ptr feature;
496  bool deleted;
497  };
498 
502  boost::shared_ptr<Data> myData;
503  mutable Signal mySignal;
505  };
506 
507  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Attribute&);
508  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature&);
509  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key&);
510  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key::String&);
511 
519 }
520 

Document ID: Generated on Mon Jul 4 01:00:18 EDT 2016 from SVN revision 166489
Copyright © 2005-2015 VT MÄK. All Rights Reserved (www.mak.com)