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

[SofaKernel] Minor code refactor in BaseData & new StringUtils functions. #860

Merged
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
23 changes: 4 additions & 19 deletions SofaKernel/framework/sofa/core/objectmodel/BaseData.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,20 +180,9 @@ class SOFA_CORE_API BaseData : public DDGNode
/// Set widget
void setWidget(const char* val) { widget = val; }

/// True if the value has been modified
/// If this data is linked, the value of this data will be considered as modified
/// (even if the parent's value has not been modified)
bool isSet() const { return m_isSets[currentAspect()]; }

/// True if the counter of modification gives valid information.
virtual bool isCounterValid() const = 0;

/// Reset the isSet flag to false, to indicate that the current value is the default for this %Data.
void unset() { m_isSets[currentAspect()] = false; }

/// Reset the isSet flag to true, to indicate that the current value has been modified.
void forceSet() { m_isSets[currentAspect()] = true; }

/// @name Flags
/// @{

Expand Down Expand Up @@ -253,28 +242,24 @@ class SOFA_CORE_API BaseData : public DDGNode
/// This method should not be called directly, the %Data registration methods in Base should be used instead.
void setName(const std::string& name) { m_name=name; }

/// Return the number of changes since creation.
/// This can be used to efficiently detect changes.
int getCounter() const { return m_counters[currentAspect()]; }


/// @name Optimized edition and retrieval API (for multi-threading performances)
/// @{

/// True if the value has been modified
/// If this data is linked, the value of this data will be considered as modified
/// (even if the parent's value has not been modified)
bool isSet(const core::ExecParams* params) const { return m_isSets[currentAspect(params)]; }
bool isSet(const core::ExecParams* params=nullptr) const { return m_isSets[currentAspect(params)]; }

/// Reset the isSet flag to false, to indicate that the current value is the default for this %Data.
void unset(const core::ExecParams* params) { m_isSets[currentAspect(params)] = false; }
void unset(const core::ExecParams* params=nullptr) { m_isSets[currentAspect(params)] = false; }

/// Reset the isSet flag to true, to indicate that the current value has been modified.
void forceSet(const core::ExecParams* params) { m_isSets[currentAspect(params)] = true; }
void forceSet(const core::ExecParams* params=nullptr) { m_isSets[currentAspect(params)] = true; }

/// Return the number of changes since creation
/// This can be used to efficiently detect changes
int getCounter(const core::ExecParams* params) const { return m_counters[currentAspect(params)]; }
int getCounter(const core::ExecParams* params=nullptr) const { return m_counters[currentAspect(params)]; }

/// @}

