mirror of
https://github.com/moveit/moveit_task_constructor.git
synced 2025-11-04 14:49:57 +08:00
separate setValue() and setCurrentValue()
setValue() also updates the default value. reset() reset to the default value. setCurrentValue() only updates the current value, keeping current default. Thus setCurrentValue() can be reverted (to default) using reset().
This commit is contained in:
parent
d62b85572a
commit
59fe1e7860
@ -60,8 +60,12 @@ enum PropertyInitializerSource {
|
||||
|
||||
/** Property is a wrapper for a boost::any value, also providing a default value and a description.
|
||||
*
|
||||
* Properties can be configured to be initialized from another PropertyMap.
|
||||
* Properties can be configured to be initialized from another PropertyMap - if still undefined.
|
||||
* Potential sources are the properties of the parent of a stage, or the properties passed in the interface.
|
||||
*
|
||||
* Setting the value via setValue() updates both, the current value and the default value.
|
||||
* Using reset() the default value can be restored.
|
||||
* Using setCurrentValue() only updates the current value, allowing for later reset to the original default.
|
||||
*/
|
||||
class Property {
|
||||
friend class PropertyMap;
|
||||
@ -72,11 +76,23 @@ public:
|
||||
|
||||
Property(const std::type_index& type_index, const std::string& description, const boost::any& default_value);
|
||||
|
||||
/// set current value and default value
|
||||
void setValue(const boost::any& value);
|
||||
void setCurrentValue(const boost::any& value);
|
||||
|
||||
const boost::any& value() const;
|
||||
/// reset to default value (which can be empty)
|
||||
void reset();
|
||||
|
||||
inline bool defined() const { return !value_.empty(); }
|
||||
|
||||
/// get current value
|
||||
inline const boost::any& value() const { return value_; }
|
||||
/// get default value
|
||||
const boost::any& defaultValue() const { return default_; }
|
||||
|
||||
/// get description text
|
||||
const std::string& description() const { return description_; }
|
||||
/// get typename
|
||||
std::string typeName() const { return type_index_.name(); }
|
||||
|
||||
/// configure initialization from source using an arbitrary function
|
||||
@ -84,6 +100,9 @@ public:
|
||||
/// configure initialization from source using given other property name
|
||||
Property &configureInitFrom(PropertyInitializerSource source, const std::string& name);
|
||||
|
||||
/// set current value using configured initializers
|
||||
void performInitFrom(PropertyInitializerSource source, const PropertyMap& other);
|
||||
|
||||
private:
|
||||
std::string description_;
|
||||
std::type_index type_index_;
|
||||
@ -127,8 +146,10 @@ public:
|
||||
/// allow initialization from given source for listed properties - always using the same name
|
||||
void configureInitFrom(PropertyInitializerSource source, const std::set<std::string> &properties = {});
|
||||
|
||||
/// set the value of a property
|
||||
/// set (and, if neccessary, declare) the value of a property
|
||||
void set(const std::string& name, const boost::any& value);
|
||||
/// temporarily set the value of a property
|
||||
void setCurrent(const std::string& name, const boost::any& value);
|
||||
|
||||
/// get the value of a property
|
||||
const boost::any& get(const std::string& name) const;
|
||||
@ -143,12 +164,11 @@ public:
|
||||
/// count number of defined properties from given list
|
||||
size_t countDefined(const std::vector<std::string>& list) const;
|
||||
|
||||
/// reset properties to nil, if they have initializers
|
||||
/// reset all properties to their defaults
|
||||
void reset();
|
||||
|
||||
/// perform initialization of properties using configured initializers
|
||||
void performInitFrom(PropertyInitializerSource source, const PropertyMap& other,
|
||||
bool checkConsistency = false);
|
||||
/// perform initialization of still undefined properties using configured initializers
|
||||
void performInitFrom(PropertyInitializerSource source, const PropertyMap& other, bool enforce = false);
|
||||
};
|
||||
|
||||
} // namespace task_constructor
|
||||
|
||||
@ -48,6 +48,7 @@ Property::Property(const std::type_index& type_index, const std::string& descrip
|
||||
: description_(description)
|
||||
, type_index_(type_index)
|
||||
, default_(default_value)
|
||||
, value_(default_value)
|
||||
{
|
||||
if (!default_.empty() && std::type_index(default_.type()) != type_index_)
|
||||
throw std::runtime_error("type of default value doesn't match declared type");
|
||||
@ -64,16 +65,24 @@ void typeCheck(const boost::any& value, const std::type_index& type_index)
|
||||
}
|
||||
|
||||
void Property::setValue(const boost::any &value) {
|
||||
typeCheck(value, type_index_);
|
||||
value_ = value;
|
||||
// clear all initializers when value was explicitly set
|
||||
initializers_.clear();
|
||||
setCurrentValue(value);
|
||||
default_ = value_;
|
||||
}
|
||||
|
||||
const boost::any &Property::value() const {
|
||||
return value_.empty() ? default_ : value_;
|
||||
void Property::setCurrentValue(const boost::any &value)
|
||||
{
|
||||
if (!value.empty())
|
||||
typeCheck(value, type_index_);
|
||||
value_ = value;
|
||||
}
|
||||
|
||||
void Property::reset()
|
||||
{
|
||||
value_ = default_;
|
||||
}
|
||||
|
||||
|
||||
|
||||
Property& Property::configureInitFrom(PropertyInitializerSource source, const Property::InitializerFunction &f)
|
||||
{
|
||||
initializers_[source] = f;
|
||||
@ -86,6 +95,14 @@ Property &Property::configureInitFrom(PropertyInitializerSource source, const st
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Property::performInitFrom(PropertyInitializerSource source, const PropertyMap &other)
|
||||
{
|
||||
auto it = initializers_.find(source);
|
||||
if (it == initializers_.end()) return;
|
||||
|
||||
setCurrentValue(it->second(other));
|
||||
}
|
||||
|
||||
|
||||
Property& PropertyMap::declare(const std::string &name, const std::type_info &type,
|
||||
const std::string &description, const boost::any &default_value)
|
||||
@ -128,6 +145,11 @@ void PropertyMap::set(const std::string &name, const boost::any &value)
|
||||
}
|
||||
}
|
||||
|
||||
void PropertyMap::setCurrent(const std::string &name, const boost::any &value)
|
||||
{
|
||||
property(name).setCurrentValue(value);
|
||||
}
|
||||
|
||||
const boost::any &PropertyMap::get(const std::string &name) const
|
||||
{
|
||||
return property(name).value();
|
||||
@ -144,31 +166,16 @@ size_t PropertyMap::countDefined(const std::vector<std::string> &list) const
|
||||
|
||||
void PropertyMap::reset()
|
||||
{
|
||||
for (auto& pair : props_) {
|
||||
Property &p = pair.second;
|
||||
if (!p.initializers_.empty())
|
||||
// if there are initializers, reset property value
|
||||
// explicitly setting the value, clears initializers
|
||||
p.value_ = boost::any();
|
||||
}
|
||||
for (auto& pair : props_)
|
||||
pair.second.reset();
|
||||
}
|
||||
|
||||
void PropertyMap::performInitFrom(PropertyInitializerSource source, const PropertyMap &other,
|
||||
bool checkConsistency)
|
||||
void PropertyMap::performInitFrom(PropertyInitializerSource source, const PropertyMap &other, bool enforce)
|
||||
{
|
||||
for (auto& pair : props_) {
|
||||
Property &p = pair.second;
|
||||
auto it = p.initializers_.find(source);
|
||||
if (it == p.initializers_.end()) continue;
|
||||
const boost::any& value = it->second(other);
|
||||
if (value.empty()) continue;
|
||||
|
||||
typeCheck(value, p.type_index_);
|
||||
#if 0 // TODO: we cannot generically check for equality of boost::anys
|
||||
if (checkConsistency && !p.value_.empty() && p.value_ != value)
|
||||
throw std::runtime_error ("inconsistent values for property '" + pair.first + "'");
|
||||
#endif
|
||||
p.value_ = value;
|
||||
if (enforce || !p.defined())
|
||||
p.performInitFrom(source, other);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user