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) Lumiera.org
5  2008, 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 
40 #ifndef LUMIERA_INSTANCEHANDLE_H
41 #define LUMIERA_INSTANCEHANDLE_H
42 
43 
44 #include "include/logging.h"
45 #include "lib/error.hpp"
46 #include "lib/nocopy.hpp"
47 #include "lib/depend-inject.hpp"
48 
49 extern "C" {
50 #include "common/interface.h"
52 }
53 
54 #include <string>
55 
56 
57 
58 namespace lumiera {
59 
60  using std::string;
61 
62  template<class I, class FA>
64 
65 
66  namespace { // implementation details
67 
68  void
69  throwIfError()
70  {
71  if (lumiera_error_peek())
72  throw lumiera::error::Config("failed to open interface or plugin.",lumiera_error());
73  }
74 
81  LumieraInterface
82  register_and_open (LumieraInterface descriptor)
83  {
84  if (!descriptor) return NULL;
85  lumiera_interfaceregistry_register_interface (descriptor, NULL);
86  throwIfError();
87  return lumiera_interface_open (descriptor->interface,
88  descriptor->version,
89  descriptor->size,
90  descriptor->name);
91  }
92 
96  bool
97  verify_validity (LumieraInterface ifa)
98  {
99  REQUIRE (ifa);
100  return (ifa == lumiera_interfaceregistry_interface_find (ifa->interface,
101  ifa->version,
102  ifa->name));
103  }
104 
105  } // (End) impl details
106 
107 
108 
109 
110  namespace facade {
111 
119  template<class IHA>
120  class Proxy;
121 
123  template<class I, class FA>
124  using ServiceHandle = typename lib::DependInject<FA>::template ServiceInstance<Proxy<InstanceHandle<I,FA>>>;
125 
126 
136  template<class I, class FA>
137  struct Link
138  : ServiceHandle<I,FA>
139  {
140  using IH = InstanceHandle<I,FA>;
141 
142  Link (IH const& iha);
143  ~Link ();
144 
145  FA* operator->() const;
146  };
147 
148 
154  template<class I>
155  struct Link<I,I>
157  {
158  using IH = InstanceHandle<I,I>;
159  IH& ih_;
160 
161  Link (IH& ih)
162  : ih_{ih}
163  { }
164 
165  I*
166  operator->() const
167  {
168  return & ih_.get();
169  }
170  };
171 
172  } // namespace facade (impl details)
173 
174 
175 
176 
177 
188  template< class I
189  , class FA = I
190  >
191  class InstanceHandle
193  {
194  LumieraInterface desc_;
195  I* instance_;
196  facade::Link<I,FA> facadeLink_;
197 
198  public:
206  InstanceHandle (string const& iName, uint version, size_t minminor, string const& impName)
207  : desc_(0)
208  , instance_(reinterpret_cast<I*>
209  (lumiera_interface_open (iName.c_str(), version, minminor, impName.c_str())))
210  , facadeLink_(*this)
211  {
212  throwIfError();
213  }
214 
221  InstanceHandle (LumieraInterface descriptor)
222  : desc_(descriptor)
223  , instance_(reinterpret_cast<I*> (register_and_open (desc_)))
224  , facadeLink_(*this)
225  {
226  throwIfError();
227  }
228 
229  ~InstanceHandle ()
230  {
231  lumiera_interface_close (&instance_->interface_header_);
232  if (desc_)
233  lumiera_interfaceregistry_remove_interface (desc_);
234  }
235 
236 
237 
241  FA*
242  operator-> () const
243  {
244  return facadeLink_.operator ->();
245  }
246 
248  I&
249  get () const
250  {
251  ENSURE(instance_);
252  return *instance_;
253  }
254 
255 
256  explicit
257  operator bool() const
258  {
259  return isValid();
260  }
261  bool
262  operator!() const
263  {
264  return not isValid();
265  }
266 
267 
268  private:
269  bool
270  isValid() const
271  {
272  return instance_
273  && verify_validity (&instance_->interface_header_);
274  }
275  };
276 
277 
278 } // namespace lumiera
279 
280 #endif
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:142
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:58
InstanceHandle(LumieraInterface descriptor)
Set up an InstanceHandle managing the registration and deregistration of interface(s).
Any copy and copy construction prohibited.
Definition: nocopy.hpp:46
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:199
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:235
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:124
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:113
typename lib::DependInject< FA >::template ServiceInstance< Proxy< InstanceHandle< I, FA > >> ServiceHandle
The ServiceHandle automatically creates and manages the Proxy instance.