Lumiera  0.pre.03
»edit your freedom«
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)
5  2010, Hermann Vosseler <Ichthyostega@web.de>
6 
7   **Lumiera** is free software; you can redistribute it and/or modify it
8   under the terms of the GNU General Public License as published by the
9   Free Software Foundation; either version 2 of the License, or (at your
10   option) any later version. See the file COPYING for further details.
11 
12 */
13 
14 
89 #ifndef LUMIERA_ADVICE_H
90 #define LUMIERA_ADVICE_H
91 
92 
93 #include "lib/error.hpp"
94 #include "lib/nocopy.hpp"
95 #include "lib/null-value.hpp"
96 #include "lib/symbol.hpp"
97 #include "lib/util.hpp"
98 
100 
101 
102 namespace lumiera{
103 namespace advice {
104 
105  using lib::Literal;
106  using util::isSameObject;
107 
108 
123  {
124  Binding::Matcher pattern_;
125  PointOfAdvice* resolution_;
126 
127  protected:
133  void setBindingPattern (Binding const& binding)
134  {
135  pattern_ = binding.buildMatcher();
136  }
137 
138  public:
139  explicit
140  PointOfAdvice (Binding const& binding)
141  : pattern_(binding.buildMatcher())
142  , resolution_(nullptr)
143  { }
144 
145  // using default copy/assignment
146 
147 
148 
149  /* == Adapter interface for use within the Index == */
150 
151  void
152  setSolution (PointOfAdvice* solution =0)
153  {
154  resolution_ = solution;
155  }
156 
157  const PointOfAdvice*
158  getSolution () const
159  {
160  return resolution_;
161  }
162 
164  getMatcher () const
165  {
166  return pattern_;
167  }
168 
169  friend HashVal
170  hash_value (PointOfAdvice const& entry)
171  {
172  return hash_value (entry.pattern_);
173  }
174  };
175 
176 
177 
178 
186  : public PointOfAdvice
187  {
188  protected:
189  void publishProvision (PointOfAdvice*);
190  void discardSolutions ();
191  void publishRequestBindingChange(HashVal);
192 
193  void registerRequest();
194  void deregisterRequest();
195 
196  static void* getBuffer(size_t);
197  static void releaseBuffer (void*, size_t);
198 
199  typedef void (DeleterFunc)(void*);
200  static void manageAdviceData (PointOfAdvice*, DeleterFunc*);
201 
202  public:
203  explicit
204  AdviceLink (Binding const& binding)
205  : PointOfAdvice(binding)
206  { }
207 
208  // using default copy/assignment
209  };
210 
211 
212 
213 
214 
234  template<class AD>
235  class Provision
236  : protected AdviceLink
237  {
238 
239 
240  /* == policy definitions == */
241 
242  void deregister() { /* NOP */ }
243 
244 
245  public:
246  explicit
247  Provision (Literal bindingSpec =0)
248  : AdviceLink (Binding(bindingSpec).addTypeGuard<AD>())
249  { }
250 
251  ~Provision()
252  {
253  this->deregister();
254  }
255 
256  Provision (Provision const& o)
257  : AdviceLink(o)
258  {
259  setSolution ( NULL );
260  }
261 
262  Provision&
263  operator= (Provision const& o)
264  {
265  if (not isSameObject (*this, o))
266  {
267  AdviceLink::operator= (o);
268  setSolution (nullptr);
269  }
270  return *this;
271  }
272 
273 
274  void setAdvice (AD const& pieceOfAdvice)
275  {
276  publishProvision(
277  storeCopy (pieceOfAdvice));
278  }
279 
280  void retractAdvice()
281  {
282  discardSolutions();
283  }
284 
285  bool
286  isGiven() const
287  {
288  return bool{this->getSolution()};
289  }
290 
291  void
292  defineBinding (Literal topic)
293  {
294  setBindingPattern (Binding(topic).addTypeGuard<AD>());
295  maybe_rePublish();
296  }
297 
298  private:
299  PointOfAdvice* storeCopy (AD const& advice_given);
300  static void releaseAdviceData (void*);
301  void maybe_rePublish ();
302  };
303 
304 
316  template<class AD>
318  : public PointOfAdvice
320  {
321  AD theAdvice_;
322 
323  public:
324  AD const&
325  getAdvice() const
326  {
327  return theAdvice_;
328  }
329 
330  protected:
331  ActiveProvision (PointOfAdvice const& refPoint, AD const& advice_given)
332  : PointOfAdvice(refPoint)
333  , theAdvice_(advice_given)
334  {
335  this->setSolution (this); // not used currently (5/10)
336  }
337 
338  friend class Provision<AD>;
339  };
340 
341 
342  /* ==== memory management for Provision data ===== */
343 
348  template<class AD>
349  inline PointOfAdvice*
350  Provision<AD>::storeCopy (AD const& advice_given)
351  {
352  typedef ActiveProvision<AD> Holder;
353  void* storage = getBuffer(sizeof(Holder));
354  try
355  {
356  Holder* storedProvision = new(storage) Holder (*this, advice_given);
357  manageAdviceData (storedProvision, &releaseAdviceData);
358  return storedProvision;
359  }
360  catch(...)
361  {
362  Literal errID = lumiera_error();
363  releaseBuffer (storage, sizeof(Holder));
364  throw lumiera::error::Fatal ("Failure to store advice data", errID);
365  }
366  }
367 
368 
373  template<class AD>
374  inline void
376  {
377  typedef ActiveProvision<AD> Holder;
378  if (entry)
379  {
380  Holder* obj = static_cast<Holder*> (entry);
381  obj->~Holder();
382  releaseBuffer (entry, sizeof(Holder));
383  }
384  }
385 
386 
391  template<class AD>
392  inline void
394  {
395  typedef const ActiveProvision<AD> AdviceProvision;
396  AdviceProvision* solution = static_cast<AdviceProvision*> (getSolution());
397 
398  if (solution) // create copy of the data holder, using the new binding
399  publishProvision(
400  storeCopy (solution->getAdvice()));
401  }
402 
403 
404 
405 
406 
407 
408 
427  template<class AD>
428  class Request
429  : protected AdviceLink
430  {
431  typedef const ActiveProvision<AD> AdviceProvision;
432 
433 
434  /* == policy definitions == */
435 
436  AD const&
438  {
439  return lib::NullValue<AD>::get();
440  }
441 
442 
443  public:
444  explicit
445  Request (Literal bindingSpec =0)
446  : AdviceLink (Binding(bindingSpec).addTypeGuard<AD>())
447  {
448  registerRequest();
449  }
450 
451  ~Request()
452  {
453  deregisterRequest();
454  }
455 
456  // copying Requests is allowed, using default
457 
458 
459  AD const&
460  getAdvice() const
461  {
462  AdviceProvision* solution = static_cast<AdviceProvision*> (this->getSolution());
463  if (!solution)
464  return this->handleMissingSolution();
465  else
466  return solution->getAdvice();
467  }
468 
469 
474  bool
475  isMatched() const
476  {
477  return bool{this->getSolution()};
478  }
479 
480 
482  void
484  {
485  HashVal previous_bindingKey (hash_value(*this));
486  setBindingPattern (Binding(topic).addTypeGuard<AD>());
487  publishRequestBindingChange (previous_bindingKey);
488  }
489  };
490 
491 
492 
493 
494 
495 }} // namespace lumiera::advice
496 #endif
Access point for the advised entity (client).
Definition: advice.hpp:428
Conjunction of predicates to be matched against a collaboration partner for establishing an Advice co...
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:122
void defineBinding(Literal topic)
set and possibly change the binding term used to retrieve Advice
Definition: advice.hpp:483
Piece of Advice as incorporated into the AdviceSystem.
Definition: advice.hpp:317
static void releaseAdviceData(void *)
Definition: advice.hpp:375
AnyPair entry(Query< TY > const &query, typename WrapReturn< TY >::Wrapper &obj)
helper to simplify creating mock table entries, wrapped correctly
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
inline string literal This is a marker type to indicate that
Definition: symbol.hpp:76
Singleton holder for NIL or default value objects.
Definition: null-value.hpp:62
PointOfAdvice * storeCopy(AD const &advice_given)
Definition: advice.hpp:350
bool isMatched() const
Definition: advice.hpp:475
Singleton-style holder for NIL or default values.
Derived specific exceptions within Lumiera&#39;s exception hierarchy.
Definition: error.hpp:190
Mix-Ins to allow or prohibit various degrees of copying and cloning.
Access point for the advising entity (server).
Definition: advice.hpp:235
A pattern to define and identify a specific attachment to the Advice system.
Marker types to indicate a literal string and a Symbol.
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:115
Lumiera error handling (C++ interface).
size_t HashVal
a STL compatible hash value
Definition: hash-value.h:52
Lumiera public interface.
Definition: advice.cpp:104
AD const & handleMissingSolution() const
<
Definition: advice.hpp:437
void setBindingPattern(Binding const &binding)
define or re-define the binding, which specifically labels this attachment to the advice system...
Definition: advice.hpp:133
bool isSameObject(A const &a, B const &b)
compare plain object identity, based directly on the referee&#39;s memory identities. ...
Definition: util.hpp:421