code up the obvious part of the AdviceSystem implementation
This commit is contained in:
parent
d0e7f9b77d
commit
666d57f6ef
3 changed files with 96 additions and 20 deletions
|
|
@ -171,7 +171,6 @@ namespace advice {
|
|||
protected:
|
||||
void publishProvision (PointOfAdvice*);
|
||||
void discardSolutions ();
|
||||
void publishBindingChange();
|
||||
void publishRequestBindingChange();
|
||||
|
||||
void registerRequest();
|
||||
|
|
@ -240,11 +239,12 @@ namespace advice {
|
|||
defineBinding (Literal topic)
|
||||
{
|
||||
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
||||
publishBindingChange();
|
||||
maybe_rePublish();
|
||||
}
|
||||
|
||||
private:
|
||||
PointOfAdvice* storeCopy (AD const& advice_given);
|
||||
void maybe_rePublish ();
|
||||
};
|
||||
|
||||
|
||||
|
|
@ -289,12 +289,29 @@ namespace advice {
|
|||
@throw error::External on allocation problems, plus anything
|
||||
the advice data may throw during copy construction. */
|
||||
template<class AD>
|
||||
PointOfAdvice*
|
||||
inline PointOfAdvice*
|
||||
Provision<AD>::storeCopy (AD const& advice_given)
|
||||
{
|
||||
typedef ActiveProvision<AD> Holder;
|
||||
return new(getBuffer(sizeof(Holder))) Holder (*this, advice_given);
|
||||
}
|
||||
{
|
||||
typedef ActiveProvision<AD> Holder;
|
||||
return new(getBuffer(sizeof(Holder))) Holder (*this, advice_given);
|
||||
}
|
||||
|
||||
|
||||
/** @internal in case we've already published this provision,
|
||||
* we temporarily need a new provision entry, to allow the
|
||||
* AdviceSystem implementation to rewrite the internal index
|
||||
*/
|
||||
template<class AD>
|
||||
inline void
|
||||
Provision<AD>::maybe_rePublish ()
|
||||
{
|
||||
typedef const ActiveProvision<AD> AdviceProvision;
|
||||
AdviceProvision* solution = static_cast<AdviceProvision*> (getSolution (*this));
|
||||
|
||||
if (solution) // create copy of the data holder, using the new binding
|
||||
publishProvision (storeCopy (solution->getAdvice()));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -346,6 +363,7 @@ namespace advice {
|
|||
defineBinding (Literal topic)
|
||||
{
|
||||
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
||||
////////////////////////////////////////////////////////////////////////////TODO: conceptual mismatch here! we don't have an "old entry", because we ourselves are the entry ;-)
|
||||
publishRequestBindingChange();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -23,14 +23,51 @@
|
|||
|
||||
#include "lib/advice.hpp"
|
||||
#include "lib/advice/index.hpp"
|
||||
#include "lib/singleton.hpp"
|
||||
#include "include/logging.h"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
using lib::Singleton;
|
||||
|
||||
namespace lib {
|
||||
namespace advice {
|
||||
|
||||
// LUMIERA_ERROR_DEFINE (MISSING_INSTANCE, "Existing ID registration without associated instance");
|
||||
|
||||
namespace { // ======= implementation of the AdviceSystem ============
|
||||
|
||||
class AdviceSystem
|
||||
: public Index<PointOfAdvice>
|
||||
, boost::noncopyable
|
||||
{
|
||||
|
||||
public:
|
||||
AdviceSystem()
|
||||
{
|
||||
INFO (library, "Initialising Advice Index tables.");
|
||||
}
|
||||
|
||||
~AdviceSystem()
|
||||
{
|
||||
INFO (library, "Shutting down Advice system.");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** hidden implementation-level access to the AdviceSystem */
|
||||
Singleton<AdviceSystem> aSys;
|
||||
|
||||
|
||||
} //(End) AdviceSystem implementation
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* ====== AdviceLink : access point for Provisions and Requests ====== */
|
||||
|
||||
|
||||
/** 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.
|
||||
|
|
@ -45,30 +82,49 @@ namespace advice {
|
|||
}
|
||||
|
||||
|
||||
/** when the Provision actually sets advice data, this is copied
|
||||
* into an internal buffer within the AdviceSystem. We then use the
|
||||
* Index to remember the presence of this advice data and to detect
|
||||
* possible matches with existing advice::Request entries.
|
||||
* @param adviceData pointer to the copied data,
|
||||
* actually pointing to an ActiveProvision<AD>
|
||||
*/
|
||||
void
|
||||
AdviceLink::publishProvision (PointOfAdvice*)
|
||||
AdviceLink::publishProvision (PointOfAdvice* newProvision)
|
||||
{
|
||||
UNIMPLEMENTED ("change advice provision registration");
|
||||
const PointOfAdvice* previousProvision (getSolution (*this));
|
||||
setSolution (this, newProvision);
|
||||
|
||||
if (!previousProvision && newProvision)
|
||||
aSys().addProvision (*newProvision);
|
||||
else
|
||||
if (previousProvision && newProvision)
|
||||
aSys().modifyProvision (*previousProvision, *newProvision);
|
||||
else
|
||||
if (previousProvision && !newProvision)
|
||||
aSys().removeProvision (*previousProvision); ////////////////////////////TODO: don't we need to release buffer storage here?
|
||||
}
|
||||
|
||||
|
||||
/** when advice is retracted explicitly,
|
||||
* after removing the provision index entry
|
||||
* we also need to re-process any requests
|
||||
* which happen to match our binding...
|
||||
*/
|
||||
void
|
||||
AdviceLink::discardSolutions ()
|
||||
{
|
||||
UNIMPLEMENTED ("notify index of retracted advice");
|
||||
const PointOfAdvice* existingProvision (getSolution (*this));
|
||||
setSolution (this, NULL );
|
||||
if (existingProvision)
|
||||
aSys().removeProvision (*existingProvision); ////////////////////////////TODO: don't we need to release buffer storage here?
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdviceLink::publishBindingChange ()
|
||||
{
|
||||
UNIMPLEMENTED ("propagate binding change to index");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdviceLink::publishRequestBindingChange()
|
||||
{
|
||||
////////////////////////////////////////////////////////////////////////////TODO: conceptual mismatch here! we don't have an "old entry", because we ourselves are the entry ;-)
|
||||
UNIMPLEMENTED ("propagate binding change to index");
|
||||
}
|
||||
|
||||
|
|
@ -76,14 +132,14 @@ namespace advice {
|
|||
void
|
||||
AdviceLink::registerRequest()
|
||||
{
|
||||
UNIMPLEMENTED ("registrate request with the index");
|
||||
aSys().addRequest (*this);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AdviceLink::deregisterRequest()
|
||||
{
|
||||
UNIMPLEMENTED ("detach request from index");
|
||||
aSys().removeRequest (*this);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -350,7 +350,9 @@ namespace advice {
|
|||
requestEntries_[nKey].append (newEntry);
|
||||
}
|
||||
else
|
||||
requestEntries_[nKey].overwrite (oldRef, newEntry);
|
||||
{
|
||||
requestEntries_[nKey].overwrite (oldRef, newEntry);
|
||||
}
|
||||
provisionEntries_[nKey].publish_latest_solution (newEntry);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue