Nemiver  0.3
nmv-dynamic-module.h
Go to the documentation of this file.
1 /* -*- Mode: C++; indent-tabs-mode:nil; c-basic-offset:4;-*- */
2 
3 /*Copyright (c) 2005-2006 Dodji Seketeli
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of this
6  * software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute,
9  * sublicense, and/or sell copies of the Software, and to permit
10  * persons to whom the Software is furnished to do so,
11  * subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all copies
14  * or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS",
17  * WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
18  * INCLUDING BUT NOT LIMITED TO THE
19  * WARRANTIES OF MERCHANTABILITY,
20  * FITNESS FOR A PARTICULAR PURPOSE
21  * AND NONINFRINGEMENT.
22  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23  * HOLDERS BE LIABLE FOR ANY CLAIM,
24  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
25  * CONTRACT, TORT OR OTHERWISE,
26  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
27  * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28  *
29  */
30 #ifndef __NMV_DYNAMIC_MODULE_H__
31 #define __NMV_DYNAMIC_MODULE_H__
32 
33 #include <vector>
34 #include <list>
35 #include <map>
36 #include <string>
37 #include <gmodule.h>
38 #include "nmv-api-macros.h"
39 #include "nmv-object.h"
40 #include "nmv-ustring.h"
41 #include "nmv-safe-ptr-utils.h"
42 #include "nmv-exception.h"
43 
46 extern "C" {
47 
54 bool nemiver_common_create_dynamic_module_instance (void **a_new_instance);
55 
56 }
57 
58 NEMIVER_BEGIN_NAMESPACE (nemiver)
59 NEMIVER_BEGIN_NAMESPACE (common)
60 
63 
66 
69  ObjectRef,
71 
77 
78 public:
79 
80  struct Info {
84 
85  Info (const UString &a_name,
86  const UString &a_desc,
87  const UString &a_version) :
88  module_name (a_name),
89  module_description (a_desc),
90  module_version (a_version)
91  {}
92 
93  };//end struct info
94 
95  struct Config : public Object {
96  std::vector<UString> custom_library_search_paths;
98  virtual ~Config () {};
99  };//end stuct ModuleConfig
100 
102 
103  class NEMIVER_API Loader : public Object {
104  struct Priv;
106  friend class DynamicModuleManager;
107 
108  //non copyable
109  Loader (const Loader &);
110  Loader& operator= (const Loader &);
111 
112  void set_dynamic_module_manager (DynamicModuleManager *a_mgr);
113 
114 
115  public:
116  Loader ();
117  virtual ~Loader ();
118  std::vector<UString>& config_search_paths ();
119  virtual DynamicModule::ConfigSafePtr module_config
120  (const std::string &a_name);
121  virtual UString build_library_path (const UString &a_module_name,
122  const UString &a_lib_name);
123  virtual ConfigSafePtr parse_module_config_file (const UString &a_path);
124  virtual UString module_library_path (const UString &a_name);
125  virtual GModule* load_library_from_path (const UString &a_path);
126  virtual GModule* load_library_from_module_name (const UString &a_name);
127  virtual DynamicModuleSafePtr create_dynamic_module_instance
128  (GModule *a_module);
129 
130  virtual DynamicModuleSafePtr load (const UString &a_name);
131  virtual DynamicModuleSafePtr load_from_path
132  (const UString &a_lib_path);
133  DynamicModuleManager* get_dynamic_module_manager ();
134 
135  };//end class Loader
137 
138 protected:
139  //must be instanciated by a factory
140  DynamicModule ();
141 
142 private:
143  struct Priv;
144  SafePtr<Priv> m_priv;
145  friend bool gpil_common_create_loadable_module_instance (void **a_new_inst);
146  friend class Loader;
147  friend class DynamicModuleManager;
148 
149  //non copyable
150  DynamicModule (const DynamicModule &);
151  DynamicModule& operator= (const DynamicModule &);
152 
153  void set_real_library_path (const UString &a_path);
154 
155  void set_name (const UString &a_name);
156 
157  void set_module_loader (Loader *a_loader);
158 
159 
160 public:
161 
164  Loader* get_module_loader ();
165 
169  const UString& get_real_library_path () const;
170 
172  const UString& get_name () const;
173 
175  virtual ~DynamicModule ();
176 
178  virtual void get_info (Info &a_info) const = 0;
179 
184  virtual void do_init () = 0;
185 
197  virtual bool lookup_interface (const std::string &a_iface_name,
198  DynModIfaceSafePtr &a_iface) = 0;
199 
200  template <class T> bool lookup_interface
201  (const std::string &a_iface_name,
203  {
204  DynModIfaceSafePtr iface;
205  if (!lookup_interface (a_iface_name, iface)) {
206  return false;
207  }
208  typedef SafePtr<T, ObjectRef, ObjectUnref> TSafePtr;
209  // Here, the 'template' keyword is useless, stricto sensu.
210  // But we need it to keep gcc 3.3.5 happy.
211  TSafePtr res = iface.template do_dynamic_cast<T> ();
212  if (!res) {
213  return false;
214  }
215  a_iface = res;
216  return true;
217  }
218 };//end class DynamicModule
219 
221  DynamicModuleSafePtr m_dynamic_module;
222  //subclassers _MUST_ not use the default constructor,
223  //but rather use the DynModIface (DynamicModule &a_dynmod) one.
224  DynModIface ();
225  DynModIface (const DynModIface &);
227 
228 public:
229 
231  m_dynamic_module (a_dynmod)
232  {
233  THROW_IF_FAIL (m_dynamic_module);
234  }
235 
237  m_dynamic_module (DynamicModuleSafePtr (a_dynmod, true))
238  {
239  THROW_IF_FAIL (m_dynamic_module);
240  }
241 
243  {
244  THROW_IF_FAIL (m_dynamic_module);
245  return *m_dynamic_module;
246  }
247 };//end class DynModIface
248 
250  struct Priv;
252  //non coyable;
253  ModuleRegistry (const ModuleRegistry &);
255 
256 public:
257  ModuleRegistry ();
258  virtual ~ModuleRegistry ();
259  GModule* get_library_from_cache (const UString a_name);
260  void put_library_into_cache (const UString a_name,
261  GModule *a_module);
262 };//end class ModuleRegistry
263 
264 
266  struct Priv;
268 
269 public:
270 
272  virtual ~DynamicModuleManager ();
273 
274  DynamicModuleSafePtr load_module_from_path (const UString &a_library_path,
276 
277  DynamicModuleSafePtr load_module_from_path (const UString &a_library_path);
278 
279  DynamicModuleSafePtr load_module (const UString &a_name,
281 
282  DynamicModuleSafePtr load_module (const UString &a_name);
283 
284  static DynamicModuleManager& get_default_manager ();
285 
286  static DynamicModuleSafePtr load_module_with_default_manager
287  (const UString &a_mod_name,
289 
290  static DynamicModuleSafePtr load_module_with_default_manager
291  (const UString &a_mod_name);
292 
293 
294  template <class T> SafePtr<T, ObjectRef, ObjectUnref>
295  load_iface (const UString &a_module_name,
296  const UString &a_iface_name,
297  DynamicModule::Loader & a_loader,
298  DynamicModuleSafePtr &a_dynmod);
299 
300  template <class T> SafePtr<T, ObjectRef, ObjectUnref>
301  load_iface (const UString &a_module_name,
302  const UString &a_iface_name,
303  DynamicModule::Loader & a_loader);
304 
305  template <class T> SafePtr<T, ObjectRef, ObjectUnref>
306  load_iface (const UString &a_module_name,
307  const UString &a_iface_name,
308  DynamicModuleSafePtr &a_dynmod);
309 
310  template <class T> SafePtr<T, ObjectRef, ObjectUnref>
311  load_iface (const UString &a_module_name,
312  const UString &a_iface_name);
313  template <class T> static SafePtr<T, ObjectRef, ObjectUnref>
314  load_iface_with_default_manager (const UString &a_module_name,
315  const UString &a_iface_name);
316 
317 
318  ModuleRegistry& module_registry ();
319  DynamicModule::LoaderSafePtr& module_loader ();
320  void module_loader (DynamicModule::LoaderSafePtr &a_loader);
321 };//end class DynamicModuleManager
322 
323 template <class T>
325 DynamicModuleManager::load_iface (const UString &a_module_name,
326  const UString &a_iface_name,
327  DynamicModule::Loader &a_loader,
328  DynamicModuleSafePtr &a_dynmod)
329 {
330  DynamicModuleSafePtr module (load_module (a_module_name, a_loader));
331  typedef SafePtr<T, ObjectRef, ObjectUnref> TSafePtr;
332  if (!module) {
333  THROW (UString ("failed to load module '") + a_module_name);
334  }
335  module->do_init ();
336  LOG_REF_COUNT (module, a_module_name);
337  DynModIfaceSafePtr tmp_iface;
338  if (!module->lookup_interface (a_iface_name, tmp_iface)) {
339  THROW (UString ("module does not have interface: ") + a_iface_name);
340  }
341  THROW_IF_FAIL (tmp_iface);
342  LOG_REF_COUNT (module, a_module_name);
343  TSafePtr result;
344  // Here, the 'template' keyword is useless, stricto sensu.
345  // But we need it to keep gcc 3.3.5 happy.
346  result = tmp_iface.template do_dynamic_cast<T> ();
347  LOG_REF_COUNT (module, a_module_name);
348  if (!result) {
349  THROW (UString ("interface named ")
350  + a_iface_name
351  + " is not of the expected type'");
352  }
353  a_dynmod = module;
354  return result;
355 }
356 
357 template <class T>
359 DynamicModuleManager::load_iface (const UString &a_module_name,
360  const UString &a_iface_name,
361  DynamicModule::Loader &a_loader)
362 {
363  DynamicModuleSafePtr dynmod;
364 
365  return load_iface<T> (a_module_name, a_iface_name,
366  a_loader, dynmod);
367 }
368 
369 template <class T>
371 DynamicModuleManager::load_iface (const UString &a_module_name,
372  const UString &a_iface_name,
373  DynamicModuleSafePtr &a_dynmod)
374 {
375  return load_iface<T> (a_module_name, a_iface_name,
376  *module_loader (), a_dynmod);
377 }
378 
379 template <class T>
381 DynamicModuleManager::load_iface (const UString &a_module_name,
382  const UString &a_iface_name)
383 {
384  DynamicModuleSafePtr dynmod;
385  return load_iface<T> (a_module_name, a_iface_name,
386  *module_loader (), dynmod);
387 }
388 
389 template <class T>
391 DynamicModuleManager::load_iface_with_default_manager
392  (const UString &a_mod_name,
393  const UString &a_iface_name)
394 {
395  return get_default_manager ().load_iface<T> (a_mod_name, a_iface_name);
396 }
397 
401 template<class T>
404  const UString &a_iface_name)
405 {
406  DynamicModuleManager *manager =
409  THROW_IF_FAIL (manager);
411  manager->load_iface<T> (a_iface.get_dynamic_module ().get_name (),
412  a_iface_name);
413  THROW_IF_FAIL (iface);
414  return iface;
415 }
416 
417 template<class T>
420  const UString &a_iface_name)
421 {
422  DynamicModuleManager *manager =
424 
425  THROW_IF_FAIL (manager);
427  manager->load_iface<T> (a_dynmod.get_name (), a_iface_name);
428  THROW_IF_FAIL (iface);
429  return iface;
430 }
431 
432 NEMIVER_END_NAMESPACE (common)
433 NEMIVER_END_NAMESPACE (nemiver)
434 
435 #endif// __NMV_DYNAMIC_MODULE_H__
436 
nmv-safe-ptr-utils.h
nemiver::common::DynamicModule::Config
Definition: nmv-dynamic-module.h:95
nemiver::common::Object
Definition: nmv-object.h:43
nemiver
Definition: nmv-address.h:31
nemiver::common::ObjectRef
Definition: nmv-safe-ptr-utils.h:45
nemiver::common::DynamicModule::Config::library_name
UString library_name
Definition: nmv-dynamic-module.h:97
nemiver::common::DynamicModule::Loader::get_dynamic_module_manager
DynamicModuleManager * get_dynamic_module_manager()
THROW
#define THROW(a_reason)
Definition: nmv-exception.h:99
nmv-ustring.h
NEMIVER_API
#define NEMIVER_API
Definition: nmv-api-macros.h:53
nemiver::common::DynModIface::get_dynamic_module
DynamicModule & get_dynamic_module() const
Definition: nmv-dynamic-module.h:242
nmv-api-macros.h
nemiver::common::DynamicModule::get_name
const UString & get_name() const
gets the (short) name of this dynmod
nemiver::common::DynamicModule
The base class for loadable modules.
Definition: nmv-dynamic-module.h:76
nemiver_common_create_dynamic_module_instance
bool nemiver_common_create_dynamic_module_instance(void **a_new_instance)
the factory of the DynamicModule.
nemiver::common::UString
Definition: nmv-ustring.h:45
nemiver::common::DynamicModule::lookup_interface
virtual bool lookup_interface(const std::string &a_iface_name, DynModIfaceSafePtr &a_iface)=0
lookup the interface of a service object
nemiver::common::DynModIface
Definition: nmv-dynamic-module.h:220
nemiver::common::Object::operator=
Object & operator=(Object const &)
nemiver::common::DynModIface::DynModIface
DynModIface(DynamicModuleSafePtr &a_dynmod)
Definition: nmv-dynamic-module.h:230
nemiver::common::ModuleRegistry
Definition: nmv-dynamic-module.h:249
nemiver::common::Object::m_priv
SafePtr< ObjectPriv > m_priv
Definition: nmv-object.h:47
nemiver::common::DynamicModule::ConfigSafePtr
SafePtr< Config, ObjectRef, ObjectUnref > ConfigSafePtr
Definition: nmv-dynamic-module.h:101
nemiver::common::DynamicModule::Info::module_description
UString module_description
Definition: nmv-dynamic-module.h:82
nemiver::common::DynamicModule::Info
Definition: nmv-dynamic-module.h:80
nemiver::common::DynModIface::DynModIface
DynModIface(DynamicModule *a_dynmod)
Definition: nmv-dynamic-module.h:236
nemiver::common::DynamicModule::Config::custom_library_search_paths
std::vector< UString > custom_library_search_paths
Definition: nmv-dynamic-module.h:96
nemiver::common::DynamicModule::Info::module_version
UString module_version
Definition: nmv-dynamic-module.h:83
nemiver::common::DynamicModule::do_init
virtual void do_init()=0
module init routinr
nemiver::common::ObjectUnref
Definition: nmv-safe-ptr-utils.h:55
nemiver::common::DynamicModuleManager
Definition: nmv-dynamic-module.h:265
nemiver::common::DynamicModule::Loader
Definition: nmv-dynamic-module.h:103
nmv-object.h
nemiver::common::DynamicModule::LoaderSafePtr
SafePtr< Loader, ObjectRef, ObjectUnref > LoaderSafePtr
Definition: nmv-dynamic-module.h:136
nemiver::common::DynamicModuleManager::load_iface
SafePtr< T, ObjectRef, ObjectUnref > load_iface(const UString &a_module_name, const UString &a_iface_name, DynamicModule::Loader &a_loader, DynamicModuleSafePtr &a_dynmod)
Definition: nmv-dynamic-module.h:325
nemiver::common::SafePtr
Definition: nmv-safe-ptr.h:71
nemiver::common::DynamicModule::get_module_loader
Loader * get_module_loader()
get the module loader class
THROW_IF_FAIL
#define THROW_IF_FAIL(a_cond)
Definition: nmv-exception.h:65
nmv-exception.h
nemiver::common::DynamicModule::Config::~Config
virtual ~Config()
Definition: nmv-dynamic-module.h:98
nemiver::common::env::do_init
void do_init()
common
Definition: nmv-proc-list-dialog.h:32
nemiver::common::DynamicModule::Info::Info
Info(const UString &a_name, const UString &a_desc, const UString &a_version)
Definition: nmv-dynamic-module.h:85
nemiver::common::DynamicModule::Info::module_name
UString module_name
Definition: nmv-dynamic-module.h:81
nemiver::common::load_iface_using_context
SafePtr< T, ObjectRef, ObjectUnref > load_iface_using_context(DynamicModule &a_dynmod, const UString &a_iface_name)
Definition: nmv-dynamic-module.h:419