PluginInstance.cpp
Go to the documentation of this file.
00001 /*********************************************************************
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Copyright (c) 2013, Institute for Artificial Intelligence,
00005  *  Universität Bremen.
00006  *  All rights reserved.
00007  *
00008  *  Redistribution and use in source and binary forms, with or without
00009  *  modification, are permitted provided that the following conditions
00010  *  are met:
00011  *
00012  *   * Redistributions of source code must retain the above copyright
00013  *     notice, this list of conditions and the following disclaimer.
00014  *   * Redistributions in binary form must reproduce the above
00015  *     copyright notice, this list of conditions and the following
00016  *     disclaimer in the documentation and/or other materials provided
00017  *     with the distribution.
00018  *   * Neither the name of the Institute for Artificial Intelligence,
00019  *     Universität Bremen, nor the names of its contributors may be
00020  *     used to endorse or promote products derived from this software
00021  *     without specific prior written permission.
00022  *
00023  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00024  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00025  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00026  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00027  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00028  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00029  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00030  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00031  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00032  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00033  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00034  *  POSSIBILITY OF SUCH DAMAGE.
00035  *********************************************************************/
00036 
00040 #include <PluginInstance.h>
00041 
00042 
00043 namespace beliefstate {
00044   PluginInstance::PluginInstance() {
00045     m_strName = "";
00046     m_vdLibHandle = NULL;
00047     m_piInstance = NULL;
00048     m_thrdPluginCycle = NULL;
00049     m_bRunCycle = true;
00050     m_resCycleResult = defaultResult();
00051     
00052     this->setMessagePrefixLabel("plugin-instance");
00053   }
00054   
00055   PluginInstance::~PluginInstance() {
00056   }
00057   
00058   Result PluginInstance::loadPluginLibrary(std::string strFilepath) {
00059     Result resLoad = defaultResult();
00060     
00061     std::fstream fsFile;
00062     fsFile.open(strFilepath.c_str(), std::fstream::in);
00063     
00064     if(fsFile.is_open()) {
00065       fsFile.close();
00066       
00067       m_vdLibHandle = dlopen(strFilepath.c_str(), RTLD_LAZY);
00068       if(m_vdLibHandle) {
00069         plugins::Plugin* (*createInstance)();
00070         createInstance = (plugins::Plugin* (*)())dlsym(m_vdLibHandle, "createInstance");
00071         m_piInstance = (plugins::Plugin*)createInstance();
00072         
00073         m_strName = strFilepath;
00074         
00075         // Remove path
00076         const size_t last_slash_idx = m_strName.find_last_of("\\/");
00077         if(std::string::npos != last_slash_idx) {
00078           m_strName.erase(0, last_slash_idx + 1);
00079         }
00080         
00081         // Remove extension
00082         const size_t period_idx = m_strName.rfind('.');
00083         if(std::string::npos != period_idx) {
00084           m_strName.erase(period_idx);
00085         }
00086         
00087         // Remove plugin prefix
00088         std::string strPrefix = "libbs_plugin_";
00089         m_strName = m_strName.substr(strPrefix.size());
00090         
00091         std::string strVersionString = m_piInstance->pluginVersion();
00092         
00093         this->info("Loaded plugin '" + m_strName + "'" + (strVersionString == "" ? "" : " (version: " + strVersionString + ")"));
00094         m_piInstance->setPluginName(m_strName);
00095       } else {
00096         resLoad.riResultIdentifier = RI_PLUGIN_LOADING_FAILED;
00097         resLoad.bSuccess = false;
00098         resLoad.strErrorMessage = "Failed to load library `" + strFilepath + "'.";
00099         this->fail("Could not open shared library: " + string(dlerror()));
00100       }
00101     } else {
00102       resLoad.riResultIdentifier = RI_FILE_NOT_FOUND;
00103       resLoad.bSuccess = false;
00104       resLoad.strErrorMessage = "File `" + strFilepath + "' could not be found.";
00105     }
00106     
00107     return resLoad;
00108   }
00109   
00110   Result PluginInstance::init(int argc, char** argv) {
00111     Result resInit = m_piInstance->init(argc, argv);
00112     
00113     if(resInit.bSuccess) {
00114       this->success("Initialized plugin '" + m_strName + "'");
00115     } else {
00116       this->fail("Failed to initialize plugin '" + m_strName + "'.");
00117     }
00118     
00119     return resInit;
00120   }
00121   
00122   void PluginInstance::setDevelopmentPlugin(bool bDevelopmentPlugin) {
00123     if(m_vdLibHandle) {
00124       m_piInstance->setDevelopmentPlugin(bDevelopmentPlugin);
00125     }
00126   }
00127   
00128   bool PluginInstance::developmentPlugin() {
00129     if(m_vdLibHandle) {
00130       return m_piInstance->developmentPlugin();
00131     }
00132     
00133     return false;
00134   }
00135   
00136   void PluginInstance::unload() {
00137     if(m_vdLibHandle) {
00138       m_piInstance->deinit();
00139       
00140       void (*destroyInstance)(plugins::Plugin*);
00141       destroyInstance = (void (*)(plugins::Plugin*))dlsym(m_vdLibHandle, "destroyInstance");
00142       destroyInstance(m_piInstance);
00143       dlclose(m_vdLibHandle);
00144       
00145       this->info("Unloaded plugin '" + m_strName + "'");
00146     }
00147   }
00148   
00149   int PluginInstance::pluginID() {
00150     return m_piInstance->pluginID();
00151   }
00152   
00153   Result PluginInstance::cycle() {
00154     if(m_thrdPluginCycle == NULL) {
00155       m_thrdPluginCycle = new std::thread(&PluginInstance::spinCycle, this);
00156     }
00157     
00158     return this->currentResult();
00159   }
00160   
00161   void PluginInstance::spinCycle() {
00162     while(m_bRunCycle) {
00163       Result resCycle = m_piInstance->cycle();
00164       
00165       m_mtxCycleResults.lock();
00166       for(Event evCurrent : resCycle.lstEvents) {
00167         m_resCycleResult.lstEvents.push_back(evCurrent);
00168       }
00169       resCycle.lstEvents.clear();
00170       
00171       for(ServiceEvent seCurrent : resCycle.lstServiceEvents) {
00172         m_resCycleResult.lstServiceEvents.push_back(seCurrent);
00173       }
00174       resCycle.lstServiceEvents.clear();
00175       
00176       for(StatusMessage smCurrent : resCycle.lstStatusMessages) {
00177         m_resCycleResult.lstStatusMessages.push_back(smCurrent);
00178       }
00179       // TODO(winkler): Maybe there is a `clear` missing here. Check this.
00180       
00181       m_mtxCycleResults.unlock();
00182       
00183       usleep(10);
00184     }
00185   }
00186   
00187   std::list<std::string> PluginInstance::dependencies() {
00188     return m_piInstance->dependencies();
00189   }
00190   
00191   bool PluginInstance::subscribedToEvent(std::string strEventName) {
00192     return m_piInstance->subscribedToEvent(strEventName);
00193   }
00194   
00195   void PluginInstance::consumeEvent(Event evEvent) {
00196     m_piInstance->consumeEvent(evEvent);
00197   }
00198   
00199   bool PluginInstance::offersService(std::string strServiceName) {
00200     return m_piInstance->offersService(strServiceName);
00201   }
00202   
00203   Event PluginInstance::consumeServiceEvent(ServiceEvent seServiceEvent) {
00204     return m_piInstance->consumeServiceEvent(seServiceEvent);
00205   }
00206   
00207   std::string PluginInstance::name() {
00208     return m_strName;
00209   }
00210   
00211   Result PluginInstance::currentResult() {
00212     Result resReturn = defaultResult();
00213     
00214     if(m_mtxCycleResults.try_lock()) {
00215       resReturn = m_resCycleResult;
00216       m_resCycleResult = defaultResult();
00217       m_mtxCycleResults.unlock();
00218     }
00219     
00220     return resReturn;
00221   }
00222   
00223   void PluginInstance::setRunning(bool bRunCycle) {
00224     m_bRunCycle = bRunCycle;
00225     
00226     m_piInstance->setRunning(bRunCycle);
00227   }
00228   
00229   void PluginInstance::waitForJoin() {
00230     m_thrdPluginCycle->join();
00231     delete m_thrdPluginCycle;
00232   }
00233 }


beliefstate
Author(s): Jan Winkler
autogenerated on Sun Oct 5 2014 22:30:15