Files
ThirdParty-6/ParaView-5.0.1/ParaViewCore/ServerManager/Core/vtkSMPluginManager.cxx

286 lines
9.1 KiB
C++

/*=========================================================================
Program: ParaView
Module: $RCSfile$
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkSMPluginManager.h"
#include "vtkCommand.h"
#include "vtkObjectFactory.h"
#include "vtkPVPluginLoader.h"
#include "vtkPVPluginsInformation.h"
#include "vtkPVPluginTracker.h"
#include "vtkSmartPointer.h"
#include "vtkSMPluginLoaderProxy.h"
#include "vtkSMPropertyHelper.h"
#include "vtkSMProxyDefinitionManager.h"
#include "vtkSMProxyManager.h"
#include "vtkSMSession.h"
#include "vtkSMSessionProxyManager.h"
#include "vtkSMTrace.h"
#include "vtkWeakPointer.h"
#include <assert.h>
#include <map>
class vtkSMPluginManager::vtkInternals
{
public:
typedef std::map<vtkSMSession*,
vtkSmartPointer<vtkPVPluginsInformation> > RemoteInfoMapType;
RemoteInfoMapType RemoteInformations;
};
namespace
{
class vtkFlagStateUpdated
{
bool Prev;
bool &Flag;
public:
vtkFlagStateUpdated(bool &flag, bool new_val=true) : Prev(flag), Flag(flag)
{
this->Flag = new_val;
}
~vtkFlagStateUpdated()
{
this->Flag = this->Prev;
}
private:
vtkFlagStateUpdated(const vtkFlagStateUpdated&); // Not implemented
void operator=(const vtkFlagStateUpdated&); // Not implemented
};
}
vtkStandardNewMacro(vtkSMPluginManager);
//----------------------------------------------------------------------------
vtkSMPluginManager::vtkSMPluginManager()
{
this->Internals = new vtkInternals();
this->InLoadPlugin = false;
// Setup and update local plugins information.
this->LocalInformation = vtkPVPluginsInformation::New();
this->LocalInformation->CopyFromObject(NULL);
// When a plugin is register with the local tracker (either at buildtime or
// at runtime, RegisterEvent is fired. We ensure that the PluginLoadedEvent
// get fired, especially for plugins brought in a buildtime.
vtkPVPluginTracker* tracker = vtkPVPluginTracker::GetInstance();
tracker->AddObserver(vtkCommand::RegisterEvent,
this, &vtkSMPluginManager::OnPluginRegistered);
}
//----------------------------------------------------------------------------
vtkSMPluginManager::~vtkSMPluginManager()
{
delete this->Internals;
this->Internals = NULL;
this->LocalInformation->Delete();
this->LocalInformation = NULL;
}
//----------------------------------------------------------------------------
void vtkSMPluginManager::RegisterSession(vtkSMSession* session)
{
assert(session != NULL);
if (this->Internals->RemoteInformations.find(session) !=
this->Internals->RemoteInformations.end())
{
vtkWarningMacro("Session already registered!!!");
}
else
{
vtkPVPluginsInformation* remoteInfo = vtkPVPluginsInformation::New();
this->Internals->RemoteInformations[session].TakeReference(remoteInfo);
session->GatherInformation(vtkPVSession::DATA_SERVER_ROOT, remoteInfo, 0);
}
// Also update the local information. This is generally unnecessary, but for
// statically linked in plugins, this provides a cleaner opportunity to bring
// in what's linked in.
// we use Update so that any auto-load state changes done in
// this->LocalInformation are preserved.
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
temp->CopyFromObject(NULL);
this->LocalInformation->Update(temp);
temp->Delete();
}
//----------------------------------------------------------------------------
void vtkSMPluginManager::UnRegisterSession(vtkSMSession* session)
{
this->Internals->RemoteInformations.erase(session);
}
//----------------------------------------------------------------------------
vtkPVPluginsInformation* vtkSMPluginManager::GetRemoteInformation(
vtkSMSession* session)
{
return (session)? this->Internals->RemoteInformations[session] : NULL;
}
//----------------------------------------------------------------------------
bool vtkSMPluginManager::LoadLocalPlugin(const char* filename)
{
SM_SCOPED_TRACE(CallFunction)
.arg("LoadPlugin")
.arg(filename)
.arg("remote", false);
// .arg("ns=globals()"); <== FIXME
vtkFlagStateUpdated stateUpdater(this->InLoadPlugin);
vtkPVPluginLoader* loader = vtkPVPluginLoader::New();
bool ret_val = loader->LoadPlugin(filename);
loader->Delete();
if (ret_val)
{
// Update local-plugin information.
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
temp->CopyFromObject(NULL);
// we use Update so that any auto-load state changes done in
// this->LocalInformation are preserved.
this->LocalInformation->Update(temp);
temp->Delete();
this->InvokeEvent(vtkSMPluginManager::PluginLoadedEvent);
this->InvokeEvent(vtkSMPluginManager::LocalPluginLoadedEvent,(void*) filename);
}
// We don't report the error here if ret_val == false since vtkPVPluginLoader
// already reports those errors using vtkErrorMacro.
return ret_val;
}
//----------------------------------------------------------------------------
bool vtkSMPluginManager::LoadRemotePlugin(const char* filename,
vtkSMSession* session)
{
assert("Session cannot be NULL" && session != NULL);
SM_SCOPED_TRACE(CallFunction)
.arg("LoadPlugin")
.arg(filename)
.arg("remote", true);
// .arg("ns=globals()"); <== FIXME
vtkFlagStateUpdated stateUpdater(this->InLoadPlugin);
vtkSMSessionProxyManager* pxm = session->GetSessionProxyManager();
vtkSMPluginLoaderProxy* proxy =
vtkSMPluginLoaderProxy::SafeDownCast(pxm->NewProxy("misc", "PluginLoader"));
proxy->UpdateVTKObjects();
bool status = proxy->LoadPlugin(filename);
if (!status)
{
vtkErrorMacro("Plugin load failed: " <<
vtkSMPropertyHelper(proxy, "ErrorString").GetAsString());
}
proxy->Delete();
// Refresh definitions since those may have changed.
pxm->GetProxyDefinitionManager()->SynchronizeDefinitions();
if (status)
{
// Refresh the remote plugin information
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
session->GatherInformation(
vtkPVSession::DATA_SERVER_ROOT, temp, 0);
this->Internals->RemoteInformations[session]->Update(temp);
temp->Delete();
this->InvokeEvent(vtkSMPluginManager::PluginLoadedEvent);
this->InvokeEvent(vtkSMPluginManager::RemotePluginLoadedEvent,(void*) filename);
}
return status;
}
//----------------------------------------------------------------------------
void vtkSMPluginManager::LoadPluginConfigurationXMLFromString(
const char* xmlcontents, vtkSMSession* session, bool remote)
{
vtkFlagStateUpdated stateUpdater(this->InLoadPlugin);
if (remote)
{
assert("Session should already be set" && (session != NULL));
vtkSMSessionProxyManager* pxm = session->GetSessionProxyManager();
vtkSMPluginLoaderProxy* proxy =
vtkSMPluginLoaderProxy::SafeDownCast(pxm->NewProxy("misc", "PluginLoader"));
proxy->UpdateVTKObjects();
proxy->LoadPluginConfigurationXMLFromString(xmlcontents);
proxy->Delete();
// Refresh definitions since those may have changed.
pxm->GetProxyDefinitionManager()->SynchronizeDefinitions();
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
session->GatherInformation(vtkPVSession::DATA_SERVER_ROOT, temp, 0);
this->Internals->RemoteInformations[session]->Update(temp);
temp->Delete();
}
else
{
vtkPVPluginTracker::GetInstance()->LoadPluginConfigurationXMLFromString(
xmlcontents);
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
temp->CopyFromObject(NULL);
this->LocalInformation->Update(temp);
temp->Delete();
}
this->InvokeEvent(vtkSMPluginManager::PluginLoadedEvent);
}
//----------------------------------------------------------------------------
void vtkSMPluginManager::OnPluginRegistered()
{
if (this->InLoadPlugin)
{
return;
}
// Update local-plugin information.
vtkPVPluginsInformation* temp = vtkPVPluginsInformation::New();
temp->CopyFromObject(NULL);
// we use Update so that any auto-load state changes done in
// this->LocalInformation are preserved.
this->LocalInformation->Update(temp);
temp->Delete();
this->InvokeEvent(vtkSMPluginManager::PluginLoadedEvent);
}
//----------------------------------------------------------------------------
const char* vtkSMPluginManager::GetLocalPluginSearchPaths()
{
return this->LocalInformation->GetSearchPaths();
}
//----------------------------------------------------------------------------
const char* vtkSMPluginManager::GetRemotePluginSearchPaths(vtkSMSession* session)
{
return this->Internals->RemoteInformations[session]->GetSearchPaths();
}
//----------------------------------------------------------------------------
void vtkSMPluginManager::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}