/* * ObservedValuesContainer_impl.hpp * * Created on: Oct 29, 2015 * Author: heber */ #ifndef OBSERVEDVALUESCONTAINER_IMPL_HPP_ #define OBSERVEDVALUESCONTAINER_IMPL_HPP_ // include config.h #ifdef HAVE_CONFIG_H #include #endif #include "ObservedValuesContainer.hpp" #include "CodePatterns/Assert.hpp" #include template ObservedValuesContainer::ObservedValuesContainer( const std::string _name, QtObservedInstanceBoard &_board, const onDestroy_t _onDestroy) : NameOfType(_name), board(_board), onDestroy(_onDestroy) {} template ObservedValuesContainer::~ObservedValuesContainer() { boost::recursive_mutex::scoped_lock lock(atomic_mutex); for (typename CountedObservedValues_t::iterator iter = ObservedValues.begin(); iter != ObservedValues.end(); ++iter) iter->second->noteBoardIsGone(); } template #ifdef HAVE_INLINE inline #endif void ObservedValuesContainer::checkRemoval(const id _id) { if (checkMarkedForConnected(_id) && checkMarkedForErase(_id)) removeObservedValues(_id); } template typename T::ptr ObservedValuesContainer::get(const id _id) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); LOG(3, "DEBUG: ObservedValuesContainer got get() for an observed value of " << NameOfType << " " << _id); typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id); if (iter == ObservedValues.end()) return typename T::ptr(); else return iter->second; } template void ObservedValuesContainer::markObservedValuesAsConnected( const id _id) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsConnected() for an observed value of " << NameOfType << " " << _id); ASSERT (MarkedForConnected.find(_id) == MarkedForConnected.end(), "ObservedValuesContainer::markObservedValuesAsConnected() - Observed value of " +NameOfType+" "+toString(_id)+" is already marked as connected."); MarkedForConnected.insert( _id ); } template bool ObservedValuesContainer::checkMarkedForConnected( const id _id) const { boost::recursive_mutex::scoped_lock lock(atomic_mutex); typename MarkedSet_t::const_iterator const iter = MarkedForConnected.find(_id); return iter == MarkedForConnected.end(); } template void ObservedValuesContainer::markObservedValuesAsDisconnected( const id _id) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); LOG(3, "DEBUG: ObservedValuesContainer got markObservedValuesAsDisconnected() for an observed value of " << NameOfType << " " << _id); typename MarkedSet_t::iterator const iter = MarkedForConnected.find(_id); ASSERT (iter != MarkedForConnected.end(), "ObservedValuesContainer::markObservedValuesAsDisconnected() - Observed value of " +NameOfType+" "+toString(_id)+" is not marked as connected."); MarkedForConnected.erase(iter); checkRemoval(_id); } template void ObservedValuesContainer::removeObservedValues(const id _id) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); LOG(3, "DEBUG: ObservedValuesContainer removes " << NameOfType << " " << _id); MarkedForConnected.erase(_id); MarkedForErase.erase(_id); ObservedValues.erase(_id); // call callback function onDestroy(_id); } template void ObservedValuesContainer::eraseObservedValues(const id _id) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); #ifndef NDEBUG std::pair< typename std::set::iterator, bool > inserter = #endif MarkedForErase.insert(_id); ASSERT( inserter.second, "ObservedValuesContainer::eraseObservedValues() - received twice for " +NameOfType+" "+toString(_id)+"."); checkRemoval(_id); } template #ifdef HAVE_INLINE inline #endif bool ObservedValuesContainer::checkMarkedForErase(const id _id) const { boost::recursive_mutex::scoped_lock lock(atomic_mutex); typename MarkedSet_t::const_iterator const iter = MarkedForErase.find(_id); return iter != MarkedForErase.end(); } template void ObservedValuesContainer::insert(const id _id, const typename T::ptr &_obsvalues) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); typename CountedObservedValues_t::iterator iter = ObservedValues.find(_id); ASSERT (iter == ObservedValues.end(), "ObservedValuesContainer::insert() of "+NameOfType +" for "+toString(_id)+" failed because "+toString(_id)+" already present."); std::pair inserter = ObservedValues.insert( std::make_pair( _id, _obsvalues ) ); ASSERT( inserter.second, "ObservedValuesContainer::insert() of "+NameOfType +" for "+toString(_id)+", insertion failed though empty?"); _obsvalues->activateObserver(); } template bool ObservedValuesContainer::changeIdentifier(const id _oldid, const id _newid) { boost::recursive_mutex::scoped_lock lock(atomic_mutex); const typename CountedObservedValues_t::iterator Colditer = ObservedValues.find(_oldid); const typename CountedObservedValues_t::iterator Cnewiter = ObservedValues.find(_newid); const typename MarkedSet_t::iterator MEolditer = MarkedForErase.find(_oldid); const typename MarkedSet_t::iterator MEnewiter = MarkedForErase.find(_newid); const typename MarkedSet_t::iterator MColditer = MarkedForConnected.find(_oldid); const typename MarkedSet_t::iterator MCnewiter = MarkedForConnected.find(_newid); bool status = ((Colditer != ObservedValues.end()) && (Cnewiter == ObservedValues.end())); status &= ((MEolditer != MarkedForErase.end()) && (MEnewiter == MarkedForErase.end())); status &= ((MColditer != MarkedForConnected.end()) && (MCnewiter == MarkedForConnected.end())); // change id here only if still present if (status) { { // TODO: Actually, we need to think whether we do not have to to split the // deque in two parts: the last entry having the newid, while all other // ones retain the old one until they get removed. But we need to check // whether changing ids "there" is possible when the QtObserved... is under // removal. typename T::ptr obsvalues = Colditer->second; ObservedValues.erase(Colditer); ObservedValues.insert( std::make_pair(_newid, obsvalues) ); } { MarkedForErase.erase(MEolditer); MarkedForErase.insert(_newid); } { MarkedForConnected.erase(MColditer); MarkedForConnected.insert(_newid); } return true; } else return false; } template #ifdef HAVE_INLINE inline #endif bool ObservedValuesContainer::isPresent(const id _id) const { boost::recursive_mutex::scoped_lock lock(atomic_mutex); typename CountedObservedValues_t::const_iterator iter = ObservedValues.find(_id); return (iter != ObservedValues.end()); } #endif /* OBSERVEDVALUESCONTAINER_IMPL_HPP_ */