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/internal/instance_factory.h>
25 #include <blackboard/exceptions.h>
26 
27 #include <interface/interface.h>
28 
29 #include <utils/system/dynamic_module/module_manager.h>
30 #include <utils/system/dynamic_module/module.h>
31 
32 #include <cstdlib>
33 #include <cstring>
34 
35 namespace fawkes {
36 
37 /** @class BlackBoardInstanceFactory <blackboard/internal/instance_factory.h>
38  * BlackBoard instance factory.
39  * This class is used to interact with the interface shared object to create
40  * and delete interface instances.
41  *
42  * @author Tim Niemueller
43  */
44 
45 
46 /** Constructor.*/
48 {
49  __mm = new ModuleManager(IFACEDIR);
50 }
51 
52 
53 /** Destructor */
55 {
56  delete __mm;
57 }
58 
59 
60 /** Creates a new interface instance.
61  * This method will look in the for the appropriate library in LIBDIR/interfaces
62  * and then use the factory function for the interface of the given type. If
63  * this was found a new instance of the interface is returned.
64  * @param type type of the interface
65  * @param identifier identifier of the interface
66  * @return a new instance of the requested interface type
67  * @exception BlackBoardInterfaceNotFoundException thrown if the factory function
68  * for the given interface type could not be found
69  */
70 Interface *
71 BlackBoardInstanceFactory::new_interface_instance(const char *type, const char *identifier)
72 {
73  if (strlen(identifier) == 0) {
74  throw Exception("Interface ID may not be empty");
75  }
76  if (strlen(type) == 0) {
77  throw Exception("Interface type may not be empty");
78  }
79  if (strlen(type) > __INTERFACE_TYPE_SIZE) {
80  throw Exception("Interface type '%s' too long, maximum length is %zu",
81  type, __INTERFACE_TYPE_SIZE);
82  }
83  if (strlen(identifier) > __INTERFACE_ID_SIZE) {
84  throw Exception("Interface ID '%s' too long, maximum length is %zu",
85  type, __INTERFACE_ID_SIZE);
86  }
87 
88  Module *mod = NULL;
89  std::string filename = std::string("lib") + type + "." + __mm->get_module_file_extension();
90  try {
91  mod = __mm->open_module(filename.c_str());
92  } catch (Exception &e) {
93  throw BlackBoardInterfaceNotFoundException(type, " Module file not found.");
94  }
95 
96  if ( ! mod->has_symbol("interface_factory") ) {
97  throw BlackBoardInterfaceNotFoundException(type, " Generator function not found.");
98  }
99 
100  InterfaceFactoryFunc iff = (InterfaceFactoryFunc)mod->get_symbol("interface_factory");
101 
102  Interface *iface = iff();
103  iface->set_type_id(type, identifier);
104 
105  return iface;
106 }
107 
108 
109 /** Destroy an interface instance.
110  * The destroyer function for the given interface is called to destroy the given
111  * interface instance.
112  * @param interface to destroy
113  * @exception BlackBoardInterfaceNotFoundException thrown if the destroyer function
114  * for the given interface could not be found. The interface will not be freed.
115  */
116 void
118 {
119  std::string filename = std::string("lib") + interface->__type + "." + __mm->get_module_file_extension();
120  Module *mod = __mm->get_module(filename.c_str());
121 
122  if ( ! mod) {
123  throw BlackBoardInterfaceNotFoundException(interface->__type, " Interface module not opened.");
124  }
125 
126  if ( ! mod->has_symbol("interface_destroy") ) {
127  throw BlackBoardInterfaceNotFoundException(interface->__type, " Destroyer function not found.");
128  }
129 
130  InterfaceDestroyFunc idf = (InterfaceDestroyFunc)mod->get_symbol("interface_destroy");
131  idf(interface);
132 
133  mod->unref();
134  __mm->close_module(mod);
135 }
136 
137 } // end namespace fawkes
virtual void unref()
Decrease the reference count of this module.
Definition: module.cpp:179
Interface * new_interface_instance(const char *type, const char *identifier)
Creates a new interface instance.
virtual void close_module(Module *module)
Close a module by Module instance.
Fawkes library namespace.
Base class for all Fawkes BlackBoard interfaces.
Definition: interface.h:79
Dynamic module loader for Linux, FreeBSD, and MacOS X.
Definition: module.h:40
Base class for exceptions in Fawkes.
Definition: exception.h:36
void delete_interface_instance(Interface *interface)
Destroy an interface instance.
void(* InterfaceDestroyFunc)(Interface *interface)
Interface destructor function for the shared library.
Definition: interface.h:324
virtual const char * get_module_file_extension()
Get the file extension for the current module type.
Thrown if no definition of interface or interface generator found.
Definition: exceptions.h:91
virtual Module * open_module(const char *filename)
Open a module.
virtual void * get_symbol(const char *symbol_name)
Get a symbol from the module.
Definition: module.cpp:253
Interface *(* InterfaceFactoryFunc)(void)
Interface generator function for the shared library Do not use directly.
Definition: interface.h:329
Dynamic module manager.
virtual Module * get_module(const char *filename)
Get a module if opened.
virtual bool has_symbol(const char *symbol_name)
Check if the module has the given symbol.
Definition: module.cpp:230