/* * Cacheable.hpp * * Created on: Feb 2, 2010 * Author: crueger */ #ifndef CACHEABLE_HPP_ #define CACHEABLE_HPP_ #include "Patterns/Observer.hpp" #include #ifndef NO_CACHING template class Cacheable : public Observer { public: Cacheable(Observable *_owner, boost::function _recalcMethod); virtual ~Cacheable(); const bool isValid(); const T& operator*(); const bool operator==(const T&); const bool operator!=(const T&); // methods implemented for base-class Observer void update(Observable *subject); void subjectKilled(Observable *subject); private: void checkValid(); T content; Observable *owner; bool valid; bool canBeUsed; boost::function recalcMethod; }; template Cacheable::Cacheable(Observable *_owner, boost::function _recalcMethod) : owner(_owner), recalcMethod(_recalcMethod), valid(false), canBeUsed(true) { // we sign on with the best(=lowest) priority, so cached values are recalculated before // anybody else might ask for updated values owner->signOn(this,-20); } template const T& Cacheable::operator*(){ checkValid(); return content; } template const bool Cacheable::operator==(const T& rval){ checkValid(); return (content == rval); } template const bool Cacheable::operator!=(const T& rval){ checkValid(); return (content != rval); } template Cacheable::~Cacheable() { owner->signOff(this); } template const bool Cacheable::isValid(){ return valid; } template void Cacheable::update(Observable *subject) { valid = false; } template void Cacheable::subjectKilled(Observable *subject) { valid = false; canBeUsed = false; } template void Cacheable::checkValid(){ assert(canBeUsed && "Cacheable used after owner was deleted"); if(!isValid()){ content = recalcMethod(); } } #else template class Cacheable : public Observer { public: Cacheable(Observable *_owner, boost::function _recalcMethod); virtual ~Cacheable(); const bool isValid(); const T& operator*(); const bool operator==(const T&); const bool operator!=(const T&); // methods implemented for base-class Observer void update(Observable *subject); void subjectKilled(Observable *subject); private: boost::function recalcMethod; }; template Cacheable::Cacheable(Observable *_owner, boost::function _recalcMethod) : recalcMethod(_recalcMethod) {} template const T& Cacheable::operator*(){ return recalcMethod(); } template const bool Cacheable::operator==(const T& rval){ return (recalcMethod() == rval); } template const bool Cacheable::operator!=(const T& rval){ return (recalcMethod() != rval); } template Cacheable::~Cacheable() {} template const bool Cacheable::isValid(){ return true; } template void Cacheable::update(Observable *subject) { assert(0 && "Cacheable::update should never be called when caching is disabled"); } template void Cacheable::subjectKilled(Observable *subject) { assert(0 && "Cacheable::subjectKilled should never be called when caching is disabled"); } #endif #endif /* CACHEABLE_HPP_ */