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 + -
显示快捷键?