Lumiera  0.pre.03
»edityourfreedom«
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
advice.hpp
Go to the documentation of this file.
1 /*
2  ADVICE.hpp - generic loosely coupled interaction guided by symbolic pattern
3 
4  Copyright (C) Lumiera.org
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7  This program is free software; you can redistribute it and/or
8  modify it under the terms of the GNU General Public License as
9  published by the Free Software Foundation; either version 2 of
10  the License, or (at your option) any later version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 
21 */
22 
23 
93 #ifndef LUMIERA_ADVICE_H
94 #define LUMIERA_ADVICE_H
95 
96 
97 #include "lib/error.hpp"
98 #include "lib/nocopy.hpp"
99 #include "lib/null-value.hpp"
100 #include "lib/symbol.hpp"
101 #include "lib/util.hpp"
102 
103 #include "common/advice/binding.hpp"
104 
105 
106 namespace lumiera{
107 namespace advice {
108 
109  using lib::Literal;
110  using util::isSameObject;
111 
112 
127  {
130 
131  protected:
137  void setBindingPattern (Binding const& binding)
138  {
139  pattern_ = binding.buildMatcher();
140  }
141 
142  public:
143  explicit
144  PointOfAdvice (Binding const& binding)
145  : pattern_(binding.buildMatcher())
146  , resolution_(0)
147  { }
148 
149  // using default copy/assignment
150 
151 
152 
153  /* == Adapter interface for use within the Index == */
154 
155  void
156  setSolution (PointOfAdvice* solution =0)
157  {
158  resolution_ = solution;
159  }
160 
161  const PointOfAdvice*
162  getSolution () const
163  {
164  return resolution_;
165  }
166 
168  getMatcher () const
169  {
170  return pattern_;
171  }
172 
173  friend HashVal
174  hash_value (PointOfAdvice const& entry)
175  {
176  return hash_value (entry.pattern_);
177  }
178  };
179 
180 
181 
182 
190  : public PointOfAdvice
191  {
192  protected:
194  void discardSolutions ();
196 
197  void registerRequest();
198  void deregisterRequest();
199 
200  static void* getBuffer(size_t);
201  static void releaseBuffer (void*, size_t);
202 
203  typedef void (DeleterFunc)(void*);
204  static void manageAdviceData (PointOfAdvice*, DeleterFunc*);
205 
206  public:
207  explicit
208  AdviceLink (Binding const& binding)
209  : PointOfAdvice(binding)
210  { }
211 
212  // using default copy/assignment
213  };
214 
215 
216 
217 
218 
238  template<class AD>
239  class Provision
240  : protected AdviceLink
241  {
242 
243 
244  /* == policy definitions == */
245 
246  void deregistrate() { /* NOP */ }
247 
248 
249  public:
250  explicit
251  Provision (Literal bindingSpec =0)
252  : AdviceLink (Binding(bindingSpec).addTypeGuard<AD>())
253  { }
254 
256  {
257  this->deregistrate();
258  }
259 
260  Provision (Provision const& o)
261  : AdviceLink(o)
262  {
263  setSolution ( NULL );
264  }
265 
266  Provision&
268  {
269  if (!isSameObject(*this, o))
270  {
271  AdviceLink::operator= (o);
272  setSolution ( NULL );
273  }
274  return *this;
275  }
276 
277 
278  void setAdvice (AD const& pieceOfAdvice)
279  {
281  storeCopy (pieceOfAdvice));
282  }
283 
285  {
287  }
288 
289  void
291  {
292  setBindingPattern (Binding(topic).addTypeGuard<AD>());
293  maybe_rePublish();
294  }
295 
296  private:
297  PointOfAdvice* storeCopy (AD const& advice_given);
298  static void releaseAdviceData (void*);
299  void maybe_rePublish ();
300  };
301 
302 
314  template<class AD>
316  : public PointOfAdvice
318  {
320 
321  public:
322  AD const&
323  getAdvice() const
324  {
325  return theAdvice_;
326  }
327 
328  protected:
329  ActiveProvision (PointOfAdvice const& refPoint, AD const& advice_given)
330  : PointOfAdvice(refPoint)
331  , theAdvice_(advice_given)
332  {
333  this->setSolution (this); // not used currently (5/10)
334  }
335 
336  friend class Provision<AD>;
337  };
338 
339 
340  /* ==== memory management for Provision data ===== */
341 
346  template<class AD>
347  inline PointOfAdvice*
348  Provision<AD>::storeCopy (AD const& advice_given)
349  {
350  typedef ActiveProvision<AD> Holder;
351  void* storage = getBuffer(sizeof(Holder));
352  try
353  {
354  Holder* storedProvision = new(storage) Holder (*this, advice_given);
355  manageAdviceData (storedProvision, &releaseAdviceData);
356  return storedProvision;
357  }
358  catch(...)
359  {
360  Literal errID = lumiera_error();
361  releaseBuffer (storage, sizeof(Holder));
362  throw lumiera::error::Fatal ("Failure to store advice data", errID);
363  }
364  }
365 
366 
371  template<class AD>
372  inline void
374  {
375  typedef ActiveProvision<AD> Holder;
376  if (entry)
377  {
378  Holder* obj = static_cast<Holder*> (entry);
379  obj->~Holder();
380  releaseBuffer (entry, sizeof(Holder));
381  }
382  }
383 
384 
389  template<class AD>
390  inline void
392  {
393  typedef const ActiveProvision<AD> AdviceProvision;
394  AdviceProvision* solution = static_cast<AdviceProvision*> (getSolution());
395 
396  if (solution) // create copy of the data holder, using the new binding
397  publishProvision(
398  storeCopy (solution->getAdvice()));
399  }
400 
401 
402 
403 
404 
405 
406 
425  template<class AD>
426  class Request
427  : protected AdviceLink
428  {
430 
431 
432  /* == policy definitions == */
433 
434  AD const&
436  {
437  return lib::NullValue<AD>::get();
438  }
439 
440 
441  public:
442  explicit
443  Request (Literal bindingSpec =0)
444  : AdviceLink (Binding(bindingSpec).addTypeGuard<AD>())
445  {
446  registerRequest();
447  }
448 
450  {
452  }
453 
454  // copying Requests is allowed, using default
455 
456 
457  AD const&
458  getAdvice() const
459  {
460  AdviceProvision* solution = static_cast<AdviceProvision*> (this->getSolution());
461  if (!solution)
462  return this->handleMissingSolution();
463  else
464  return solution->getAdvice();
465  }
466 
467 
468  void
470  {
471  HashVal previous_bindingKey (hash_value(*this));
472  setBindingPattern (Binding(topic).addTypeGuard<AD>());
473  publishRequestBindingChange (previous_bindingKey);
474  }
475  };
476 
477 
478 
479 
480 
481 }} // namespace lumiera::advice
482 #endif
AD const & getAdvice() const
Definition: advice.hpp:323
Access point for the advised entity (client).
Definition: advice.hpp:426
Conjunction of predicates to be matched against a collaboration partner for establishing an Advice co...
ActiveProvision(PointOfAdvice const &refPoint, AD const &advice_given)
Definition: advice.hpp:329
Provision(Literal bindingSpec=0)
Definition: advice.hpp:251
Functor object for matching against another Binding.
Basic (abstracted) view of an advice collaboration partner, as used internally by the AdviceSystem to...
Definition: advice.hpp:126
void defineBinding(Literal topic)
Definition: advice.hpp:469
Piece of Advice as incorporated into the AdviceSystem.
Definition: advice.hpp:315
static void releaseAdviceData(void *)
Definition: advice.hpp:373
PointOfAdvice * resolution_
Definition: advice.hpp:129
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:75
const ActiveProvision< AD > AdviceProvision
Definition: advice.hpp:429
PointOfAdvice * storeCopy(AD const &advice_given)
Definition: advice.hpp:348
Singleton-style holder for NIL or default values.
static TY const & get()
Definition: null-value.hpp:75
void setSolution(PointOfAdvice *solution=0)
Definition: advice.hpp:156
bool isSameObject(A const &a, B const &b)
compare plain object identity, bypassing any custom comparison operators.
Definition: util.hpp:337
AD const & getAdvice() const
Definition: advice.hpp:458
Provision(Provision const &o)
Definition: advice.hpp:260
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Access point for the advising entity (server).
Definition: advice.hpp:239
return NULL
Definition: llist.h:596
AD const & handleMissingSolution() const
<
Definition: advice.hpp:435
Marker types to indicate a literal string and a Symbol.
void setAdvice(AD const &pieceOfAdvice)
Definition: advice.hpp:278
Tiny helper functions and shortcuts to be used everywhere Consider this header to be effectively incl...
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:124
friend HashVal hash_value(PointOfAdvice const &entry)
Definition: advice.hpp:174
const PointOfAdvice * getSolution() const
Definition: advice.hpp:162
Request(Literal bindingSpec=0)
Definition: advice.hpp:443
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:56
Provision & operator=(Provision const &o)
Definition: advice.hpp:267
PointOfAdvice(Binding const &binding)
Definition: advice.hpp:144
Binding::Matcher getMatcher() const
Definition: advice.hpp:168
Lumiera public interface.
Binding::Matcher pattern_
Definition: advice.hpp:128
void setBindingPattern(Binding const &binding)
define or re-define the binding, which specifically labels this attachment to the advice system...
Definition: advice.hpp:137
void defineBinding(Literal topic)
Definition: advice.hpp:290
LumieraError< LERR_(FATAL), Logic > Fatal
Definition: error.hpp:213