factor advice holding buffer into separate Class

This commit is contained in:
Fischlurch 2010-05-29 01:25:14 +02:00
parent d5ebe14d73
commit 74e12dd17a
3 changed files with 78 additions and 24 deletions

View file

@ -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<AD>())
, 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<AD>());
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 AD>
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<AD>;
};
/** 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<class AD>
PointOfAdvice*
Provision<AD>::storeCopy (AD const& advice_given)
{
typedef ActiveProvision<AD> Holder;
return new(getBuffer(sizeof(Holder))) Holder (*this, advice_given);
}
@ -241,7 +282,7 @@ namespace advice {
class Request
: public PointOfAdvice
{
typedef const Provision<AD> AdviceProvision;
typedef const ActiveProvision<AD> AdviceProvision;
/* == policy definitions == */ ////TODO: extract into policy classes
@ -254,12 +295,12 @@ namespace advice {
Request (Literal bindingSpec =0)
: PointOfAdvice (Binding(bindingSpec).addTypeGuard<AD>())
{
registrateRequest();
registerRequest();
}
~Request()
{
deregistrateRequest();
deregisterRequest();
}

View file

@ -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");
}

View file

@ -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]);
}