VR-Forces 5.0.1 Developer's Guide
 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 #ifdef DtObjectDebugger_Enable
39  : public DtObjectDebugger<DtFeature>
40 #endif
41  {
42  public:
43  static const char* TypeName;
44 
45  typedef boost::shared_ptr<DtFeature> Ptr;
46  typedef boost::shared_ptr<const DtFeature> CPtr;
47 
48  DtFeature() {};
49 
51  typedef boost::variant<
52  std::string,
53  long long,
54  bool,
55  double
56  > Attribute;
57 
59  template <typename T>
60  static boost::optional<T> ConvertAttribute(const Attribute& attr)
61  {
62  return boost::apply_visitor(AttributeConverter<T>(), attr);
63  }
64 
69  {
72  {
73  public:
74  String();
75  String(const std::string&);
76  String(const char*);
77 
79  const char* c_str() const;
80 
82  const std::string& str() const;
83 
84  bool operator==(const String&) const;
85  bool operator!=(const String&) const;
86  bool operator<(const String&) const;
87 
88  private:
89  std::string myString;
90  };
91 
92  Key(const std::string& name, unsigned index = 0);
93  Key(const String& name, unsigned index = 0);
94  Key(const char* name, unsigned index = 0);
95  Key(const Key& key, unsigned index = 0);
96 
97  bool operator== (const Key&) const;
98  bool operator!= (const Key&) const;
99  bool operator< (const Key&) const;
100 
102  unsigned index;
103  };
104 
107  static bool Equal(const Attribute&, const Attribute&);
108  static bool NotEqual(const Attribute&, const Attribute&);
109  static bool Less(const Attribute&, const Attribute&);
110  static bool LessOrEqual(const Attribute&, const Attribute&);
111  static bool Greater(const Attribute&, const Attribute&);
112  static bool GreaterOrEqual(const Attribute&, const Attribute&);
113  static bool Regex(const Attribute& text, const Attribute& pattern);
115 
117  static std::string TypeOfAttribute(const Attribute&);
118 
120  static std::auto_ptr<DtFeature> CreateEmptyFeature();
121 
123  static std::auto_ptr<DtFeature> CreateGeometryFeature(const DtFeatureGeometry&);
124 
127  static std::auto_ptr<DtFeature> CreateGeometryFeature(
128  const DtFeatureGeometry&,
129  unsigned char red, unsigned char green, unsigned char blue);
130 
133  static std::auto_ptr<DtFeature> CreateCopy(const DtFeature& feature);
134 
136  virtual ~DtFeature();
137 
144  virtual DtFeature* clone() const;
145 
151  virtual DtFeatureGeometry geometry() const { return DtFeatureGeometry(); };
152 
154  typedef boost::function<void (const Key&, const Attribute&)> ForEachFunction;
155 
157  virtual void forEachAttribute(ForEachFunction f) const {};
158 
160  virtual unsigned numberOfAttributes(const Key::String &) const { return 0; };
161 
163  virtual bool hasAttribute(const Key & k) const;
164 
166  virtual boost::optional<Attribute> attribute(const Key &) const {return boost::none;};
167 
169  template <typename T>
170  boost::optional<T> attributeAs(const Key& k) const
171  {
172  if (boost::optional<Attribute> attr = attribute(k))
173  return boost::apply_visitor(AttributeConverter<T>(), *attr);
174 
175  return boost::none;
176  }
177 
180  typedef boost::function<void ()> DetachCallback;
181 
183  typedef boost::function<void ()> DeleteCallback;
184 
194  const DeleteCallback& callback) const { return callback; };
195 
200  virtual bool isDeleted() const { return false; };
201 
202  public:
203  //Defining copy ctor here to satisfy boost::bind & compiler. However, we pass all DtFeature objects by reference so this function should
204  //never be hit. (used in attributeConfigParser.cxx::stringParser ctor)
205  DtFeature(const DtFeature&) { throw std::runtime_error("DtFeature copy ctor, should not hit! At " __FILE__ ":" + __LINE__); };
206 
207  private:
210  template <typename T>
211  struct AttributeConverter : public boost::static_visitor< boost::optional<T> >
212  {
213  template <typename From>
214  boost::optional<T> operator()(const From& from) const
215  {
216  try
217  {
218  return boost::lexical_cast<T>(from);
219  }
220  catch (boost::bad_lexical_cast&)
221  {
222  return boost::optional<T>();
223  }
224  }
225  };
226  };
227 
228  template <typename Feature, typename Inner = Feature>
229  class DtFeatureRefWrapper : public Feature
230  {
231  public:
232  typedef typename Feature::ForEachFunction ForEachFunction;
233  typedef typename Feature::Attribute Attribute;
234  typedef typename Feature::Key Key;
235 
236  typedef typename Inner::DetachCallback DetachCallback;
237 
239  {
240  return myFeature.geometry();
241  }
242 
244  {
245  myFeature.forEachAttribute(func);
246  }
247 
248  unsigned numberOfAttributes(const typename Key::String& str) const
249  {
250  return myFeature.numberOfAttributes(str);
251  }
252 
253  boost::optional<Attribute> attribute(const Key& key) const
254  {
255  return myFeature.attribute(key);
256  }
257 
259  const typename Inner::DeleteCallback& callback) const
260  {
261  return myFeature.addDeleteCallback(callback);
262  }
263 
264  bool isDeleted() const
265  {
266  return myFeature.isDeleted();
267  }
268 
269  Feature* clone() const
270  {
271  return myFeature.clone();
272  }
273 
276  : myFeature(from.myFeature)
277  {
278  }
279 
280  explicit DtFeatureRefWrapper(const Inner& feature)
281  : myFeature(feature)
282  {
283  }
284 
285  //protected:
286  //Inner& wrappedFeature() { return myFeature; }
287  //const Inner& wrappedFeature() const { return myFeature; }
288 
289  protected:
290  const Inner& myFeature;
291  };
292 
300  template <typename Feature, typename Inner = Feature>
301  class DtFeatureWrapper : public Feature
302  {
303  public:
304  typedef boost::shared_ptr<DtFeatureWrapper> Ptr;
305  typedef boost::shared_ptr<const DtFeatureWrapper> CPtr;
306 
307  typedef typename Feature::ForEachFunction ForEachFunction;
308  typedef typename Feature::Attribute Attribute;
309  typedef typename Feature::Key Key;
310 
311  typedef typename Inner::DetachCallback DetachCallback;
312 
314  {
317  myConnection.disconnect();
318  }
319 
321  {
322  return myData->feature->geometry();
323  }
324 
326  {
327  myData->feature->forEachAttribute(func);
328  }
329 
330  unsigned numberOfAttributes(const typename Key::String& str) const
331  {
332  return myData->feature->numberOfAttributes(str);
333  }
334 
335  boost::optional<Attribute> attribute(const Key& key) const
336  {
337  return myData->feature->attribute(key);
338  }
339 
341 #ifdef DtObjectDebugger_Enable
342  : public DtObjectDebugger<DeletedCounter>
343 #endif
344  {
345  const typename Inner::DeleteCallback callback;
346  explicit DeletedCounter(const typename Inner::DeleteCallback& cb) : callback(cb) { }
347  void operator()() const { callback(); }
348  };
349 
351  const typename Inner::DeleteCallback& callback) const
352  {
353  if (!callback)
354  return DetachCallback();
355 
356  Mutex::scoped_lock lock(myData->mutex);
357  if (myData->deleted)
358  {
359  lock.release();
360  callback();
361  return DetachCallback();
362  }
363 
364  Connection conn = mySignal.connect(
365  DeletedCounter(callback), boost::signals2::at_front);
366 
367  return boost::bind(&Connection::disconnect, conn);
368  }
369 
370  bool isDeleted() const
371  {
372  Mutex::scoped_lock lock(myData->mutex);
373  return myData->deleted;
374  }
375 
377  {
378  return new DtFeatureWrapper(*this);
379  }
380 
381  void setDeleted()
382  {
383  typename Data::SPtr d(myData);
384  d->deletedCallback();
385  }
386 
388  explicit DtFeatureWrapper(const DtFeatureWrapper& from)
389  : myData(from.myData)
390  , myConnection()
391  {
392  Mutex::scoped_lock lock(myData->mutex);
393  if (!myData->deleted)
394  myConnection = myData->signal.connect(std::ref(mySignal), boost::signals2::at_front);
395  }
396 
397  explicit DtFeatureWrapper(const typename Inner::Ptr& f)
398  : myData(new Data(f))
399  , myConnection(myData->signal.connect(std::ref(mySignal)))
400  {
401  myData->init(myData);
402  }
403 
405  explicit DtFeatureWrapper(Inner* feature)
406  : myData(new Data(typename Inner::Ptr(feature)))
407  , myConnection(myData->signal.connect(std::ref(mySignal)))
408  {
409  myData->init(myData);
410  }
411 
412  explicit DtFeatureWrapper(const Inner& feature)
413  : myData(new Data(typename Inner::Ptr(feature.clone())))
414  , myConnection(myData->signal.connect(std::ref(mySignal)))
415  {
416  myData->init(myData);
417  }
418 
419  Inner& wrappedFeature() { return *myData->feature; }
420  const Inner& wrappedFeature() const { return *myData->feature; }
421 
424 
425  private:
426  typedef tbb::spin_mutex Mutex;
427 
428  typedef boost::signals2::signal_type<
429  void (),
430  boost::signals2::keywords::mutex_type<tbb::spin_mutex> >::type Signal;
431 
432  typedef boost::signals2::connection Connection;
433 
435  struct Data : boost::noncopyable
436  {
437  public:
438  typedef boost::shared_ptr<Data> SPtr;
439  typedef boost::weak_ptr<Data> WPtr;
440 
442  {
443  Mutex::scoped_lock lock(mutex);
444  if (!deleted)
445  {
446  deleted = true;
447  DetachCallback localDetacher;
448  swap(localDetacher, detacher);
449 
450  lock.release();
451 
452  try
453  {
454  if (localDetacher)
455  localDetacher();
456 
457  signal();
458  signal.disconnect_all_slots();
459  }
460  catch (...)
461  {
462  DtWarn << "Exception thrown in delete callback" << std::endl;
463  }
464  }
465  }
466 
467  explicit Data(const typename Inner::Ptr& f)
468  : feature(f)
470  {
471  }
472 
474  {
475  if (detacher)
476  detacher();
477  }
478 
479  bool init(const SPtr& This)
480  {
481  assert(!detacher);
482 
483  if (!deleted)
484  detacher = feature->addDeleteCallback(Caller(This));
485 
486  return detacher;
487  }
488 
490  struct Caller
491  {
493  explicit Caller(const SPtr& data) : datawptr(data) { }
494 
495  void operator()() const
496  {
497  SPtr data(datawptr.lock());
498  if (data)
499  data->deletedCallback();
500  }
501  };
502 
503  mutable Mutex mutex;
504  typename Inner::Ptr feature;
507  bool deleted;
508  };
509 
513  boost::shared_ptr<Data> myData;
514  mutable Signal mySignal;
516  };
517 
518  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Attribute&);
519  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature&);
520  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key&);
521  DT_DLL_features std::ostream& operator<<(std::ostream&, const DtFeature::Key::String&);
522 
530 }
531 
Feature::Attribute Attribute
Definition: feature.h:308
#define DT_DLL_features
stop complaining about multiple independent base classes for boost::noncopyable this should probably ...
Definition: featuresDefines.h:41
void operator()() const
Definition: feature.h:495
boost variant visitor for converting attributes with lexical_cast lexical_cast will not do anything f...
Definition: feature.h:211
Data(const typename Inner::Ptr &f)
Definition: feature.h:467
DtFeatureGeometry geometry() const
Definition: feature.h:320
Key used to lookup attributes. The DtFeature interface is a dictionary that maps Key objects to attri...
Definition: feature.h:68
boost::shared_ptr< DtFeature > Ptr
Definition: feature.h:45
Inner::DetachCallback DetachCallback
Definition: feature.h:311
bool deleted
Definition: feature.h:507
Inner::DetachCallback DetachCallback
Definition: feature.h:236
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:243
boost::signals2::signal_type< void(), boost::signals2::keywords::mutex_type< tbb::spin_mutex > >::type Signal
Definition: feature.h:430
Wraps a feature object and makes sure all the callbacks are unhooked correctly In order to wrap a fea...
Definition: feature.h:301
bool isDeleted() const
Definition: feature.h:264
std::string myString
Definition: feature.h:89
DtFeatureWrapper * clone() const
Definition: feature.h:376
Feature::Attribute Attribute
Definition: feature.h:233
boost::shared_ptr< const DtFeature > CPtr
Definition: feature.h:46
const Inner & myFeature
Definition: feature.h:290
boost::shared_ptr< Data > SPtr
Definition: feature.h:438
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:309
DT_DLL_features std::ostream & operator<<(std::ostream &, const DtFeatureTransform &)
std::ostream output.
DtFeatureRefWrapper(const Inner &feature)
Definition: feature.h:280
void setDeleted()
Definition: feature.h:381
Feature::ForEachFunction ForEachFunction
Definition: feature.h:232
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:350
Inner & wrappedFeature()
Definition: feature.h:419
boost::optional< T > operator()(const From &from) const
Definition: feature.h:214
DtFeatureWrapper(const Inner &feature)
Definition: feature.h:412
Mutex mutex
Definition: feature.h:503
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:330
boost::function< void()> DetachCallback
Callback used to detach the user from a feature so the users callback is not called anymore...
Definition: feature.h:180
DeletedCounter(const typename Inner::DeleteCallback &cb)
Definition: feature.h:346
bool init(const SPtr &This)
Definition: feature.h:479
DtFeature()
Definition: feature.h:48
virtual bool isDeleted() const
Check to see if feature has been deleted. Note: this is not related to C++ delete or destructors...
Definition: feature.h:200
~DtFeatureWrapper()
Definition: feature.h:313
static boost::optional< T > ConvertAttribute(const Attribute &attr)
Convert an attribute to a type using iostream.
Definition: feature.h:60
String name
Definition: feature.h:101
bool isDeleted() const
Definition: feature.h:370
Feature::ForEachFunction ForEachFunction
Definition: feature.h:307
Connection myConnection
Definition: feature.h:515
unsigned index
Definition: feature.h:102
static const char * TypeName
Definition: feature.h:43
DtFeatureGeometry geometry() const
Definition: feature.h:238
unsigned numberOfAttributes(const typename Key::String &str) const
Definition: feature.h:248
boost::function< void(const Key &, const Attribute &)> ForEachFunction
Callback used to iterating through attributes with ForEachAttribute.
Definition: feature.h:151
DtFeatureWrapper(const typename Inner::Ptr &f)
Definition: feature.h:397
binderNoArgs< _Fn > bind(const _Fn &_Func, const _Ty &_Left)
Definition: DtSTLUtilities.h:76
const Inner & wrappedFeature() const
Definition: feature.h:420
boost::function< void()> DeleteCallback
User supplied callback called when feature is deleted.
Definition: feature.h:183
Signal signal
Definition: feature.h:506
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:335
DetachCallback addDeleteCallback(const typename Inner::DeleteCallback &callback) const
Definition: feature.h:258
Feature * clone() const
Definition: feature.h:269
Signal mySignal
Definition: feature.h:514
typedef long(ZCALLBACK *tell_file_func) OF((voidpf opaque
~Data()
Definition: feature.h:473
virtual void forEachAttribute(ForEachFunction f) const
Calls the provided callback on each attribute.
Definition: feature.h:157
boost::optional< T > attributeAs(const Key &k) const
Return attribute as a specific type using build in conversion methods.
Definition: feature.h:170
virtual DetachCallback addDeleteCallback(const DeleteCallback &callback) const
Add a user supplied callback to the feature to be called when the feature is deleted. If the feature is already deleted the callback may or may not be called by the implementation of this function. The callback is guaranteed to only be called once.
Definition: feature.h:193
DT_DEFINE_OBJECT_DEBUGGER_NAME_TEMPLATE2(MAKVRinTerra::DtFeatureWrapper)
boost signal for attaching to delete signal
Definition: feature.h:435
DtFeatureWrapper(const DtFeatureWrapper &from)
Copy constructor.
Definition: feature.h:388
void forEachAttribute(ForEachFunction func) const
Definition: feature.h:325
Caller(const SPtr &data)
Definition: feature.h:493
Functor for calling delete signal.
Definition: feature.h:490
const Inner::DeleteCallback callback
Definition: feature.h:345
virtual DtFeatureGeometry geometry() const
Get the geometry associated with this feature. GIS features each typically each associated with one g...
Definition: feature.h:151
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:513
boost::weak_ptr< Data > WPtr
Definition: feature.h:439
Case insensitive string.
Definition: feature.h:71
void operator()() const
Definition: feature.h:347
virtual unsigned numberOfAttributes(const Key::String &) const
Number of attributes with a given key.
Definition: feature.h:160
DT_DLL_terrainCS bool operator!=(const DtDegMinSec &lhs, const DtDegMinSec &rhs)
boost::shared_ptr< const DtFeatureWrapper > CPtr
Definition: feature.h:305
boost::shared_ptr< DtFeatureWrapper > Ptr
Definition: feature.h:304
tbb::spin_mutex Mutex
typename Inner::Ptr&amp; wrappedFeaturePtr() { return myData-&gt;feature; } const typename Inner::Ptr&amp; wrapp...
Definition: feature.h:426
Represents a GIS feature. Features consist of a DtFeatureGeometry (2.5D geometric vector data) and a ...
Definition: feature.h:37
DetachCallback detacher
Definition: feature.h:505
Definition: feature.h:229
DtFeatureWrapper(Inner *feature)
Create from instance of wrapped type.
Definition: feature.h:405
Feature::Key Key
Definition: feature.h:234
Inner::Ptr feature
Definition: feature.h:504
boost::optional< Attribute > attribute(const Key &key) const
Definition: feature.h:253
Represents a feature geometry.
Definition: featureGeometry.h:39
virtual boost::optional< Attribute > attribute(const Key &) const
Get attribute at a certain key.
Definition: feature.h:166
DtFeatureRefWrapper(const DtFeatureRefWrapper &from)
Copy constructor.
Definition: feature.h:275
boost::variant< std::string, long long, bool, double > Attribute
boost::variant type for accessing attributes.
Definition: feature.h:48
void deletedCallback()
Definition: feature.h:441
WPtr datawptr
Definition: feature.h:492
DtFeature(const DtFeature &)
Definition: feature.h:205

Document ID: Generated on Mon Jun 20 00:38:30 EDT 2022 from SVN revision 244029
Copyright © 2005-2021 MAK Technologies. All Rights Reserved (www.mak.com)