Expand Down
1 change: 1 addition & 0 deletions SofaKernel/framework/sofa/helper/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,7 @@ set(SOURCE_FILES
Polynomial_LD.cpp
Quater.cpp
RandomGenerator.cpp
StringUtils.cpp
TagFactory.cpp
UnitTest.cpp
Utils.cpp
Expand Down
84 changes: 84 additions & 0 deletions SofaKernel/framework/sofa/helper/StringUtils.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/******************************************************************************
* SOFA, Simulation Open-Framework Architecture, development version *
* (c) 2006-2018 INRIA, USTL, UJF, CNRS, MGH *
* *
* This program is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by *
* the Free Software Foundation; either version 2.1 of the License, or (at *
* your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
*******************************************************************************
* Authors: The SOFA Team and external contributors (see Authors.txt) *
* *
* Contact information: contact@sofa-framework.org *
******************************************************************************/
#include <cstring>
#include "StringUtils.h"

namespace sofa
{

namespace helper
{

/// Taken from https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/
std::vector<std::string> split(const std::string& s, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}

char* getAStringCopy(const char *c)
{
char* tmp = new char[strlen(c)+1] ;
strcpy(tmp,c);
return tmp ;
}

void replaceAll(std::string& str, const std::string& search, const std::string& replace)
{
size_t pos = 0;
while((pos = str.find(search, pos)) != std::string::npos)
{
str.replace(pos, search.length(), replace);
pos += replace.length();
}
}

bool ends_with(const std::string& suffix, const std::string& full)
{
const std::size_t lf = full.length();
const std::size_t ls = suffix.length();

if(lf < ls) return false;

return (0 == full.compare(lf - ls, ls, suffix));
}

bool starts_with(const std::string& prefix, const std::string& full)
{
const std::size_t lf = full.length();
const std::size_t lp = prefix.length();

if(lf < lp) return false;

return (0 == full.compare(0, lp, prefix));
}

} // namespace helper

} // namespace sofa

45 changes: 16 additions & 29 deletions SofaKernel/framework/sofa/helper/StringUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,20 @@
#define SOFA_HELPER_STRING_UTILS_H

#include <string>
#include <cstring>
#include <vector>
#include <sstream>

#include <sofa/config.h>
namespace sofa
{

namespace helper
{

/// Taken from https://www.fluentcpp.com/2017/04/21/how-to-split-a-string-in-c/
static inline std::vector<std::string> split(const std::string& s, char delimiter)
{
std::vector<std::string> tokens;
std::string token;
std::istringstream tokenStream(s);
while (std::getline(tokenStream, token, delimiter))
{
tokens.push_back(token);
}
return tokens;
}
///@brief Split one string by a given delimiter and returns that into a std::vector
std::vector<std::string> SOFA_HELPER_API split(const std::string& s, char delimiter);

///@brief Join a std::vector into a single string, separated by the provided delimiter.
///
/// Taken from https://github.com/ekg/split/blob/master/join.h (I don't know what is the licence
/// but thank for the author.
template<class S, class T>
Expand All @@ -60,23 +51,19 @@ std::string join(std::vector<T>& elems, S& delim) {
}
return ss.str();
}
///@brief returns a copy of the string given in argument.
SOFA_HELPER_API char* getAStringCopy(const char *c);

static inline char* getAStringCopy(const char *c)
{
char* tmp = new char[strlen(c)+1] ;
strcpy(tmp,c);
return tmp ;
}
///@brief replace all occurence of "search" by the "replace" string.
SOFA_HELPER_API void replaceAll(std::string& str,
const std::string& search,
const std::string& replace);

static inline void replaceAll(std::string& str, const std::string& search, const std::string& replace)
{
size_t pos = 0;
while((pos = str.find(search, pos)) != std::string::npos)
{
str.replace(pos, search.length(), replace);
pos += replace.length();
}
}
///@brief returns true if the prefix if located at the beginning of the "full" string.
SOFA_HELPER_API bool starts_with(const std::string& prefix, const std::string& full);

///@brief returns true if the suffix if located at the end of the "full" string.
SOFA_HELPER_API bool ends_with(const std::string& suffix, const std::string& full);

} // namespace helper

Expand Down
36 changes: 23 additions & 13 deletions SofaKernel/modules/SofaSimulationGraph/SimpleApi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -81,39 +81,49 @@ Node::SPtr createRootNode(Simulation::SPtr s, const std::string& name,
return root ;
}


BaseObject::SPtr createObject(Node::SPtr parent, const std::string& type, const std::map<std::string, std::string>& params)
BaseObject::SPtr createObject(Node::SPtr parent, BaseObjectDescription& desc)
{
/// temporarily, the name is set to the type name.
/// if a "name" parameter is provided, it will overwrite it.
BaseObjectDescription desc(type.c_str(),type.c_str());
for(auto& kv : params)
{
desc.setAttribute(kv.first.c_str(), kv.second);
}

/// Create the object.
BaseObject::SPtr obj = ObjectFactory::getInstance()->createObject(parent.get(), &desc);
if (obj==0)
if (obj==nullptr)
{
std::stringstream msg;
msg << "Component '" << desc.getName() << "' of type '" << desc.getAttribute("type","") << "' failed:" << msgendl ;
for (std::vector< std::string >::const_iterator it = desc.getErrors().begin(); it != desc.getErrors().end(); ++it)
msg << " " << *it << msgendl ;
msg_error(parent.get()) << msg.str() ;
return NULL;
return nullptr;
}

return obj ;
}

BaseObject::SPtr createObject(Node::SPtr parent, const std::string& type, const std::map<std::string, std::string>& params)
{
/// temporarily, the name is set to the type name.
/// if a "name" parameter is provided, it will overwrite it.
BaseObjectDescription desc(type.c_str(),type.c_str());
for(auto& kv : params)
{
desc.setAttribute(kv.first.c_str(), kv.second);
}

return createObject(parent, desc);
}

Node::SPtr createChild(Node::SPtr& node, const std::string& name, const std::map<std::string, std::string>& params)
{
BaseObjectDescription desc(name.c_str(), "Node");
for(auto& kv : params)
{
desc.setAttribute(kv.first.c_str(), kv.second);
}
Node::SPtr tmp = node->createChild(name);
return createChild(node, desc);
}

Node::SPtr createChild(Node::SPtr node, BaseObjectDescription& desc)
{
Node::SPtr tmp = node->createChild(desc.getName());
tmp->parse(&desc);
return tmp;
}
Expand Down
20 changes: 17 additions & 3 deletions SofaKernel/modules/SofaSimulationGraph/SimpleApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,15 @@

#include <sofa/simulation/Node.h>
#include <sofa/simulation/Simulation.h>
#include <sofa/core/objectmodel/BaseObject.h>

namespace sofa
{
namespace simpleapi
{

using sofa::core::objectmodel::BaseObject ;
using sofa::core::objectmodel::BaseObject;
using sofa::core::objectmodel::BaseObjectDescription;

using sofa::simulation::Simulation ;
using sofa::simulation::Node ;

Expand All @@ -51,12 +52,25 @@ Simulation::SPtr SOFA_SIMULATION_GRAPH_API createSimulation(const std::string& t
Node::SPtr SOFA_SIMULATION_GRAPH_API createRootNode( Simulation::SPtr, const std::string& name,
const std::map<std::string, std::string>& params = std::map<std::string, std::string>{} );

BaseObject::SPtr SOFA_SIMULATION_GRAPH_API createObject( Node::SPtr parent, const std::string& type,
///@brief Create a sofa object in the provided node.
///The parameter "params" is for passing specific data argument to the created object including the
///object's type.
BaseObject::SPtr SOFA_SIMULATION_GRAPH_API createObject(Node::SPtr node, BaseObjectDescription& params);

///@brief create a sofa object in the provided node of the given type.
///The parameter "params" is for passing specific data argument to the created object.
BaseObject::SPtr SOFA_SIMULATION_GRAPH_API createObject( Node::SPtr node, const std::string& type,
const std::map<std::string, std::string>& params = std::map<std::string, std::string>{} );

///@brief create a child to the provided nodeof given name.
///The parameter "params" is for passing specific data argument to the created object.
Node::SPtr SOFA_SIMULATION_GRAPH_API createChild( Node::SPtr& node, const std::string& name,
const std::map<std::string, std::string>& params = std::map<std::string, std::string>{} );

///@brief create a child to the provided node.
///The parameter "params" is for passing specific data argument to the created object (including the node name).
Node::SPtr SOFA_SIMULATION_GRAPH_API createChild(Node::SPtr node, BaseObjectDescription& desc);

void SOFA_SIMULATION_GRAPH_API dumpScene(Node::SPtr root) ;

template<class T>
Expand Down