Accessible.h
Go to the documentation of this file.
// This file is a part of the OpenSurgSim project.
// Copyright 2013-2015, SimQuest Solutions Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef SURGSIM_FRAMEWORK_ACCESSIBLE_H
#define SURGSIM_FRAMEWORK_ACCESSIBLE_H
#include <boost/any.hpp>
#include <boost/preprocessor.hpp>
#include <functional>
#include <memory>
#include <string>
#include <unordered_map>
#include <yaml-cpp/yaml.h>
#include "SurgSim/Math/Matrix.h"
namespace SurgSim
{
namespace Framework
{
class Accessible
{
public:
Accessible();
~Accessible();
typedef std::function<boost::any(void)> GetterType;
typedef std::function<void (boost::any)> SetterType;
typedef std::function<YAML::Node(void)> EncoderType;
typedef std::function<void(const YAML::Node*)> DecoderType;
template <class T>
T getValue(const std::string& name) const;
boost::any getValue(const std::string& name) const;
template <class T>
bool getValue(const std::string& name, T* value) const;
void setValue(const std::string& name, const boost::any& value);
bool isReadable(const std::string& name) const;
bool isWriteable(const std::string& name) const;
void setGetter(const std::string& name, GetterType func);
void setSetter(const std::string& name, SetterType func);
void setAccessors(const std::string& name, GetterType getter, SetterType setter);
void removeAccessors(const std::string& name);
void forwardProperty(const std::string& name, const Accessible& target, const std::string& targetProperty);
void setSerializable(const std::string& name, EncoderType encoder, DecoderType decoder);
void setDecoder(const std::string& name, DecoderType decoder);
YAML::Node encode() const;
void decode(const YAML::Node& node, const std::vector<std::string>& ignoredProperties = std::vector<std::string>());
private:
Accessible(const Accessible& other) /*= delete*/;
Accessible& operator=(const Accessible& other) /*= delete*/;
struct Functors
{
Functors() : getter(nullptr), setter(nullptr), encoder(nullptr), decoder(nullptr) {}
GetterType getter;
SetterType setter;
EncoderType encoder;
DecoderType decoder;
};
std::unordered_map<std::string, Functors> m_functors;
};
struct Property
{
std::weak_ptr<Accessible> accessible;
std::string name;
};
template <>
boost::any Accessible::getValue(const std::string& name) const;
template <class T>
T convert(boost::any val);
template <>
SurgSim::Math::Matrix44f convert(boost::any val);
template <>
std::string convert(boost::any val);
#define SURGSIM_ADD_RW_PROPERTY(class, type, property, getter, setter) \
setAccessors(#property, \
std::bind(&class::getter, this),\
std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)))
#define SURGSIM_ADD_RO_PROPERTY(class, type, property, getter) \
setGetter(#property, \
std::bind(&class::getter, this))
#define SURGSIM_ADD_SERIALIZABLE_PROPERTY(class, type, property, getter, setter) \
setAccessors(#property, \
std::bind(&class::getter, this),\
std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
setSerializable(#property,\
std::bind(&YAML::convert<type>::encode, std::bind(&class::getter, this)),\
std::bind(&class::setter, this, std::bind(&YAML::Node::as<type>,std::placeholders::_1)))
#define SURGSIM_ADD_SETTER(class, type, property, setter) \
{\
setDecoder(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
std::bind(&YAML::Node::as<type>,std::placeholders::_1))); \
setSetter(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
}
}; // Framework
}; // SurgSim
#define SURGSIM_ENUM_TOSTRING(r, data, elem) \
case data::elem: \
result = BOOST_PP_STRINGIZE(elem); \
break;
#define SURGSIM_ENUM_FROMSTRING(r, data, elem) \
if (value == BOOST_PP_STRINGIZE(elem)) \
{ \
rhs = data::elem; \
return true; \
}
#define SURGSIM_ENUM_TYPE int8_t
#define SURGSIM_SERIALIZABLE_ENUM(name, enumerators) \
enum name : SURGSIM_ENUM_TYPE\
{ \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
namespace YAML \
{ \
template <> \
struct convert<name> \
{ \
static Node encode(const name& rhs) \
{ \
Node result; \
switch (rhs) \
{ \
BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_TOSTRING, name, enumerators) \
default: \
SURGSIM_FAILURE() << "Can not find enum value in " << #name << ": " << rhs; \
} \
return result; \
} \
static bool decode(const Node& node, name& rhs) \
{ \
std::string value = node.as<std::string>(); \
std::transform(value.begin(), value.end(), value.begin(), ::toupper); \
BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_FROMSTRING, name, enumerators) \
SURGSIM_FAILURE() << "Unknown " << #name << ": " << value; \
return false; \
} \
}; \
}
#include "SurgSim/Framework/Accessible-inl.h"
#endif
SurgSim::Framework::Accessible::isReadable
bool isReadable(const std::string &name) const
Check whether a property is readable.
Definition: Accessible.cpp:104
SurgSim::Framework::Accessible::SetterType
std::function< void(boost::any)> SetterType
Definition: Accessible.h:48
SurgSim
Definition: CompoundShapeToGraphics.cpp:29
SurgSim::Framework::Property::name
std::string name
Definition: Accessible.h:181
SurgSim::Framework::Accessible::~Accessible
~Accessible()
Destructor.
Definition: Accessible.cpp:31
SurgSim::Framework::Accessible::Functors
Private struct to keep the map under control.
Definition: Accessible.h:164
SurgSim::Framework::Accessible::Functors::Functors
Functors()
Definition: Accessible.h:166
SurgSim::Framework::Property::accessible
std::weak_ptr< Accessible > accessible
Definition: Accessible.h:180
SurgSim::Framework::Accessible::Functors::setter
SetterType setter
Definition: Accessible.h:168
SurgSim::Framework::Accessible::isWriteable
bool isWriteable(const std::string &name) const
Check whether a property is writable.
Definition: Accessible.cpp:110
SurgSim::Framework::Accessible::setSerializable
void setSerializable(const std::string &name, EncoderType encoder, DecoderType decoder)
Sets the functions used to convert data from and to a YAML::Node.
Definition: Accessible.cpp:116
SurgSim::Framework::Accessible::decode
void decode(const YAML::Node &node, const std::vector< std::string > &ignoredProperties=std::vector< std::string >())
Decode this Accessible from a YAML::Node, will throw an exception if the data type cannot be converte...
Definition: Accessible.cpp:146
SurgSim::Framework::Accessible::encode
YAML::Node encode() const
Encode this Accessible to a YAML::Node.
Definition: Accessible.cpp:132
SurgSim::Framework::Accessible::operator=
Accessible & operator=(const Accessible &other)
SurgSim::Framework::convert
SurgSim::Math::Matrix44f convert(boost::any val)
Specialization for convert<T>() to correctly cast Matrix44d to Matrix44f, will throw if the val is no...
Definition: Accessible.cpp:210
SurgSim::Framework::Property
Public struct to pair an accessible with its appropriate property.
Definition: Accessible.h:178
SurgSim::Framework::Accessible::Functors::encoder
EncoderType encoder
Definition: Accessible.h:169
SurgSim::Framework::Accessible::DecoderType
std::function< void(const YAML::Node *)> DecoderType
Definition: Accessible.h:51
SurgSim::Framework::Accessible::setValue
void setValue(const std::string &name, const boost::any &value)
Sets a value of a property that has setter.
Definition: Accessible.cpp:58
SurgSim::Framework::Accessible::Accessible
Accessible()
Default Constructor.
Definition: Accessible.cpp:26
SurgSim::Framework::Accessible::m_functors
std::unordered_map< std::string, Functors > m_functors
Definition: Accessible.h:173
SurgSim::Framework::Accessible::Functors::getter
GetterType getter
Definition: Accessible.h:167
Accessible-inl.h
SurgSim::Math::Matrix44f
Eigen::Matrix< float, 4, 4, Eigen::RowMajor > Matrix44f
A 4x4 matrix of floats.
Definition: Matrix.h:43
SurgSim::Framework::Accessible::setSetter
void setSetter(const std::string &name, SetterType func)
Sets a setter for a given property.
Definition: Accessible.cpp:80
SurgSim::Framework::Accessible::setGetter
void setGetter(const std::string &name, GetterType func)
Sets a getter for a given property.
Definition: Accessible.cpp:74
SurgSim::Framework::Accessible::setAccessors
void setAccessors(const std::string &name, GetterType getter, SetterType setter)
Sets the accessors getter and setter in one function.
Definition: Accessible.cpp:86
SurgSim::Framework::Accessible::EncoderType
std::function< YAML::Node(void)> EncoderType
Definition: Accessible.h:50
Matrix.h
Definitions of small fixed-size square matrix types.
SurgSim::Framework::Accessible::GetterType
std::function< boost::any(void)> GetterType
Definition: Accessible.h:47
SurgSim::Framework::Accessible::Functors::decoder
DecoderType decoder
Definition: Accessible.h:170
SurgSim::Framework::Accessible::setDecoder
void setDecoder(const std::string &name, DecoderType decoder)
Sets the functions used to convert data from a YAML::Node.
Definition: Accessible.cpp:125
SurgSim::Framework::Accessible
Mixin class for enabling a property system on OSS classes, the instance still needs to initialize pro...
Definition: Accessible.h:37
SurgSim::Framework::Accessible::forwardProperty
void forwardProperty(const std::string &name, const Accessible &target, const std::string &targetProperty)
Adds a property with the given name that uses the targets accessors, in effect forwarding the value t...
Definition: Accessible.cpp:191
SurgSim::Framework::Accessible::removeAccessors
void removeAccessors(const std::string &name)
Removes all the accessors (getter and setter) for a given property.
Definition: Accessible.cpp:93
SurgSim::Framework::Accessible::getValue
T getValue(const std::string &name) const
Retrieves the value with the name by executing the getter if it is found and tries to convert it to t...
Definition: Accessible-inl.h:42