Lumiera  0.pre.03
»edit your freedom«
instancehandle.hpp
Go to the documentation of this file.
1 /*
2  INSTANCEHANDLE.hpp - automatically handling interface lifecycle
3 
4  Copyright (C)
5  2008, 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 
31 #ifndef LUMIERA_INSTANCEHANDLE_H
32 #define LUMIERA_INSTANCEHANDLE_H
33 
34 
35 #include "include/logging.h"
36 #include "lib/error.hpp"
37 #include "lib/nocopy.hpp"
38 #include "lib/depend-inject.hpp"
39 
40 extern "C" {
41 #include "common/interface.h"
43 }
44 
45 #include <string>
46 
47 
48 
49 namespace lumiera {
50 
51  using std::string;
52 
53  template<class I, class FA>
55 
56 
57  namespace { // implementation details
58 
59  inline void
60  throwIfError()
61  {
62  if (lumiera_error_peek())
63  throw lumiera::error::Config("failed to open interface or plugin.",lumiera_error());
64  }
65 
72  inline LumieraInterface
73  register_and_open (LumieraInterface descriptor)
74  {
75  if (!descriptor) return NULL;
76  lumiera_interfaceregistry_register_interface (descriptor, NULL);
77  throwIfError();
78  return lumiera_interface_open (descriptor->interface,
79  descriptor->version,
80  descriptor->size,
81  descriptor->name);
82  }
83 
87  inline bool
88  verify_validity (LumieraInterface ifa)
89  {
90  REQUIRE (ifa);
91  return (ifa == lumiera_interfaceregistry_interface_find (ifa->interface,
92  ifa->version,
93  ifa->name));
94  }
95 
96  } // (End) impl details
97 
98 
99 
100 
101  namespace facade {
102 
110  template<class IHA>
111  class Proxy;
112 
114  template<class I, class FA>
115  using ServiceHandle = typename lib::DependInject<FA>::template ServiceInstance<Proxy<InstanceHandle<I,FA>>>;
116 
117 
127  template<class I, class FA>
128  struct Link
129  : ServiceHandle<I,FA>
130  {
131  using IH = InstanceHandle<I,FA>;
132 
133  Link (IH const& iha);
134  ~Link ();
135 
136  FA* operator->() const;
137  };
138 
139 
145  template<class I>
146  struct Link<I,I>
148  {
149  using IH = InstanceHandle<I,I>;
150 
151  IH& ih_;
152 
153  Link(IH& ih)
154  : ih_{ih}
155  { }
156 
157  I*
158  operator->() const
159  {
160  return & ih_.get();
161  }
162  };
163 
164  } // namespace facade (impl details)
165 
166 
167 
168 
169 
180  template< class I
181  , class FA = I
182  >
183  class InstanceHandle
185  {
186  LumieraInterface desc_;
187  I* instance_;
188  facade::Link<I,FA> facadeLink_;
189 
190  public:
198  InstanceHandle (string const& iName, uint version, size_t minminor, string const& impName)
199  : desc_(0)
200  , instance_(reinterpret_cast<I*>
201  (lumiera_interface_open (iName.c_str(), version, minminor, impName.c_str())))
202  , facadeLink_(*this)
203  {
204  throwIfError();
205  }
206 
213  InstanceHandle (LumieraInterface descriptor)
214  : desc_(descriptor)
215  , instance_(reinterpret_cast<I*> (register_and_open (desc_)))
216  , facadeLink_(*this)
217  {
218  throwIfError();
219  }
220 
221  ~InstanceHandle()
222  {
223  lumiera_interface_close (&instance_->interface_header_);
224  if (desc_)
225  lumiera_interfaceregistry_remove_interface (desc_);
226  }
227 
228 
229 
233  FA*
234  operator->() const
235  {
236  return facadeLink_.operator ->();
237  }
238 
240  I&
241  get() const
242  {
243  ENSURE(instance_);
244  return *instance_;
245  }
246 
247 
248  explicit
249  operator bool() const
250  {
251  return isValid();
252  }
253  bool
254  operator!() const
255  {
256  return not isValid();
257  }
258 
259 
260  private:
261  bool
262  isValid() const
263  {
264  return instance_
265  and verify_validity (&instance_->interface_header_);
266  }
267  };
268 
269 
270 } // namespace lumiera
271 #endif /*LUMIERA_INSTANCEHANDLE_H*/
lumiera_err lumiera_error_peek(void)
Check current error state without clearing it Please avoid this function and use lumiera_error() if p...
Definition: error-state.c:133
FA * operator->() const
act as smart pointer to allow access through the facade.
I & get() const
directly access the instance via the CL interface
LumieraInterface lumiera_interface_open(const char *interface, unsigned version, size_t minminorversion, const char *name)
Open an interface by version and name.
Definition: interface.c:49
InstanceHandle(LumieraInterface descriptor)
Set up an InstanceHandle managing the registration and deregistration of interface(s).
Any copy and copy construction prohibited.
Definition: nocopy.hpp:37
Per type specific configuration of instances created as service dependencies.
bool verify_validity(LumieraInterface ifa)
do a lookup within the interfaceregistry using the name/version found within the interface handle...
This header is for including and configuring NoBug.
Lumiera interface macros and structures.
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.
This framework allows to (re)configure the lib::Depend front-end for dependency-injection.
void lumiera_interface_close(LumieraInterface self)
Close an interface after use.
Definition: interface.c:226
to be specialised and implemented for each individual interface and facade interface.
InstanceHandle(string const &iName, uint version, size_t minminor, string const &impName)
Set up an InstanceHandle representing a plugin.
lumiera_err lumiera_error(void)
Get and clear current error state.
Definition: error-state.c:115
Lumiera error handling (C++ interface).
Global registry for interfaces (extension points).
Handle tracking the registration of an interface, deregistering it on deletion.
LumieraInterface register_and_open(LumieraInterface descriptor)
takes a (single) instance definitions, as typically created when defining interfaces for external use...
Lumiera public interface.
Definition: advice.cpp:104
typename lib::DependInject< FA >::template ServiceInstance< Proxy< InstanceHandle< I, FA > >> ServiceHandle
The ServiceHandle automatically creates and manages the Proxy instance.