Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[pull] master from choreonoid:master #110

Merged
merged 3 commits into from
Mar 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
Choreonoid 2.1.1 released on March 21, 2024
===========================================

Changes since 2.1.0:

* Improve the plugin path management
* Add the command line option "--add-plugin-dir-as-prefix"
* Improve SimpleControllerItem to support additional controller directories in the plugin path

Choreonoid 2.1.0 released on March 17, 2024
===========================================

Expand Down
15 changes: 14 additions & 1 deletion src/Base/App.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@ bool isNoWindowMode = false;
bool ctrl_c_pressed = false;
bool exitRequested = false;
vector<string> additionalPathVariables;
vector<string> pluginDirsAsPrefix;

void onCtrl_C_Input(int)
{
Expand Down Expand Up @@ -222,7 +223,11 @@ App::Impl::Impl(App* self, int& argc, char** argv, const std::string& appName, c
mout->setPendingMode(true);

AppConfig::initialize(appName, organization);

pluginManager = PluginManager::instance();
if(auto pluginPathList = getenv("CNOID_PLUGIN_PATH")){
pluginManager->addPluginPathList(toUTF8(pluginPathList));
}

ext = nullptr;
mainWindow = nullptr;
Expand Down Expand Up @@ -317,7 +322,7 @@ void App::setIcon(const std::string& filename)
void App::addPluginPath(const std::string& path)
{
if(!path.empty()){
impl->pluginManager->addPluginPath(path);
impl->pluginManager->addPluginPathList(path);
}
}

Expand Down Expand Up @@ -375,6 +380,10 @@ void App::Impl::initialize()
optionManager->add_option(
"--path-variable", additionalPathVariables,
"Set a path variable in the format \"name=value\"");

optionManager->add_option(
"--add-plugin-dir-as-prefix", pluginDirsAsPrefix,
"Add a plugin directory as an install path prefix");

mainWindow = MainWindow::initialize(appName, ext);

Expand Down Expand Up @@ -545,6 +554,10 @@ int App::Impl::exec()
doQuit = true;
}
}

for(auto& prefix : pluginDirsAsPrefix){
pluginManager->addPluginDirectoryAsPrefix(prefix);
}

optionManager->processOptionsPhase1();

Expand Down
2 changes: 2 additions & 0 deletions src/Base/App.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class CNOID_EXPORT App

~App();

[[deprecated("Use PluginManager::addPluginPathList")]]
void addPluginPath(const std::string& path);

bool requirePluginToCustomizeApplication(const std::string& pluginName);

// Optional setting
Expand Down
74 changes: 60 additions & 14 deletions src/Base/PluginManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ class PluginManager::Impl
MainMenu* mainMenu;

string pluginDirectory;
vector<string> pluginPaths;
vector<string> pluginDirectories;
QRegExp pluginNamePattern;

vector<PluginInfoPtr> allPluginInfos;
Expand All @@ -121,7 +121,7 @@ class PluginManager::Impl
LazyCaller unloadPluginsLater;
LazyCaller reloadPluginsLater;

void addPluginPath(const std::string& path);
void addPluginDirectory(const std::string& directory, bool doMakeAbsolute);
void loadPlugins(bool doActivation);
void scanPluginFiles(const std::string& pathString, bool isUTF8, bool isRecursive);
void loadScannedPluginFiles(bool doActivation);
Expand Down Expand Up @@ -176,7 +176,7 @@ PluginManager::Impl::Impl()
mout = MessageOut::master();
mainMenu = nullptr;

addPluginPath(cnoid::pluginDir());
addPluginDirectory(cnoid::pluginDir(), false);

pluginNamePattern.setPattern(
QString(DLL_PREFIX) + "Cnoid(.+)Plugin" + DEBUG_SUFFIX + "\\." + DLL_EXTENSION);
Expand Down Expand Up @@ -208,27 +208,73 @@ PluginManager::Impl::~Impl()


