Fawkes API  Fawkes Development Version
instance_factory.cpp
1 
2 /***************************************************************************
3  * instance_factory.cpp - BlackBoard interface instance factory
4  *
5  * Created: Mon Mar 03 18:01:53 2008
6  * Copyright 2006-2011 Tim Niemueller [www.niemueller.de]
7  *
8  ****************************************************************************/
9 
10 /* This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version. A runtime exception applies to
14  * this software (see LICENSE.GPL_WRE file mentioned below for details).
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19  * GNU Library General Public License for more details.
20  *
21  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
22  */
23 
24 #include <blackboard/exceptions.h>
25 #include <blackboard/internal/instance_factory.h>
26 #include <interface/interface.h>
27 #include <utils/system/dynamic_module/module.h>
28 #include <utils/system/dynamic_module/module_manager.h>
29 
30 #include <cstdlib>
31 #include <cstring>
32 
33 namespace fawkes {
34 
35 /** @class BlackBoardInstanceFactory <blackboard/internal/instance_factory.h>
36  * BlackBoard instance factory.
37  * This class is used to interact with the interface shared object to create
38  * and delete interface instances.
39  *
40  * @author Tim Niemueller
41  */
42 
43 /** Constructor.*/
45 {
46  mm_ = new ModuleManager(IFACEDIR);
47 }
48 
49 /** Destructor */
51 {
52  delete mm_;
53 }
54 
55 /** Creates a new interface instance.
56  * This method will look in the for the appropriate library in LIBDIR/interfaces
57  * and then use the factory function for the interface of the given type. If
58  * this was found a new instance of the interface is returned.
59  * @param type type of the interface
60  * @param identifier identifier of the interface
61  * @return a new instance of the requested interface type
62  * @exception BlackBoardInterfaceNotFoundException thrown if the factory function
63  * for the given interface type could not be found
64  */
65 Interface *
66 BlackBoardInstanceFactory::new_interface_instance(const char *type, const char *identifier)
67 {
68  if (strlen(identifier) == 0) {
69  throw Exception("Interface ID may not be empty");
70  }
71  if (strlen(type) == 0) {
72  throw Exception("Interface type may not be empty");
73  }
74  if (strlen(type) > INTERFACE_TYPE_SIZE_) {
75  throw Exception("Interface type '%s' too long, maximum length is %zu",
76  type,
77  INTERFACE_TYPE_SIZE_);
78  }
79  if (strlen(identifier) > INTERFACE_ID_SIZE_) {
80  throw Exception("Interface ID '%s' too long, maximum length is %zu", type, INTERFACE_ID_SIZE_);
81  }
82 
83  Module * mod = NULL;
84  std::string filename = std::string("lib") + type + "." + mm_->get_module_file_extension();
85  try {
86  mod = mm_->open_module(filename.c_str());
87  } catch (Exception &e) {
88  throw BlackBoardInterfaceNotFoundException(type, " Module file not found.");
89  }
90 
91  if (!mod->has_symbol("interface_factory")) {
92  throw BlackBoardInterfaceNotFoundException(type, " Generator function not found.");
93  }
94 
95  InterfaceFactoryFunc iff = (InterfaceFactoryFunc)mod->get_symbol("interface_factory");
96 
97  Interface *iface = iff();
98  iface->set_type_id(type, identifier);
99 
100  return iface;
101 }
102 
103 /** Destroy an interface instance.
104  * The destroyer function for the given interface is called to destroy the given
105  * interface instance.
106  * @param interface to destroy
107  * @exception BlackBoardInterfaceNotFoundException thrown if the destroyer function
108  * for the given interface could not be found. The interface will not be freed.
109  */
110 void
112 {
113  std::string filename =
114  std::string("lib") + interface->type_ + "." + mm_->get_module_file_extension();
115  Module *mod = mm_->get_module(filename.c_str());
116 
117  if (!mod) {
118  throw BlackBoardInterfaceNotFoundException(interface->type_, " Interface module not opened.");
119  }
120 
121  if (!mod->has_symbol("interface_destroy")) {
122  throw BlackBoardInterfaceNotFoundException(interface->type_, " Destroyer function not found.");
123  }
124 
125  InterfaceDestroyFunc idf = (InterfaceDestroyFunc)mod->get_symbol("interface_destroy");
126  idf(interface);
127 
128  mod->unref();
129  mm_->close_module(mod);
130 }
131 
132 } // end namespace fawkes
fawkes::ModuleManager::open_module
virtual Module * open_module(const char *filename)
Open a module.
Definition: module_manager.cpp:80
fawkes::BlackBoardInterfaceNotFoundException
Thrown if no definition of interface or interface generator found.
Definition: exceptions.h:95
fawkes::Module::unref
virtual void unref()
Decrease the reference count of this module.
Definition: module.cpp:175
fawkes::Module::get_symbol
virtual void * get_symbol(const char *symbol_name)
Get a symbol from the module.
Definition: module.cpp:244
fawkes::BlackBoardInstanceFactory::delete_interface_instance
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
Definition: instance_factory.cpp:111
fawkes::InterfaceDestroyFunc
void(* InterfaceDestroyFunc)(Interface *interface)
Interface destructor function for the shared library.
Definition: interface.h:323
fawkes::Module::has_symbol
virtual bool has_symbol(const char *symbol_name)
Check if the module has the given symbol.
Definition: module.cpp:222
fawkes
Fawkes library namespace.
fawkes::Interface
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
fawkes::ModuleManager::get_module
virtual Module * get_module(const char *filename)
Get a module if opened.
Definition: module_manager.cpp:142
fawkes::BlackBoardInstanceFactory::BlackBoardInstanceFactory
BlackBoardInstanceFactory()
Constructor.
Definition: instance_factory.cpp:44
fawkes::BlackBoardInstanceFactory::new_interface_instance
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
Definition: instance_factory.cpp:66
fawkes::ModuleManager
Dynamic module manager.
Definition: module_manager.h:38
fawkes::ModuleManager::close_module
virtual void close_module(Module *module)
Close a module by Module instance.
Definition: module_manager.cpp:108
fawkes::ModuleManager::get_module_file_extension
virtual const char * get_module_file_extension()
Get the file extension for the current module type.
Definition: module_manager.cpp:170
fawkes::BlackBoardInstanceFactory::~BlackBoardInstanceFactory
~BlackBoardInstanceFactory()
Destructor.
Definition: instance_factory.cpp:50
fawkes::InterfaceFactoryFunc
Interface *(* InterfaceFactoryFunc)(void)
Interface generator function for the shared library Do not use directly.
Definition: interface.h:328
fawkes::Module
Dynamic module loader for Linux, FreeBSD, and MacOS X.
Definition: module.h:41
fawkes::Exception
Base class for exceptions in Fawkes.
Definition: exception.h:36