Skip to content

Commit

Permalink
[SofaKernel] Implement an update mechanism on component: RequiredPlugin
Browse files Browse the repository at this point in the history
  • Loading branch information
damienmarchal committed Aug 26, 2020
1 parent b868e56 commit 6f687e1
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 16 deletions.
54 changes: 39 additions & 15 deletions SofaKernel/modules/SofaBaseUtils/RequiredPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,39 @@ RequiredPlugin::RequiredPlugin()
, d_stopAfterFirstSuffixFound( initData(&d_stopAfterFirstSuffixFound , true, "stopAfterFirstSuffixFound", "For each plugin name, stop after the first suffix that is loaded successfully"))
, d_requireOne ( initData(&d_requireOne , false, "requireOne", "Display an error message if no plugin names were successfully loaded"))
, d_requireAll ( initData(&d_requireAll , true, "requireAll", "Display an error message if any plugin names failed to be loaded"))
, d_loadedPlugins(initData(&d_loadedPlugins, "loadedPlugins", "List of the plugins that are have been loaded."))
{
this->f_printLog.setValue(true); // print log by default, to identify which pluging is responsible in case of a crash during loading

/// Add a callback to update the required plugin when its data are changed
addUpdateCallback("reloadPlugins", {&name,
&d_pluginName, &d_suffixMap, &d_stopAfterFirstNameFound, &d_stopAfterFirstSuffixFound,
&d_requireAll, &d_requireOne},
[this](const sofa::core::DataTracker&)
{
clearLoggedMessages();
/// Reload the plugins and check at least one is loaded.
if(loadPlugin())
return sofa::core::objectmodel::ComponentState::Valid;
return sofa::core::objectmodel::ComponentState::Invalid;
}, {&d_loadedPlugins});
}

void RequiredPlugin::parse(sofa::core::objectmodel::BaseObjectDescription* arg)
{
d_componentState = sofa::core::objectmodel::ComponentState::Invalid;

Inherit1::parse(arg);
loadPlugin();
if(loadPlugin())
d_componentState = sofa::core::objectmodel::ComponentState::Valid;
}

void RequiredPlugin::loadPlugin()
bool RequiredPlugin::loadPlugin()
{
/// Get a write accessor to the loadedPlugin
auto loadedPlugins = sofa::helper::getWriteOnlyAccessor(d_loadedPlugins);
loadedPlugins.clear();

sofa::helper::system::PluginManager* pluginManager = &sofa::helper::system::PluginManager::getInstance();
std::string defaultSuffix = pluginManager->getDefaultSuffix();
const helper::vector<helper::fixed_array<std::string,2> >& sMap = d_suffixMap.getValue();
Expand All @@ -80,34 +101,33 @@ void RequiredPlugin::loadPlugin()
if (suffixVec.empty())
suffixVec.push_back(defaultSuffix);

/// Copy the lost of names provided as arguments
const helper::vector<std::string>& nameVec = d_pluginName.getValue();
helper::vector<std::string> pluginsToLoad = nameVec;

/// In case the pluginName is not set we copy the provided name into the set to load.
if(!d_pluginName.isSet() && name.isSet())
{
helper::WriteOnlyAccessor<Data<helper::vector<std::string>>> pluginsName = d_pluginName ;
pluginsName.push_back(this->getName());
pluginsToLoad.push_back(this->getName());
}

const helper::vector<std::string>& nameVec = d_pluginName.getValue();
helper::vector<std::string> nameVecCopy = nameVec;

helper::vector< std::string > loaded;
helper::vector< std::string > failed;
std::ostringstream errmsg;
for (std::size_t nameIndex = 0; nameIndex < nameVecCopy.size(); ++nameIndex)
for (auto& pluginName : pluginsToLoad)
{
const std::string& name = FileSystem::cleanPath( nameVecCopy[nameIndex] ); // name is not necessarily a path
const std::string& name = FileSystem::cleanPath( pluginName ); // name is not necessarily a path
bool nameLoaded = false;
for (std::size_t suffixIndex = 0; suffixIndex < suffixVec.size(); ++suffixIndex)
for (auto& suffix : suffixVec)
{
const std::string& suffix = suffixVec[suffixIndex];
if ( pluginManager->pluginIsLoaded(name) )
{
loadedPlugins.push_back(name);
nameLoaded = true;
if (d_stopAfterFirstSuffixFound.getValue()) break;
}
else if ( pluginManager->loadPlugin(name, suffix, true, true, &errmsg) )
{
loaded.push_back(name);
loadedPlugins.push_back(name);
nameLoaded = true;
if (d_stopAfterFirstSuffixFound.getValue()) break;
}
Expand All @@ -121,20 +141,24 @@ void RequiredPlugin::loadPlugin()
break;
}
}

bool hasFailed=false;
if (!failed.empty())
{
if ((d_requireAll.getValue() || (d_requireOne.getValue() && loaded.empty())))
if ((d_requireAll.getValue() || (d_requireOne.getValue() && loadedPlugins.empty())))
{
hasFailed = true;
msg_error() << errmsg.str() << msgendl
<< "Failed to load: " << failed ;
}
else
{
msg_warning() << errmsg.str() << msgendl
<< "Failed to load optional: " << failed;
<< "Unable to load optional: " << failed;
}
}
pluginManager->init();
return !hasFailed;
}

} // namespace misc
Expand Down
4 changes: 3 additions & 1 deletion SofaKernel/modules/SofaBaseUtils/RequiredPlugin.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ class SOFA_BASE_UTILS_API RequiredPlugin : public core::objectmodel::BaseObject
sofa::core::objectmodel::Data<bool> d_requireOne; ///< Display an error message if no plugin names were successfully loaded
sofa::core::objectmodel::Data<bool> d_requireAll; ///< Display an error message if any plugin names failed to be loaded

sofa::core::objectmodel::Data<helper::vector<std::string> > d_loadedPlugins; ///< name of the loaded plugins

protected:
RequiredPlugin();
~RequiredPlugin() override {}
Expand All @@ -64,7 +66,7 @@ class SOFA_BASE_UTILS_API RequiredPlugin : public core::objectmodel::BaseObject

void parse(sofa::core::objectmodel::BaseObjectDescription* arg) override;

void loadPlugin();
bool loadPlugin();

};

Expand Down

0 comments on commit 6f687e1

Please sign in to comment.