VR-Forces 4.8 Class Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties 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  : public DtObjectDebugger<DtFeature>
39  {
40  public:
41  static const char* TypeName;
42 
43  typedef boost::shared_ptr<DtFeature> Ptr;
44  typedef boost::shared_ptr<const DtFeature> CPtr;
45 
46  DtFeature() {};
47 
49  typedef boost::variant<
50  std::string,
51  long long,
52  bool,
53  double
54  > Attribute;
55 
57  template <typename T>
58  static boost::optional<T> ConvertAttribute(const Attribute& attr)
59  {
60  return boost::apply_visitor(AttributeConverter<T>(), attr);
61  }
62 
67  {
70  {
71  public:
72  String();
73  String(const std::string&);
74  String(const char*);
75 
77  const char* c_str() const;
78 
80  const std::string& str() const;
81 
82  bool operator==(const String&) const;
83  bool operator!=(const String&) const;
84  bool operator<(const String&) const;
85 
86  private:
87  std::string myString;
88  };
89 
90  Key(const std::string& name, unsigned index = 0);
91  Key(const String& name, unsigned index = 0);
92  Key(const char* name, unsigned index = 0);
93  Key(const Key& key, unsigned index = 0);
94 
95  bool operator== (const Key&) const;
96  bool operator!= (const Key&) const;
97  bool operator< (const Key&) const;
98 
100  unsigned index;
101  };
102 
105  static bool Equal(const Attribute&, const Attribute&);
106  static bool NotEqual(const Attribute&, const Attribute&);
107  static bool Less(const Attribute&, const Attribute&);
108  static bool LessOrEqual(const Attribute&, const Attribute&);
109  static bool Greater(const Attribute&, const Attribute&);
110  static bool GreaterOrEqual(const Attribute&, const Attribute&);
111  static bool Regex(const Attribute& text, const Attribute& pattern);
113 
115  static std::string TypeOfAttribute(const Attribute&);
116 
118  static std::auto_ptr<DtFeature> CreateEmptyFeature();
119 
121  static std::auto_ptr<DtFeature> CreateGeometryFeature(const DtFeatureGeometry&);
122 
125  static std::auto_ptr<DtFeature> CreateGeometryFeature(
126  const DtFeatureGeometry&,
127  unsigned char red, unsigned char green, unsigned char blue);
128 
131  static std::auto_ptr<DtFeature> CreateCopy(const DtFeature& feature);
132 
134  virtual ~DtFeature();
135 
142  virtual DtFeature* clone() const;
143 
149  virtual DtFeatureGeometry geometry() const { return DtFeatureGeometry(); };
150 
152  typedef boost::function<void (const Key&, const Attribute&)> ForEachFunction;
153 
155  virtual void forEachAttribute(ForEachFunction f) const {};
156 
158  virtual unsigned numberOfAttributes(const Key::String &) const { return 0; };
159 
161  virtual bool hasAttribute(const Key & k) const;
162 
164  virtual boost::optional<Attribute> attribute(const Key &) const {return boost::none;};
165 
167  template <typename T>
168  boost::optional<T> attributeAs(const Key& k) const
169  {
170  if (boost::optional<Attribute> attr = attribute(k))
171  return boost::apply_visitor(AttributeConverter<T>(), *attr);
172 
173  return boost::none;
174  }
175 
178  typedef boost::function<void ()> DetachCallback;
179 
181  typedef boost::function<void ()> DeleteCallback;
182 
192  const DeleteCallback& callback) const { return callback; };
193 
198  virtual bool isDeleted() const { return false; };
199 
200  public:
201  //Defining copy ctor here to satisfy boost::bind & compiler. However, we pass all DtFeature objects by reference so this function should
202  //never be hit. (used in attributeConfigParser.cxx::stringParser ctor)
203  DtFeature(const DtFeature&) { throw std::runtime_error("DtFeature copy ctor, should not hit! At " __FILE__ ":" + __LINE__); };
204 
205  private:
208  template <typename T>
209  struct AttributeConverter : public boost::static_visitor< boost::optional<T> >
210  {
211  template <typename From>
212  boost::optional<T> operator()(const From& from) const
213  {
214  try
215  {
216  return boost::lexical_cast<T>(from);
217  }
218  catch (boost::bad_lexical_cast&)
219  {
220  return boost::optional<T>();
221  }
222  }
223  };
224  };
225 
226  template <typename Feature, typename Inner = Feature>
227  class DtFeatureRefWrapper : public Feature
228  {
229  public:
230  typedef typename Feature::ForEachFunction ForEachFunction;
231  typedef typename Feature::Attribute Attribute;
232  typedef typename Feature::Key Key;
233 
234  typedef typename Inner::DetachCallback DetachCallback;
235 
237  {
238  return myFeature.geometry();
239  }
240 
242  {
243  myFeature.forEachAttribute(func);
244  }
245 
246  unsigned numberOfAttributes(const typename Key::String& str) const
247  {
248  return myFeature.numberOfAttributes(str);
249  }
250 
251  boost::optional<Attribute> attribute(const Key& key) const
252  {
253  return myFeature.attribute(key);
254  }
255 
257  const typename Inner::DeleteCallback& callback) const
258  {
259  return myFeature.addDeleteCallback(callback);
260  }
261 
262  bool isDeleted() const
263  {
264  return myFeature.isDeleted();
265  }
266 
267  Feature* clone() const
268  {
269  return myFeature.clone();
270  }
271 
274  : myFeature(from.myFeature)
275  {
276  }
277 
278  explicit DtFeatureRefWrapper(const Inner& feature)
279  : myFeature(feature)
280  {
281  }
282 
283  //protected:
284  //Inner& wrappedFeature() { return myFeature; }
285  //const Inner& wrappedFeature() const { return myFeature; }
286 
287  protected:
288  const Inner& myFeature;
289  };
290 
298  template <typename Feature, typename Inner = Feature>
299  class DtFeatureWrapper : public Feature
300  {
301  public:
302  typedef boost::shared_ptr<DtFeatureWrapper> Ptr;
303  typedef boost::shared_ptr<const DtFeatureWrapper> CPtr;
304 
305  typedef typename Feature::ForEachFunction ForEachFunction;
306  typedef typename Feature::Attribute Attribute;
307  typedef typename Feature::Key Key;
308 
309  typedef typename Inner::DetachCallback DetachCallback;
310 
312  {
315  myConnection.disconnect();
316  }
317 
319  {
320  return myData->feature->geometry();
321  }
322 
324  {
325  myData->feature->forEachAttribute(func);
326  }
327 
328  unsigned numberOfAttributes(const typename Key::String& str) const
329  {
330  return myData->feature->numberOfAttributes(str);
331  }
332 
333  boost::optional<Attribute> attribute(const Key& key) const
334  {
335  return myData->feature->attribute(key);
336  }
337 
339  : public DtObjectDebugger<DeletedCounter>
340  {
341  const typename Inner::DeleteCallback callback;
342  explicit DeletedCounter(const typename Inner::DeleteCallback& cb) : callback(cb) { }
343  void operator()() const { callback(); }
344  };
345 
347  const typename Inner::DeleteCallback& callback) const
348  {
349  if (!callback)
350  return DetachCallback();
351 
352  Mutex::scoped_lock lock(myData->mutex);
353  if (myData->deleted)
354  {
355  lock.release();
356  callback();
357  return DetachCallback();
358  }
359 
360  Connection conn = mySignal.connect(
361  DeletedCounter(callback), boost::signals2::at_front);
362 
363  return boost::bind(&Connection::disconnect, conn);
364  }
365 
366  bool isDeleted() const
367  {
368  Mutex::scoped_lock lock(myData->mutex);
369  return myData->deleted;
370  }
371 
373  {
374  return new DtFeatureWrapper(*this);
375  }
376 
377  void setDeleted()
378  {
379  typename Data::SPtr d(myData);
380  d->deletedCallback();
381  }
382 
384  explicit DtFeatureWrapper(const DtFeatureWrapper& from)
385  : myData(from.myData)
386  , myConnection()
387  {
388  Mutex::scoped_lock lock(myData->mutex);
389  if (!myData->deleted)
390  myConnection = myData->signal.connect(std::ref(mySignal), boost::signals2::at_front);
391  }
392 
393  explicit DtFeatureWrapper(const typename Inner::Ptr& f)
394  : myData(new Data(f))
395  , myConnection(myData->signal.connect(std::ref(mySignal)))
396  {
397  myData->init(myData);
398  }
399 
401  explicit DtFeatureWrapper(Inner* feature)
402  : myData(new Data(typename Inner::Ptr(feature)))
403  , myConnection(myData->signal.connect(std::ref(mySignal)))
404  {
405  myData->init(myData);
406  }
407 
408  explicit DtFeatureWrapper(const Inner& feature)
409  : myData(new Data(typename Inner::Ptr(feature.clone())))
410  , myConnection(myData->signal.connect(std::ref(mySignal)))
411  {
412  myData->init(myData);
413  }
414 
415  Inner& wrappedFeature() { return *myData->feature; }
416  const Inner& wrappedFeature() const { return *myData->feature; }
417 
420 
421  private:
422  typedef tbb::spin_mutex Mutex;
423 
424  typedef boost::signals2::signal_type<
425  void (),
426  boost::signals2::keywords::mutex_type<tbb::spin_mutex> >::type Signal;
427 
428  typedef boost::signals2::connection Connection;
429 
431  struct Data : boost::noncopyable
432  {
433  public:
434  typedef boost::shared_ptr<Data> SPtr;
435  typedef boost::weak_ptr<Data> WPtr;
436 
438  {
439  Mutex::scoped_lock lock(mutex);
440  if (!deleted)
441  {
442  deleted = true;
443  DetachCallback localDetacher;
444  swap(localDetacher, detacher);
445 
446  lock.release();
447 
448  try
449  {
450  if (localDetacher)
451  localDetacher();
452 
453  signal();
454  signal.disconnect_all_slots();
455  }
456  catch (...)
457  {
458  DtWarn << "Exception thrown in delete callback" << std::endl;
459  }
460  }
461  }
462 
463  explicit Data(const typename Inner::Ptr& f)
464  : feature(f)
466  {
467  }
468 
470  {
471  if (detacher)
472  detacher();
473  }
474 
475  bool init(const SPtr& This)
476  {
477  assert(!detacher);
478 
479  if (!deleted)
480  detacher = feature->addDeleteCallback(Caller(This));
481 
482  return detacher;
483  }
484 
486  struct Caller
487  {
489  explicit Caller(const SPtr& data) : datawptr(data) { }
490 
491  void operator()() const
492  {
493  SPtr data(datawptr.lock());
494  if (data)
495  data->deletedCallback();
496  }
497  };
498 
499  mutable Mutex mutex;
500  typename Inner::Ptr feature;
503  bool deleted;
504  };
505 
509  boost::shared_ptr<Data> myData;
510  mutable Signal mySignal;
512  };
513 
514  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Attribute&);
515  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature&);
516  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key&);
517  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key::String&);
518 
526 }
527 
Feature::Attribute Attribute
Definition: feature.h:306
#define DT_DLL_features
stop complaining about multiple independent base classes for boost::noncopyable this should probably ...
Definition: featuresDefines.h:36
void operator()() const
Definition: feature.h:491
boost variant visitor for converting attributes with lexical_cast lexical_cast will not do anything f...
Definition: feature.h:209
Data(const typename Inner::Ptr &f)
Definition: feature.h:463
DtFeatureGeometry geometry() const
Definition: feature.h:318
Key used to lookup attributes.
Definition: feature.h:66
boost::shared_ptr< DtFeature > Ptr
Definition: feature.h:43
Inner::DetachCallback DetachCallback
Definition: feature.h:309
bool deleted
Definition: feature.h:503
Inner::DetachCallback DetachCallback
Definition: feature.h:234
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:241
boost::signals2::signal_type< void(), boost::signals2::keywords::mutex_type< tbb::spin_mutex > >::type Signal
Definition: feature.h:426
Wraps a feature object and makes sure all the callbacks are unhooked correctly In order to wrap a fea...
Definition: feature.h:299
bool isDeleted() const
Definition: feature.h:262
std::string myString
Definition: feature.h:87
DtFeatureWrapper * clone() const
Definition: feature.h:372
Feature::Attribute Attribute
Definition: feature.h:231
boost::shared_ptr< const DtFeature > CPtr
Definition: feature.h:44
const Inner & myFeature
Definition: feature.h:288
boost::shared_ptr< Data > SPtr
Definition: feature.h:434
DT_DLL_terrainCS bool operator==(const DtDegMinSec &lhs, const DtDegMinSec &rhs)
#define DT_DEFINE_OBJECT_DEBUGGER_NAME(type)
Definition: objectCounter.h:265
Default on in debug, off in release.
Definition: objectCounter.h:31
Feature::Key Key
Definition: feature.h:307
DT_DLL_features std::ostream & operator<<(std::ostream &, const DtFeatureTransform &)
std::ostream output.
DtFeatureRefWrapper(const Inner &feature)
Definition: feature.h:278
void setDeleted()
Definition: feature.h:377
Feature::ForEachFunction ForEachFunction
Definition: feature.h:230
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:346
Inner & wrappedFeature()
Definition: feature.h:415
boost::optional< T > operator()(const From &from) const
Definition: feature.h:212
DtFeatureWrapper(const Inner &feature)
Definition: feature.h:408
Mutex mutex
Definition: feature.h:499
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:328
boost::function< void()> DetachCallback
Callback used to detach the user from a feature so the users callback is not called anymore...
Definition: feature.h:178
DeletedCounter(const typename Inner::DeleteCallback &cb)
Definition: feature.h:342
bool init(const SPtr &This)
Definition: feature.h:475
DtFeature()
Definition: feature.h:46
virtual bool isDeleted() const
Check to see if feature has been deleted.
Definition: feature.h:198
~DtFeatureWrapper()
Definition: feature.h:311
static boost::optional< T > ConvertAttribute(const Attribute &attr)
Convert an attribute to a type using iostream.
Definition: feature.h:58
String name
Definition: feature.h:99
bool isDeleted() const
Definition: feature.h:366
Feature::ForEachFunction ForEachFunction
Definition: feature.h:305
Connection myConnection
Definition: feature.h:511
unsigned index
Definition: feature.h:100
static const char * TypeName
Definition: feature.h:41
DtFeatureGeometry geometry() const
Definition: feature.h:236
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:246
boost::function< void(const Key &, const Attribute &)> ForEachFunction
Callback used to iterating through attributes with ForEachAttribute.
Definition: feature.h:149
DtFeatureWrapper(const typename Inner::Ptr &f)
Definition: feature.h:393
binderNoArgs< _Fn > bind(const _Fn &_Func, const _Ty &_Left)
Definition: DtSTLUtilities.h:76
const Inner & wrappedFeature() const
Definition: feature.h:416
boost::function< void()> DeleteCallback
User supplied callback called when feature is deleted.
Definition: feature.h:181
Signal signal
Definition: feature.h:502
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:333
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:256
Feature * clone() const
Definition: feature.h:267
Signal mySignal
Definition: feature.h:510
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
~Data()
Definition: feature.h:469
virtual void forEachAttribute(ForEachFunction f) const
Calls the provided callback on each attribute.
Definition: feature.h:155
boost::optional< T > attributeAs(const Key &k) const
Return attribute as a specific type using build in conversion methods.
Definition: feature.h:168
virtual DetachCallback addDeleteCallback(const DeleteCallback &callback) const
Add a user supplied callback to the feature to be called when the feature is deleted.
Definition: feature.h:191
DT_DEFINE_OBJECT_DEBUGGER_NAME_TEMPLATE2(MAKVRinTerra::DtFeatureWrapper)
boost signal for attaching to delete signal
Definition: feature.h:431
DtFeatureWrapper(const DtFeatureWrapper &from)
Copy constructor.
Definition: feature.h:384
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:323
Caller(const SPtr &data)
Definition: feature.h:489
Functor for calling delete signal.
Definition: feature.h:486
const Inner::DeleteCallback callback
Definition: feature.h:341
virtual DtFeatureGeometry geometry() const
Get the geometry associated with this feature.
Definition: feature.h:149
boost::shared_ptr< Data > myData
all the users of this object will attach their callbacks through this signal it will be called by the...
Definition: feature.h:509
boost::weak_ptr< Data > WPtr
Definition: feature.h:435
Case insensitive string.
Definition: feature.h:69
void operator()() const
Definition: feature.h:343
virtual unsigned numberOfAttributes(const Key::String &) const
Number of attributes with a given key.
Definition: feature.h:158
DT_DLL_terrainCS bool operator!=(const DtDegMinSec &lhs, const DtDegMinSec &rhs)
boost::shared_ptr< const DtFeatureWrapper > CPtr
Definition: feature.h:303
boost::shared_ptr< DtFeatureWrapper > Ptr
Definition: feature.h:302
tbb::spin_mutex Mutex
typename Inner::Ptr&amp; wrappedFeaturePtr() { return myData-&gt;feature; } const typename Inner::Ptr&amp; wrapp...
Definition: feature.h:422
Represents a GIS feature.
Definition: feature.h:37
DetachCallback detacher
Definition: feature.h:501
Definition: feature.h:227
DtFeatureWrapper(Inner *feature)
Create from instance of wrapped type.
Definition: feature.h:401
Feature::Key Key
Definition: feature.h:232
Inner::Ptr feature
Definition: feature.h:500
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:251
Represents a feature geometry.
Definition: featureGeometry.h:35
virtual boost::optional< Attribute > attribute(const Key &) const
Get attribute at a certain key.
Definition: feature.h:164
DtFeatureRefWrapper(const DtFeatureRefWrapper &from)
Copy constructor.
Definition: feature.h:273
boost::variant< std::string, long long, bool, double > Attribute
boost::variant type for accessing attributes.
Definition: feature.h:46
void deletedCallback()
Definition: feature.h:437
WPtr datawptr
Definition: feature.h:488
DtFeature(const DtFeature &)
Definition: feature.h:203

Document ID: Generated on Thu Aug 27 10:56:05 EDT 2020 from SVN revision 217100
Copyright © 2005-2020 MAK Technologies. All Rights Reserved (www.mak.com)