opensurgsim
Accessible.h
1 // This file is a part of the OpenSurgSim project.
2 // Copyright 2013-2015, SimQuest Solutions Inc.
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 // http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 
16 #ifndef SURGSIM_FRAMEWORK_ACCESSIBLE_H
17 #define SURGSIM_FRAMEWORK_ACCESSIBLE_H
18 
19 #include <boost/any.hpp>
20 #include <boost/preprocessor.hpp>
21 #include <functional>
22 #include <memory>
23 #include <string>
24 #include <unordered_map>
25 #include <yaml-cpp/yaml.h>
26 
27 #include "SurgSim/Math/Matrix.h"
28 
29 namespace SurgSim
30 {
31 namespace Framework
32 {
33 
38 {
39 public:
40 
42  Accessible();
43 
45  ~Accessible();
46 
47  typedef std::function<boost::any(void)> GetterType;
48  typedef std::function<void (boost::any)> SetterType;
49 
50  typedef std::function<YAML::Node(void)> EncoderType;
51  typedef std::function<void(const YAML::Node*)> DecoderType;
52 
59  template <class T>
60  T getValue(const std::string& name) const;
61 
66  boost::any getValue(const std::string& name) const;
67 
74  template <class T>
75  bool getValue(const std::string& name, T* value) const;
76 
81  void setValue(const std::string& name, const boost::any& value);
82 
86  bool isReadable(const std::string& name) const;
87 
91  bool isWriteable(const std::string& name) const;
92 
97  void setGetter(const std::string& name, GetterType func);
98 
103  void setSetter(const std::string& name, SetterType func);
104 
110  void setAccessors(const std::string& name, GetterType getter, SetterType setter);
111 
114  void removeAccessors(const std::string& name);
115 
124  void forwardProperty(const std::string& name, const Accessible& target, const std::string& targetProperty);
125 
132  void setSerializable(const std::string& name, EncoderType encoder, DecoderType decoder);
133 
140  void setDecoder(const std::string& name, DecoderType decoder);
141 
142 
145  YAML::Node encode() const;
146 
153  void decode(const YAML::Node& node, const std::vector<std::string>& ignoredProperties = std::vector<std::string>());
154 
155  std::vector<std::string> getProperties();
156 private:
157 
160  Accessible(const Accessible& other) /*= delete*/;
161  Accessible& operator=(const Accessible& other) /*= delete*/;
163 
165  struct Functors
166  {
167  Functors() : getter(nullptr), setter(nullptr), encoder(nullptr), decoder(nullptr) {}
168  GetterType getter;
169  SetterType setter;
170  EncoderType encoder;
171  DecoderType decoder;
172  };
173 
174  std::unordered_map<std::string, Functors> m_functors;
175 
176 };
177 
179 struct Property
180 {
181  std::weak_ptr<Accessible> accessible;
182  std::string name;
183 };
184 
185 template <>
186 boost::any Accessible::getValue(const std::string& name) const;
187 
188 
194 template <class T>
195 T convert(boost::any val);
196 
202 template <>
203 SurgSim::Math::Matrix44f convert(boost::any val);
204 
208 template <>
209 std::string convert(boost::any val);
210 
214 #define SURGSIM_ADD_RW_PROPERTY(class, type, property, getter, setter) \
215  setAccessors(#property, \
216  std::bind(&class::getter, this),\
217  std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)))
218 
220 #define SURGSIM_ADD_RO_PROPERTY(class, type, property, getter) \
221  setGetter(#property, \
222  std::bind(&class::getter, this))
223 
226 #define SURGSIM_ADD_SERIALIZABLE_PROPERTY(class, type, property, getter, setter) \
227  setAccessors(#property, \
228  std::bind(&class::getter, this),\
229  std::bind(&class::setter, this, std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
230  setSerializable(#property,\
231  std::bind(&YAML::convert<type>::encode, std::bind(&class::getter, this)),\
232  std::bind(&class::setter, this, std::bind(&YAML::Node::as<type>,std::placeholders::_1)))
233 
237 #define SURGSIM_ADD_SETTER(class, type, property, setter) \
238  {\
239  setDecoder(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
240  std::bind(&YAML::Node::as<type>,std::placeholders::_1))); \
241  setSetter(#property, std::bind((void(class::*)(const type&))&class::setter, this,\
242  std::bind(SurgSim::Framework::convert<type>,std::placeholders::_1)));\
243  }
244 
245 
246 }; // Framework
247 }; // SurgSim
248 
249 #define SURGSIM_ENUM_TOSTRING(r, data, elem) \
250  case data::elem: \
251  result = BOOST_PP_STRINGIZE(elem); \
252  break;
253 
254 #define SURGSIM_ENUM_FROMSTRING(r, data, elem) \
255  if (value == BOOST_PP_STRINGIZE(elem)) \
256  { \
257  rhs = data::elem; \
258  return true; \
259  }
260 
262 #define SURGSIM_ENUM_TYPE int8_t
263 
268 #define SURGSIM_SERIALIZABLE_ENUM(name, enumerators) \
269  enum name : SURGSIM_ENUM_TYPE\
270  { \
271  BOOST_PP_SEQ_ENUM(enumerators) \
272  }; \
273  namespace YAML \
274  { \
275  template <> \
276  struct convert<name> \
277  { \
278  static Node encode(const name& rhs) \
279  { \
280  Node result; \
281  switch (rhs) \
282  { \
283  BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_TOSTRING, name, enumerators) \
284  default: \
285  SURGSIM_FAILURE() << "Can not find enum value in " << #name << ": " << rhs; \
286  } \
287  return result; \
288  } \
289  static bool decode(const Node& node, name& rhs) \
290  { \
291  std::string value = node.as<std::string>(); \
292  std::transform(value.begin(), value.end(), value.begin(), ::toupper); \
293  BOOST_PP_SEQ_FOR_EACH(SURGSIM_ENUM_FROMSTRING, name, enumerators) \
294  SURGSIM_FAILURE() << "Unknown " << #name << ": " << value; \
295  return false; \
296  } \
297  }; \
298  }
299 
300 #include "SurgSim/Framework/Accessible-inl.h"
301 
302 #endif
bool isReadable(const std::string &name) const
Check whether a property is readable.
Definition: Accessible.cpp:104
Wraps glewInit() to separate the glew opengl definitions from the osg opengl definitions only imgui n...
Definition: AddRandomSphereBehavior.cpp:36
~Accessible()
Destructor.
Definition: Accessible.cpp:31
bool isWriteable(const std::string &name) const
Check whether a property is writable.
Definition: Accessible.cpp:110
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
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
YAML::Node encode() const
Encode this Accessible to a YAML::Node.
Definition: Accessible.cpp:132
Public struct to pair an accessible with its appropriate property.
Definition: Accessible.h:179
void setValue(const std::string &name, const boost::any &value)
Sets a value of a property that has setter.
Definition: Accessible.cpp:58
Accessible()
Default Constructor.
Definition: Accessible.cpp:26
void setSetter(const std::string &name, SetterType func)
Sets a setter for a given property.
Definition: Accessible.cpp:80
void setGetter(const std::string &name, GetterType func)
Sets a getter for a given property.
Definition: Accessible.cpp:74
void setAccessors(const std::string &name, GetterType getter, SetterType setter)
Sets the accessors getter and setter in one function.
Definition: Accessible.cpp:86
Definitions of small fixed-size square matrix types.
Eigen::Matrix< float, 4, 4, Eigen::RowMajor > Matrix44f
A 4x4 matrix of floats.
Definition: Matrix.h:43
void setDecoder(const std::string &name, DecoderType decoder)
Sets the functions used to convert data from a YAML::Node.
Definition: Accessible.cpp:125
Mixin class for enabling a property system on OSS classes, the instance still needs to initialize pro...
Definition: Accessible.h:37
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:204
void removeAccessors(const std::string &name)
Removes all the accessors (getter and setter) for a given property.
Definition: Accessible.cpp:93
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