VR-Forces 4.3 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 typename Feature::ForEachFunction ForEachFunction;
296  typedef typename Feature::Attribute Attribute;
297  typedef typename Feature::Key Key;
298 
299  typedef typename Inner::DetachCallback DetachCallback;
300 
302  {
305  myConnection.disconnect();
306  }
307 
309  {
310  return myData->feature->geometry();
311  }
312 
314  {
315  myData->feature->forEachAttribute(func);
316  }
317 
318  unsigned numberOfAttributes(const typename Key::String& str) const
319  {
320  return myData->feature->numberOfAttributes(str);
321  }
322 
323  boost::optional<Attribute> attribute(const Key& key) const
324  {
325  return myData->feature->attribute(key);
326  }
327 
329  : public DtObjectDebugger<DeletedCounter>
330  {
331  const typename Inner::DeleteCallback callback;
332  explicit DeletedCounter(const typename Inner::DeleteCallback& cb) : callback(cb) { }
333  void operator()() const { callback(); }
334  };
335 
337  const typename Inner::DeleteCallback& callback) const
338  {
339  if (!callback)
340  return DetachCallback();
341 
342  Mutex::scoped_lock lock(myData->mutex);
343  if (myData->deleted)
344  {
345  lock.release();
346  callback();
347  return DetachCallback();
348  }
349 
350  //Connection conn(mySignal.connect(callback, boost::signals2::at_front));
351  Connection conn = mySignal.connect(DeletedCounter(callback), boost::signals2::at_front);
352 
353  return boost::bind(&Connection::disconnect, conn);
354  }
355 
356  bool isDeleted() const
357  {
358  Mutex::scoped_lock lock(myData->mutex);
359  return myData->deleted;
360  }
361 
363  {
364  return new DtFeatureWrapper(*this);
365  }
366 
367  void setDeleted()
368  {
369  typename Data::SPtr d(myData);
370  d->deletedCallback();
371  }
372 
374  explicit DtFeatureWrapper(const DtFeatureWrapper& from)
375  : myData(from.myData)
376  , myConnection()
377  {
378  Mutex::scoped_lock lock(myData->mutex);
379  if (!myData->deleted)
380  myConnection = myData->signal.connect(boost::ref(mySignal), boost::signals2::at_front);
381  }
382 
383  explicit DtFeatureWrapper(const typename Inner::Ptr& f)
384  : myData(new Data(f))
385  , myConnection(myData->signal.connect(boost::ref(mySignal)))
386  {
387  myData->init(myData);
388  }
389 
391  explicit DtFeatureWrapper(Inner* feature)
392  : myData(new Data(typename Inner::Ptr(feature)))
393  , myConnection(myData->signal.connect(boost::ref(mySignal)))
394  {
395  myData->init(myData);
396  }
397 
398  explicit DtFeatureWrapper(const Inner& feature)
399  : myData(new Data(typename Inner::Ptr(feature.clone())))
400  , myConnection(myData->signal.connect(boost::ref(mySignal)))
401  {
402  myData->init(myData);
403  }
404 
405  Inner& wrappedFeature() { return *myData->feature; }
406  const Inner& wrappedFeature() const { return *myData->feature; }
407 
410 
411  private:
412  typedef tbb::spin_mutex Mutex;
413 
414  typedef boost::signals2::signal<void ()> Signal;
415  typedef boost::signals2::connection Connection;
416 
418  struct Data : boost::noncopyable
419  {
420  public:
421  typedef boost::shared_ptr<Data> SPtr;
422  typedef boost::weak_ptr<Data> WPtr;
423 
425  {
426  Mutex::scoped_lock lock(mutex);
427  if (!deleted)
428  {
429  deleted = true;
430  DetachCallback localDetacher;
431  swap(localDetacher, detacher);
432 
433  lock.release();
434 
435  try
436  {
437  if (localDetacher)
438  localDetacher();
439 
440  signal();
441  signal.disconnect_all_slots();
442  }
443  catch (...)
444  {
445  DtWarn << "Exception thrown in delete callback" << std::endl;
446  }
447  }
448  }
449 
450  explicit Data(const typename Inner::Ptr& f)
451  : feature(f)
453  {
454  }
455 
457  {
458  if (detacher)
459  detacher();
460  }
461 
462  bool init(const SPtr& This)
463  {
464  assert(!detacher);
465 
466  if (!deleted)
467  detacher = feature->addDeleteCallback(Caller(This));
468 
469  return detacher;
470  }
471 
473  struct Caller
474  {
476  explicit Caller(const SPtr& data) : datawptr(data) { }
477 
478  void operator()() const
479  {
480  SPtr data(datawptr.lock());
481  if (data)
482  data->deletedCallback();
483  }
484  };
485 
486  mutable Mutex mutex;
487  typename Inner::Ptr feature;
490  bool deleted;
491  };
492 
496  boost::shared_ptr<Data> myData;
497  mutable Signal mySignal;
499  };
500 
501  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Attribute&);
502  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature&);
503  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key&);
504  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key::String&);
505 
513 }
514 

Document ID: Generated on Wed Mar 11 21:20:57 EDT 2015 from SVN revision 150940
Copyright © 2005-2014 VT MÄK. All Rights Reserved (www.mak.com)