17 #include <boost/scoped_ptr.hpp>
18 #include <boost/shared_ptr.hpp>
19 #include <boost/weak_ptr.hpp>
20 #include <boost/foreach.hpp>
21 #include <boost/signals2.hpp>
23 #include <tbb/spin_mutex.h>
24 #include <tbb/spin_rw_mutex.h>
25 #include <tbb/null_rw_mutex.h>
36 namespace MAKVRinTerra
46 Derived*
This() {
return static_cast<Derived*
>(
this); }
47 const Derived*
This()
const {
return static_cast<const Derived*
>(
this); }
56 typedef typename FeatureSet::Feature
Feature;
61 typedef boost::shared_ptr<Inner>
Ptr;
62 typedef boost::shared_ptr<const Inner>
CPtr;
64 template <
typename Function=ForEachFunction>
71 return handle->label();
73 return "empty feature set wrapper";
81 return handle->numberOfFeatures();
90 return handle->elided();
99 return handle->empty();
108 return handle->isIndexed();
113 bool isCacheable(
const boost::optional<DtFeatureGeometry>& area)
const
117 return handle->isCacheable(area);
122 void cacheEstimate(
double& time,
double&
size,
const boost::optional<DtFeatureGeometry>& area)
const
126 handle->cacheEstimate(time, size, area);
132 const boost::optional<DtFeatureGeometry>& area,
137 handle->cacheData(area, progress);
146 return handle->loaded(timeout);
155 return handle->loaded(timeout);
174 boost::signals2::connection conn =
myLoadedSignal->connect(LoadedCounter(cb));
178 return boost::bind(&boost::signals2::connection::disconnect, conn);
191 handle->forEachFeatureParallel(func);
196 typedef CallbackRecord<ForEachFunction> Record;
197 typedef typename Record::Ptr RecordPtr;
204 detacher = handle->forEachFeatureAsync(func);
210 RecordPtr newHead(Record::Make(func,
myHead, detacher));
211 const_cast<RecordPtr&
>(
myHead) = newHead;
212 return typename Record::Detacher(newHead);
225 const boost::optional<DtFeatureGeometry>& geometry,
230 return this->Wrap(handle->filter(query, geometry, load));
234 DtTHROW_NEW(
DtException,
"filtered empty feature set wrapper");
248 template <
typename Function>
253 typedef boost::shared_ptr<CallbackRecord>
Ptr;
254 typedef boost::weak_ptr<CallbackRecord>
WPtr;
261 boost::shared_ptr<CallbackRecord> callback(
callbackWptr.lock());
266 explicit Detacher(
const boost::shared_ptr<CallbackRecord>& rec)
277 Mutex::scoped_lock lock(newRec->next->mutex);
278 if (newRec->next->func)
281 newRec->next = newRec->next->next;
291 Mutex::scoped_lock lock(
mutex);
323 ne->addCallbacksTo(fs);
341 Mutex::scoped_lock lock(
mutex);
360 lock.acquire(pr->mutex);
365 pr = pr->prev.lock();
370 Mutex::scoped_lock endLock(ne->mutex);
396 const Function&
func,
420 myHead->addCallbacksTo(fs);
437 typedef boost::signals2::signal_type<
439 boost::signals2::keywords::mutex_type<tbb::spin_mutex> >::type
LoadedSignal;
443 boost::weak_ptr<LoadedSignal>
sig;
449 boost::shared_ptr<LoadedSignal>
signal(
sig.lock());
463 template <
typename>
class PtrTemplate,
467 template <
typename FS,
typename Inner>
481 template <
typename OtherFS>
483 : mySet(fs.release())
489 const Inner*
getPtr()
const {
return mySet.get(); }
491 std::string label()
const
493 return mySet->label();
496 unsigned numberOfFeatures()
const
498 return mySet->numberOfFeatures();
503 return mySet->elided();
508 return mySet->empty();
511 bool isIndexed()
const
513 return mySet->isIndexed();
516 bool isCacheable(
const boost::optional<DtFeatureGeometry>& area)
const
518 return mySet->isCacheable(area);
521 void cacheEstimate(
double& time,
double&
size,
const boost::optional<DtFeatureGeometry>& area)
const
523 mySet->cacheEstimate(time, size, area);
527 const boost::optional<DtFeatureGeometry>& area,
530 mySet->cacheData(area, progress);
533 bool loaded(
double timeout=0.0)
const
535 return mySet->loaded(timeout);
540 return mySet->addLoadedCallback(cb);
545 mySet->forEachFeatureParallel(func);
550 return mySet->forEachFeatureAsync(func);
555 const boost::optional<DtFeatureGeometry>& geometry,
558 return this->Wrap(mySet->filter(query, geometry, load));
563 return this->Wrap(mySet->clone());
567 const boost::scoped_ptr<Inner>
mySet;
570 template <
typename FS,
typename Inner>
573 DtFeatureSetWrapper<FS,boost::shared_ptr,Inner>,
585 setPtr(boost::shared_ptr<Inner>(fs));
588 template <
typename OtherFS>
592 setPtr(boost::shared_ptr<Inner>(fs.release()));
595 template <
typename OtherFS>
602 boost::shared_ptr<Inner> getPtr()
604 Mutex::scoped_lock lock(myMutex,
false);
608 boost::shared_ptr<const Inner> getPtr()
const
610 Mutex::scoped_lock lock(myMutex,
false);
614 boost::shared_ptr<Inner> setPtr(
const boost::shared_ptr<Inner>& p)
616 Mutex::scoped_lock lock(myMutex,
false);
620 if (!lock.upgrade_to_writer() && mySet && p)
625 lock.downgrade_to_reader();
626 this->setupCallbacks(p);
631 boost::shared_ptr<Inner> setPtr(Inner*
set)
633 boost::shared_ptr<Inner> fs(
set);
639 return this->Wrap(getPtr());
649 template <
typename FS,
typename Inner>
652 DtFeatureSetWrapper<FS,boost::weak_ptr,Inner>,
664 template <
typename T>
670 template <
typename T>
677 boost::shared_ptr<Inner> getPtr()
679 Mutex::scoped_lock lock(myMutex,
false);
683 boost::shared_ptr<const Inner> getPtr()
const
685 Mutex::scoped_lock lock(myMutex,
false);
689 boost::shared_ptr<Inner> getMutablePtr()
const
694 boost::shared_ptr<Inner> setPtr(
const boost::shared_ptr<Inner>& p)
696 Mutex::scoped_lock lock(myMutex,
false);
699 boost::shared_ptr<Inner> s(mySet.lock());
704 if (!lock.upgrade_to_writer() && p)
706 boost::shared_ptr<Inner> s(mySet.lock());
713 lock.downgrade_to_reader();
714 this->setupCallbacks(p);
721 Mutex::scoped_lock lock(myMutex,
false);
722 return this->Wrap(mySet);