From 74e12dd17ac68b65dac49430499b9fa1bd64b845 Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sat, 29 May 2010 01:25:14 +0200 Subject: [PATCH] factor advice holding buffer into separate Class --- src/lib/advice.hpp | 75 ++++++++++++++++++++++++++++++--------- src/lib/advice/advice.cpp | 21 ++++++++--- src/lib/advice/index.hpp | 6 ++-- 3 files changed, 78 insertions(+), 24 deletions(-) diff --git a/src/lib/advice.hpp b/src/lib/advice.hpp index 33cc3392e..7a33ceffa 100644 --- a/src/lib/advice.hpp +++ b/src/lib/advice.hpp @@ -116,13 +116,15 @@ namespace advice { pattern_ = binding.buildMatcher(); } - void publishProvision(); + void publishProvision (PointOfAdvice*); void discardSolutions (); void publishBindingChange(); void publishRequestBindingChange(); - void registrateRequest(); - void deregistrateRequest(); + void registerRequest(); + void deregisterRequest(); + + void* getBuffer(size_t); public: explicit @@ -181,7 +183,6 @@ namespace advice { class Provision : public PointOfAdvice { - AD theAdvice_; /* == policy definitions == */ ////TODO: extract into policy classes @@ -194,7 +195,6 @@ namespace advice { explicit Provision (Literal bindingSpec =0) : PointOfAdvice (Binding(bindingSpec).addTypeGuard()) - , theAdvice_() { } ~Provision() @@ -203,21 +203,13 @@ namespace advice { } - AD const& - getAdvice() const - { - return theAdvice_; - } - void setAdvice (AD const& pieceOfAdvice) { - theAdvice_ = pieceOfAdvice; - publishProvision (); ///////////////////////////TODO how to propagate without specific typing? + publishProvision (storeCopy (pieceOfAdvice)); } void retractAdvice() { - theAdvice_ = this->handleMissingSolution(); discardSolutions (); } @@ -227,8 +219,57 @@ namespace advice { setBindingPattern (Binding(topic).addTypeGuard()); publishBindingChange(); } + + private: + PointOfAdvice* storeCopy (AD const& advice_given); }; + + /** + * Piece of Advice as incorporated into the AdviceSystem. + * This holder-object contains a copy of the advice data + * and is placed into the internal storage buffer; the + * advice index keeps a (type erased) pointer to serve + * any requests which happen to match the binding. + */ + template + class ActiveProvision + : public PointOfAdvice + { + AD theAdvice_; + + public: + AD const& + getAdvice() const + { + return theAdvice_; + } + + protected: + ActiveProvision (PointOfAdvice const& refPoint, AD const& advice_given) + : PointOfAdvice(refPoint) + , theAdvice_(advice_given) + { + setSolution (this, this); + } + + friend class Provision; + }; + + + /** function to copy advice into an internal buffer, + @return type erased pointer to the data holder created + @throw error::External on allocation problems, plus anything + the advice data may throw during copy construction. */ + template + PointOfAdvice* + Provision::storeCopy (AD const& advice_given) + { + typedef ActiveProvision Holder; + return new(getBuffer(sizeof(Holder))) Holder (*this, advice_given); + } + + @@ -241,7 +282,7 @@ namespace advice { class Request : public PointOfAdvice { - typedef const Provision AdviceProvision; + typedef const ActiveProvision AdviceProvision; /* == policy definitions == */ ////TODO: extract into policy classes @@ -254,12 +295,12 @@ namespace advice { Request (Literal bindingSpec =0) : PointOfAdvice (Binding(bindingSpec).addTypeGuard()) { - registrateRequest(); + registerRequest(); } ~Request() { - deregistrateRequest(); + deregisterRequest(); } diff --git a/src/lib/advice/advice.cpp b/src/lib/advice/advice.cpp index 1ed7889fb..e7f729055 100644 --- a/src/lib/advice/advice.cpp +++ b/src/lib/advice/advice.cpp @@ -31,9 +31,22 @@ namespace advice { // LUMIERA_ERROR_DEFINE (MISSING_INSTANCE, "Existing ID registration without associated instance"); - /* ohlolololohaha */ + /** allocate raw storage for a buffer holding the actual piece of advice. + We need to manage this internally, as the original advice::Provision + may go out of scope, while the advice information as such remains valid. + @note the special twist is the size of the buffer depending on the actual + advice type, which we need to erase for tracking all advice provisions + and advice requests through an generic index datastructure. + @todo rewrite to use Lumiera's block allocator / memory pool */ + void* + PointOfAdvice::getBuffer(size_t) + { + UNIMPLEMENTED ("raw allocation and de-allocation of advice holding buffer"); + } + + void - PointOfAdvice::publishProvision() + PointOfAdvice::publishProvision (PointOfAdvice*) { UNIMPLEMENTED ("change advice provision registration"); } @@ -61,14 +74,14 @@ namespace advice { void - PointOfAdvice::registrateRequest() + PointOfAdvice::registerRequest() { UNIMPLEMENTED ("registrate request with the index"); } void - PointOfAdvice::deregistrateRequest() + PointOfAdvice::deregisterRequest() { UNIMPLEMENTED ("detach request from index"); } diff --git a/src/lib/advice/index.hpp b/src/lib/advice/index.hpp index 31e2bf0ca..e15c308d0 100644 --- a/src/lib/advice/index.hpp +++ b/src/lib/advice/index.hpp @@ -392,9 +392,9 @@ namespace advice { void removeProvision (POA const& refEntry) { - HashVal oKey (hash_value(refEntry)); - provisionEntries_[oKey].remove (refEntry); - requestEntries_[oKey].retract_all_solutions (refEntry, provisionEntries_[oKey]); + HashVal key (hash_value(refEntry)); + provisionEntries_[key].remove (refEntry); + requestEntries_[key].retract_all_solutions (refEntry, provisionEntries_[key]); }