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:
|
protected:
|
||||||
void publishProvision (PointOfAdvice*);
|
void publishProvision (PointOfAdvice*);
|
||||||
void discardSolutions ();
|
void discardSolutions ();
|
||||||
void publishBindingChange();
|
|
||||||
void publishRequestBindingChange();
|
void publishRequestBindingChange();
|
||||||
|
|
||||||
void registerRequest();
|
void registerRequest();
|
||||||
|
|
@ -240,11 +239,12 @@ namespace advice {
|
||||||
defineBinding (Literal topic)
|
defineBinding (Literal topic)
|
||||||
{
|
{
|
||||||
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
||||||
publishBindingChange();
|
maybe_rePublish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PointOfAdvice* storeCopy (AD const& advice_given);
|
PointOfAdvice* storeCopy (AD const& advice_given);
|
||||||
|
void maybe_rePublish ();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -289,7 +289,7 @@ namespace advice {
|
||||||
@throw error::External on allocation problems, plus anything
|
@throw error::External on allocation problems, plus anything
|
||||||
the advice data may throw during copy construction. */
|
the advice data may throw during copy construction. */
|
||||||
template<class AD>
|
template<class AD>
|
||||||
PointOfAdvice*
|
inline PointOfAdvice*
|
||||||
Provision<AD>::storeCopy (AD const& advice_given)
|
Provision<AD>::storeCopy (AD const& advice_given)
|
||||||
{
|
{
|
||||||
typedef ActiveProvision<AD> Holder;
|
typedef ActiveProvision<AD> Holder;
|
||||||
|
|
@ -297,6 +297,23 @@ namespace advice {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @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)
|
defineBinding (Literal topic)
|
||||||
{
|
{
|
||||||
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
setBindingPattern (Binding(topic).addTypeGuard<AD>());
|
||||||
|
////////////////////////////////////////////////////////////////////////////TODO: conceptual mismatch here! we don't have an "old entry", because we ourselves are the entry ;-)
|
||||||
publishRequestBindingChange();
|
publishRequestBindingChange();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,50 @@
|
||||||
|
|
||||||
#include "lib/advice.hpp"
|
#include "lib/advice.hpp"
|
||||||
#include "lib/advice/index.hpp"
|
#include "lib/advice/index.hpp"
|
||||||
|
#include "lib/singleton.hpp"
|
||||||
|
#include "include/logging.h"
|
||||||
|
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
|
using lib::Singleton;
|
||||||
|
|
||||||
namespace lib {
|
namespace lib {
|
||||||
namespace advice {
|
namespace advice {
|
||||||
|
|
||||||
// LUMIERA_ERROR_DEFINE (MISSING_INSTANCE, "Existing ID registration without associated instance");
|
// 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.
|
/** allocate raw storage for a buffer holding the actual piece of advice.
|
||||||
We need to manage this internally, as the original advice::Provision
|
We need to manage this internally, as the original advice::Provision
|
||||||
|
|
@ -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
|
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
|
void
|
||||||
AdviceLink::discardSolutions ()
|
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
|
void
|
||||||
AdviceLink::publishRequestBindingChange()
|
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");
|
UNIMPLEMENTED ("propagate binding change to index");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -76,14 +132,14 @@ namespace advice {
|
||||||
void
|
void
|
||||||
AdviceLink::registerRequest()
|
AdviceLink::registerRequest()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED ("registrate request with the index");
|
aSys().addRequest (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AdviceLink::deregisterRequest()
|
AdviceLink::deregisterRequest()
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED ("detach request from index");
|
aSys().removeRequest (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -350,7 +350,9 @@ namespace advice {
|
||||||
requestEntries_[nKey].append (newEntry);
|
requestEntries_[nKey].append (newEntry);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
requestEntries_[nKey].overwrite (oldRef, newEntry);
|
requestEntries_[nKey].overwrite (oldRef, newEntry);
|
||||||
|
}
|
||||||
provisionEntries_[nKey].publish_latest_solution (newEntry);
|
provisionEntries_[nKey].publish_latest_solution (newEntry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue