Fawkes API  Fawkes Development Version
instance_factory.cpp
00001  
00002 /***************************************************************************
00003  *  instance_factory.cpp - BlackBoard interface instance factory
00004  *
00005  *  Created: Mon Mar 03 18:01:53 2008
00006  *  Copyright  2006-2011  Tim Niemueller [www.niemueller.de]
00007  *
00008  ****************************************************************************/
00009 
00010 /*  This program is free software; you can redistribute it and/or modify
00011  *  it under the terms of the GNU General Public License as published by
00012  *  the Free Software Foundation; either version 2 of the License, or
00013  *  (at your option) any later version. A runtime exception applies to
00014  *  this software (see LICENSE.GPL_WRE file mentioned below for details).
00015  *
00016  *  This program is distributed in the hope that it will be useful,
00017  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00018  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019  *  GNU Library General Public License for more details.
00020  *
00021  *  Read the full text in the LICENSE.GPL_WRE file in the doc directory.
00022  */
00023 
00024 #include <blackboard/internal/instance_factory.h>
00025 #include <blackboard/exceptions.h>
00026 
00027 #include <interface/interface.h>
00028 
00029 #include <utils/system/dynamic_module/module_manager.h>
00030 #include <utils/system/dynamic_module/module.h>
00031 
00032 #include <cstdlib>
00033 #include <cstring>
00034 
00035 namespace fawkes {
00036 
00037 /** @class BlackBoardInstanceFactory <blackboard/internal/instance_factory.h>
00038  * BlackBoard instance factory.
00039  * This class is used to interact with the interface shared object to create
00040  * and delete interface instances.
00041  *
00042  * @author Tim Niemueller
00043  */
00044 
00045 
00046 /** Constructor.*/
00047 BlackBoardInstanceFactory::BlackBoardInstanceFactory()
00048 {
00049   __mm = new ModuleManager(IFACEDIR);
00050 }
00051 
00052 
00053 /** Destructor */
00054 BlackBoardInstanceFactory::~BlackBoardInstanceFactory()
00055 {
00056   delete __mm;
00057 }
00058 
00059 
00060 /** Creates a new interface instance.
00061  * This method will look in the for the appropriate library in LIBDIR/interfaces
00062  * and then use the factory function for the interface of the given type. If
00063  * this was found a new instance of the interface is returned.
00064  * @param type type of the interface
00065  * @param identifier identifier of the interface
00066  * @return a new instance of the requested interface type
00067  * @exception BlackBoardInterfaceNotFoundException thrown if the factory function
00068  * for the given interface type could not be found
00069  */
00070 Interface *
00071 BlackBoardInstanceFactory::new_interface_instance(const char *type, const char *identifier)
00072 {
00073   Module *mod = NULL;
00074   std::string filename = std::string("lib") + type + "." + __mm->get_module_file_extension();
00075   try {
00076       mod = __mm->open_module(filename.c_str());
00077   } catch (Exception &e) {
00078     throw BlackBoardInterfaceNotFoundException(type, " Module file not found.");
00079   }
00080 
00081   if ( ! mod->has_symbol("interface_factory") ) {
00082     throw BlackBoardInterfaceNotFoundException(type, " Generator function not found.");
00083   }
00084 
00085   InterfaceFactoryFunc iff = (InterfaceFactoryFunc)mod->get_symbol("interface_factory");
00086 
00087   Interface *iface = iff();
00088   iface->set_type_id(type, identifier);
00089 
00090   return iface;
00091 }
00092 
00093 
00094 /** Destroy an interface instance.
00095  * The destroyer function for the given interface is called to destroy the given
00096  * interface instance.
00097  * @param interface to destroy
00098  * @exception BlackBoardInterfaceNotFoundException thrown if the destroyer function
00099  * for the given interface could not be found. The interface will not be freed.
00100  */
00101 void
00102 BlackBoardInstanceFactory::delete_interface_instance(Interface *interface)
00103 {
00104   std::string filename = std::string("lib") + interface->__type + "." + __mm->get_module_file_extension();
00105   Module *mod = __mm->get_module(filename.c_str());
00106 
00107   if ( ! mod) {
00108     throw BlackBoardInterfaceNotFoundException(interface->__type, " Interface module not opened.");
00109   }
00110 
00111   if ( ! mod->has_symbol("interface_destroy") ) {
00112     throw BlackBoardInterfaceNotFoundException(interface->__type, " Destroyer function not found.");
00113   }
00114 
00115   InterfaceDestroyFunc idf = (InterfaceDestroyFunc)mod->get_symbol("interface_destroy");
00116   idf(interface);
00117 
00118   mod->unref();
00119   __mm->close_module(mod);
00120 }
00121 
00122 } // end namespace fawkes