plugin_registry.cpp
来自「ncbi源码」· C++ 代码 · 共 748 行 · 第 1/2 页
CPP
748 行
/* * =========================================================================== * PRODUCTION $Log: plugin_registry.cpp,v $ * PRODUCTION Revision 1000.8 2004/06/01 20:44:30 gouriano * PRODUCTION PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.45 * PRODUCTION * =========================================================================== *//* $Id: plugin_registry.cpp,v 1000.8 2004/06/01 20:44:30 gouriano Exp $ * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government have not placed any restriction on its use or reproduction. * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * Please cite the author in any work or product based on this material. * * =========================================================================== * * Authors: Mike DiCuccio * * File Description: * */#include <ncbi_pch.hpp>#include <corelib/ncbidll.hpp>#include <corelib/ncbifile.hpp>#include <corelib/ncbimtx.hpp>#include <gui/core/algo_factory.hpp>#include <gui/core/obj_convert.hpp>#include <gui/core/plugin_exception.hpp>#include <gui/core/plugin_factory.hpp>#include <gui/core/plugin_registry.hpp>#include <gui/core/plugin_utils.hpp>#include <gui/core/version.hpp>#include <gui/plugin/PluginCache.hpp>#include <gui/plugin/PluginInfo.hpp>#include <gui/plugin/PluginLibInfo.hpp>#include <gui/utils/message_box.hpp>#include <serial/objostr.hpp>#include <serial/objistr.hpp>#include <serial/serial.hpp>#include "plugin_handle_impl.hpp"#include <algorithm>BEGIN_NCBI_SCOPEUSING_SCOPE(objects);// typedef for our handle types (internal use only)typedef CRef<CPluginHandle_Impl> TPluginImpl;// functor for sorting plugin handles by contentstruct SPluginLessByClassName { bool operator() (const TPluginImpl& h0, const TPluginImpl& h1) const { return (h0->GetClassName() < h1->GetClassName()); }};// functor for sorting plugin handles by menu namestruct SPluginLessByMenuItem { bool operator()(const TPluginImpl& h1, const TPluginImpl& h2) const { // sort first by menu item if (h1->GetMenuItem() < h2->GetMenuItem()) { return true; } if (h1->GetMenuItem() > h2->GetMenuItem()) { return false; } // we always pass empty menu items - their sort order is unimportant if (h1->GetMenuItem().empty()) { return true; } // sort next by class name if (h1->GetClassName() < h2->GetClassName()) { return true; } if (h1->GetClassName() > h2->GetClassName()) { return false; } // sort finally by class name return (h1->GetCommand() < h2->GetCommand()); }};typedef set<TPluginImpl, SPluginLessByMenuItem> TPluginRegistry;// our plugin registrystatic TPluginRegistry s_PluginRegistry;// mutex protecting access to the registryDEFINE_STATIC_MUTEX(s_PluginRegistryMutex);//// read the plugin cache in the specified directory and add its contents to the// current registry//void CPluginRegistry::InitPlugins(const string& path){ string cache_file(path + CDirEntry::GetPathSeparator() + "plugin-cache"); {{ // first, check to see if the plugin cache exists CFile file(cache_file); if ( !file.Exists() ) { LOG_POST(Info << "CPluginRegistry::InitPlugins(): " "no plugin cache found at " << cache_file); return; } }} // try reading in ASN.1 text format try { auto_ptr<CObjectIStream> is (CObjectIStream::Open(eSerial_AsnText, cache_file)); CRef<CPluginCache> cache(new CPluginCache()); *is >> *cache; LOG_POST(Info << "CPluginRegistry::InitPlugins(): plugin cache found in " << path); x_InitPlugins(path, *cache); return; } catch (CException& _DEBUG_ARG(e)) { _TRACE("read of ASN.1 text plugin cache in " << path << " failed: " << e.what()); } // on error, try reading in ASN.1 binary format try { auto_ptr<CObjectIStream> is (CObjectIStream::Open(eSerial_AsnBinary, cache_file)); CRef<CPluginCache> cache(new CPluginCache()); *is >> *cache; LOG_POST(Info << "CPluginRegistry::InitPlugins(): plugin cache found in " << path); x_InitPlugins(path, *cache); return; } catch (CException& _DEBUG_ARG(e)) { _TRACE("read of ASN.1 binary plugin cache in " << path << " failed: " << e.what()); } // if not, try reading in XML try { auto_ptr<CObjectIStream> is (CObjectIStream::Open(eSerial_Xml, cache_file)); CRef<CPluginCache> cache(new CPluginCache()); *is >> *cache; LOG_POST(Info << "CPluginRegistry::InitPlugins(): plugin cache found in " << path); x_InitPlugins(path, *cache); return; } catch (CException& _DEBUG_ARG(e)) { _TRACE("read of XML plugin cache in " << path << " failed: " << e.what()); } // log an error and continue... LOG_POST(Error << "CPluginRegistry: No plugins found in directory " << path);}void CPluginRegistry::x_InitPlugins(const string& path, CPluginCache& cache){ CMutexGuard LOCK(s_PluginRegistryMutex); // // now, process our plugin info objects // TPlugins plugins; int plug_count = s_PluginRegistry.size(); NON_CONST_ITERATE (CPluginCache::Tdata, iter, cache.Set()) { CPluginLibInfo& libinfo = **iter; string lib_path = (path + CDirEntry::GetPathSeparator() + libinfo.GetLibrary()); libinfo.SetLibrary(lib_path); CPluginHandle handle = AddPlugin(libinfo, eNonPersistent); plugins.push_back(handle); } // // ping any autoload commands now // NON_CONST_ITERATE (TPlugins, iter, plugins) { CPluginHandle handle = *iter; if ( !handle.GetInfo().CanGetAutorun() || !handle.GetInfo().GetAutorun() ) { continue; } _TRACE("autoloading " << handle.GetInfo().GetClass_name()); const CPluginInfo::TCommands& cmds = handle.GetInfo().GetCommands(); try { switch (cmds.Which()) { case CPluginCommandSet::e_Algo: ITERATE (CPluginInfo::TCommands::TAlgo, cmd_iter, cmds.GetAlgo()) { CRef<CPluginMessage> msg(new CPluginMessage); CPluginRequest& request = msg->SetRequest(); handle.FillDefaults ((EAlgoCommand)(*cmd_iter)->GetCommand(), request.SetAlgo()); handle.Execute(*msg); } break; case CPluginCommandSet::e_View: break; case CPluginCommandSet::e_Data: break; default: break; } } catch (CException& e) { LOG_POST(Error << "Error running autoload commands: " << e.what()); }#ifndef _DEBUG catch (...) { LOG_POST(Error << "Unknown error running autoload commands"); }#endif } LOG_POST(Info << " registered " << s_PluginRegistry.size() - plug_count << " plugins in path " << path);}void CPluginRegistry::Clear(void){ CMutexGuard LOCK(s_PluginRegistryMutex); s_PluginRegistry.clear();}void CPluginRegistry::RegisterPlugin(CRef<CPluginInfo> info, CPluginFactoryBase *factory){ CMutexGuard LOCK(s_PluginRegistryMutex); // build a PluginLibInfo from info CRef<CPluginLibInfo> libinfo(new CPluginLibInfo); libinfo->SetInfo(*info); string lib_path = "NONE"; libinfo->SetLibrary(lib_path); // make a plugin handle from this TPluginImpl handle(new CPluginHandle_Impl(*libinfo)); // set the factory handle->x_SetFactory(factory); // register the plugin TPluginRegistry::iterator reg_iter = s_PluginRegistry.find(handle); if (reg_iter != s_PluginRegistry.end()) { LOG_POST(Warning << "Overriding " << libinfo->GetInfo().GetClass_name() << " with equivalent plugin from " << libinfo->GetLibrary()); s_PluginRegistry.erase(reg_iter); } s_PluginRegistry.insert(handle);}CPluginHandle CPluginRegistry::AddPlugin(CPluginLibInfo& libinfo, EUserPlugin mode){ TPluginImpl impl(new CPluginHandle_Impl(libinfo)); TPluginRegistry::iterator reg_iter = s_PluginRegistry.find(impl); if (reg_iter != s_PluginRegistry.end()) { LOG_POST(Warning << "Overriding " << libinfo.GetInfo().GetClass_name() << " with equivalent plugin from " << libinfo.GetLibrary()); s_PluginRegistry.erase(reg_iter); } s_PluginRegistry.insert(impl); switch (mode) { case ePersistent: break; default: case eNonPersistent: break; } return impl->GetHandle();}template <class Command, class BufferObj>CPluginRegistry::TPluginss_GetPlugins(const TPluginRegistry& registry, Command cmd, const BufferObj* obj, int flags){ // Some compilers (*cough*WorkShop*cough*) don't allow templates // to access statics, so we must use registry rather than // s_PluginRegistry here. CConvertCache cache; CPluginRegistry::TPlugins plugins; ITERATE (TPluginRegistry, iter, registry) { const CPluginHandle_Impl& handle = **iter; CPluginCommand args; if ( !handle.IsEnabled() ) { continue; } if ( (flags & CPluginRegistry::fHidden) == 0 && handle.GetMenuItem().empty()) { continue; } if ( !handle.FillDefaults(cmd, args) ) { continue; } /** FIXME: this causes too many problems, and will be temporarily disabled it is *very* time-consuming on large records if (CPluginUtils::CanFitArgs(args.SetArgs(), *obj, &cache)) { plugins.push_back((*iter)->GetHandle()); }
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?