/**
@param path semicolon or colon separeted path list.
@param pathList semicolon or colon separeted absolute path list.
*/
void PluginManager::addPluginPath(const std::string& pathString)
void PluginManager::addPluginPathList(const std::string& pathList)
{
for(auto& path : Tokenizer<CharSeparator<char>>(pathString, CharSeparator<char>(PATH_DELIMITER))){
impl->addPluginPath(path);
for(auto& dir : Tokenizer<CharSeparator<char>>(pathList, CharSeparator<char>(PATH_DELIMITER))){
impl->addPluginDirectory(dir, false);
}
}


void PluginManager::Impl::addPluginPath(const std::string& path)

void PluginManager::addPluginPath(const std::string& pathList)
{
pluginPaths.push_back(path);
addPluginPathList(pathList);
}


void PluginManager::addPluginDirectory(const std::string& directory)
{
impl->addPluginDirectory(directory, true);
}


void PluginManager::Impl::addPluginDirectory(const std::string& directory, bool doMakeAbsolute)
{
string directoryFromUTF8;
if(doMakeAbsolute){
directoryFromUTF8 = fromUTF8(directory);
filesystem::path path(directoryFromUTF8);
if(!path.is_absolute()){
string absDirectory = filesystem::absolute(path).string();
pluginDirectories.insert(pluginDirectories.begin(), toUTF8(absDirectory));
#ifdef Q_OS_WIN32
// Add the plugin directory to PATH
qputenv("PATH", format("{0};{1}", absDirectory, qgetenv("PATH")).c_str());
#endif
return;
}
}

pluginDirectories.insert(pluginDirectories.begin(), directory);

#ifdef Q_OS_WIN32
// Add the plugin directory to PATH
qputenv("PATH", format("{0};{1}", fromUTF8(path), qgetenv("PATH")).c_str());
if(directoryFromUTF8.empty()){
directoryFromUTF8 = fromUTF8(directory);
}
qputenv("PATH", format("{0};{1}", directoryFromUTF8, qgetenv("PATH")).c_str());
#endif
}


/**
@param directory the install prefix of the corresponding plugin module.
*/
void PluginManager::addPluginDirectoryAsPrefix(const std::string& prefix)
{
addPluginDirectory(
toUTF8((filesystem::path(fromUTF8(prefix)) / CNOID_PLUGIN_SUBDIR).string()));
}


const std::vector<std::string> PluginManager::pluginDirectories() const
{
return impl->pluginDirectories;
}


bool PluginManager::isStartupLoadingDisabled() const
{
return impl->isStartupLoadingDisabled;
Expand All @@ -252,8 +298,8 @@ void PluginManager::loadPlugins(bool doActivation)
void PluginManager::Impl::loadPlugins(bool doActivation)
{
if(allPluginInfos.empty()){ // Not scanned yet
for(auto& path : pluginPaths){
scanPluginFiles(path, true, false);
for(auto& dir : pluginDirectories){
scanPluginFiles(dir, true, false);
}
}
loadScannedPluginFiles(doActivation);
Expand Down Expand Up @@ -776,7 +822,7 @@ int PluginManager::numPlugins() const
}


const std::string& PluginManager::pluginPath(int index) const
const std::string& PluginManager::pluginFile(int index) const
{
return impl->allPluginInfos[index]->pathString;
}
Expand Down
15 changes: 9 additions & 6 deletions src/Base/PluginManager.h
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
/**
@author Shin'ichiro Nakaoka
*/

#ifndef CNOID_BASE_PLUGIN_MANAGER_H
#define CNOID_BASE_PLUGIN_MANAGER_H

#include <string>
#include <vector>
#include "exportdecl.h"

namespace cnoid {
Expand All @@ -19,7 +16,13 @@ class CNOID_EXPORT PluginManager

~PluginManager();

void addPluginPath(const std::string& path);
void addPluginPathList(const std::string& pathList);
[[deprecated("Use addPluginPathList")]]
void addPluginPath(const std::string& pathList);

void addPluginDirectory(const std::string& directory);
void addPluginDirectoryAsPrefix(const std::string& prefix);
const std::vector<std::string> pluginDirectories() const;
bool isStartupLoadingDisabled() const;
void doStartupLoading();
void loadPlugins(bool doActivation);
Expand All @@ -32,7 +35,7 @@ class CNOID_EXPORT PluginManager
void flushMessagesTo(std::ostream& os);

int numPlugins() const;
const std::string& pluginPath(int index) const;
const std::string& pluginFile(int index) const;
const std::string& pluginName(int index) const;

enum PluginStatus { NOT_LOADED, LOADED, ACTIVE, FINALIZED, UNLOADED, INVALID, CONFLICT };
Expand Down
68 changes: 57 additions & 11 deletions src/BodyPlugin/SimpleControllerItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <cnoid/FileUtil>
#include <cnoid/UTF8>
#include <cnoid/ConnectionSet>
#include <cnoid/PluginManager>
#include <cnoid/ProjectManager>
#include <cnoid/ItemManager>
#include <QLibrary>
Expand Down Expand Up @@ -90,7 +91,6 @@ class SimpleControllerItem::Impl : public SimulationSimpleControllerIO

std::string controllerModuleName;
std::string controllerModuleFilename;
filesystem::path controllerDirPath;
QLibrary controllerModule;
bool doReloading;
bool isSymbolExportEnabled;
Expand All @@ -109,6 +109,9 @@ class SimpleControllerItem::Impl : public SimulationSimpleControllerIO
Impl(SimpleControllerItem* self, const Impl& org);
~Impl();
void doCommonInitializationInConstructor();
bool checkIfControllerModuleInControllerDirectory(
const filesystem::path& modulePath, filesystem::path& out_controllerDirPath);
bool checkIfControllerModulePathExists(const filesystem::path& modulePath);
void setController(const std::string& name);
bool loadController();
bool configureController(BodyItem* bodyItem);
Expand Down Expand Up @@ -164,8 +167,6 @@ class SimpleControllerItem::Impl : public SimulationSimpleControllerIO
}


namespace {

MySimpleControllerConfig::MySimpleControllerConfig(SimpleControllerItem::Impl* impl)
: SimpleControllerConfig(impl),
impl(impl)
Expand All @@ -179,8 +180,6 @@ Referenced* MySimpleControllerConfig::bodyItem()
return impl->self->targetBodyItem();
}

}


void SimpleControllerItem::initializeClass(ExtensionManager* ext)
{
Expand Down Expand Up @@ -208,8 +207,6 @@ SimpleControllerItem::Impl::Impl(SimpleControllerItem* self)
doReloading = false;
isSymbolExportEnabled = false;

controllerDirPath = pluginDirPath() / "simplecontroller";

baseDirectoryType.setSymbol(NO_BASE_DIRECTORY, N_("None"));
baseDirectoryType.setSymbol(CONTROLLER_DIRECTORY, N_("Controller directory"));
baseDirectoryType.setSymbol(PROJECT_DIRECTORY, N_("Project directory"));
Expand All @@ -228,7 +225,6 @@ SimpleControllerItem::Impl::Impl(SimpleControllerItem* self, const Impl& org)
: self(self),
config(this),
controllerModuleName(org.controllerModuleName),
controllerDirPath(org.controllerDirPath),
baseDirectoryType(org.baseDirectoryType)
{
doCommonInitializationInConstructor();
Expand Down Expand Up @@ -296,6 +292,42 @@ SimpleController* SimpleControllerItem::controller()
}


bool SimpleControllerItem::Impl::checkIfControllerModuleInControllerDirectory
(const filesystem::path& modulePath, filesystem::path& out_controllerDirPath)
{
bool isInControllerDirectories = false;

for(auto& pluginDir : PluginManager::instance()->pluginDirectories()){
out_controllerDirPath = filesystem::path(fromUTF8(pluginDir)) / "simplecontroller";
if(modulePath.is_absolute()){
if(modulePath.parent_path() == out_controllerDirPath){
isInControllerDirectories = true;
break;
}
} else {
if(checkIfControllerModulePathExists(out_controllerDirPath / modulePath)){
isInControllerDirectories = true;
break;
}
}
}

return isInControllerDirectories;
}


bool SimpleControllerItem::Impl::checkIfControllerModulePathExists(const filesystem::path& modulePath)
{
if(filesystem::exists(modulePath)){
return true;
}
filesystem::path pathWithExtension = modulePath;
pathWithExtension += ".";
pathWithExtension += DLL_EXTENSION;
return filesystem::exists(pathWithExtension);
}


void SimpleControllerItem::setController(const std::string& name)
{
impl->setController(name);
Expand All @@ -312,7 +344,8 @@ void SimpleControllerItem::Impl::setController(const std::string& name)
filesystem::path modulePath(fromUTF8(name));
if(modulePath.is_absolute()){
baseDirectoryType.select(NO_BASE_DIRECTORY);
if(modulePath.parent_path() == controllerDirPath){
filesystem::path controllerDirPath;
if(checkIfControllerModuleInControllerDirectory(modulePath, controllerDirPath)){
baseDirectoryType.select(CONTROLLER_DIRECTORY);
modulePath = modulePath.filename();
} else {
Expand Down Expand Up @@ -347,7 +380,14 @@ bool SimpleControllerItem::Impl::loadController()
filesystem::path modulePath(fromUTF8(controllerModuleName));
if(!modulePath.is_absolute()){
if(baseDirectoryType.is(CONTROLLER_DIRECTORY)){
modulePath = controllerDirPath / modulePath;
for(auto& pluginDir : PluginManager::instance()->pluginDirectories()){
filesystem::path controllerDirPath = filesystem::path(fromUTF8(pluginDir)) / "simplecontroller";
filesystem::path moduleFullPath = controllerDirPath / modulePath;
if(checkIfControllerModulePathExists(moduleFullPath)){
modulePath = moduleFullPath;
break;
}
}
} else if(baseDirectoryType.is(PROJECT_DIRECTORY)){
string projectDir = ProjectManager::instance()->currentProjectDirectory();
if(!projectDir.empty()){
Expand Down Expand Up @@ -1080,7 +1120,13 @@ void SimpleControllerItem::Impl::doPutProperties(PutPropertyFunction& putPropert
{
FilePathProperty moduleProperty(controllerModuleName);
if(baseDirectoryType.is(CONTROLLER_DIRECTORY)){
moduleProperty.setBaseDirectory(toUTF8(controllerDirPath.string()));
filesystem::path modulePath(fromUTF8(controllerModuleName));
filesystem::path dirPath;
if(checkIfControllerModuleInControllerDirectory(modulePath, dirPath)){
moduleProperty.setBaseDirectory(toUTF8(dirPath.string()));
} else {
moduleProperty.setBaseDirectory(toUTF8((pluginDirPath() / "simplecontroller").string()));
}
} else if(baseDirectoryType.is(PROJECT_DIRECTORY)){
moduleProperty.setBaseDirectory(ProjectManager::instance()->currentProjectDirectory());
}
Expand Down
Loading