Rapicorn - Experimental UI Toolkit - Source Code  13.07.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
aidaprops.hh
Go to the documentation of this file.
00001  // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html
00002 #ifndef __RAPICORN_AIDA_PROPS_HH__
00003 #define __RAPICORN_AIDA_PROPS_HH__
00004 
00005 #include <rcore/aida.hh>
00006 #include <rcore/strings.hh>
00007 
00008 namespace Rapicorn { namespace Aida {
00009 
00010 // == PropertyHostInterface ==
00011 typedef ImplicitBase PropertyHostInterface;
00012 
00013 // == Property ==
00014 class Property {
00015 protected:
00016   virtual ~Property();
00017 public:
00018   const char *ident;
00019   char       *label;
00020   char       *blurb;
00021   char       *hints;
00022   Property (const char *cident, const char *clabel, const char *cblurb, const char *chints);
00023   virtual void   set_value   (PropertyHostInterface &obj, const String &svalue) = 0;
00024   virtual String get_value   (PropertyHostInterface &obj) = 0;
00025   virtual bool   get_range   (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) = 0;
00026   bool           readable    () const;
00027   bool           writable    () const;
00028 };
00029 
00030 // == PropertyList ==
00031 struct PropertyList 
00032 {
00033   typedef Aida::Property Property; // make Property available as class member
00034 private:
00035   size_t     n_properties_;
00036   Property **properties_;
00037   void       append_properties (size_t n_props, Property **props, const PropertyList &c0, const PropertyList &c1,
00038                                 const PropertyList &c2, const PropertyList &c3, const PropertyList &c4, const PropertyList &c5,
00039                                 const PropertyList &c6, const PropertyList &c7, const PropertyList &c8, const PropertyList &c9);
00040 public:
00041   Property** list_properties   (size_t *n_properties) const;
00042   /*dtor*/  ~PropertyList      ();
00043   explicit   PropertyList      () : n_properties_ (0), properties_ (NULL) {}
00044   template<typename Array>
00045   explicit   PropertyList      (Array &a, const PropertyList &c0 = PropertyList(), const PropertyList &c1 = PropertyList(),
00046                                 const PropertyList &c2 = PropertyList(), const PropertyList &c3 = PropertyList(),
00047                                 const PropertyList &c4 = PropertyList(), const PropertyList &c5 = PropertyList(),
00048                                 const PropertyList &c6 = PropertyList(), const PropertyList &c7 = PropertyList(),
00049                                 const PropertyList &c8 = PropertyList(), const PropertyList &c9 = PropertyList()) :
00050     n_properties_ (0), properties_ (NULL)
00051   {
00052     const size_t n_props = sizeof (a) / sizeof (a[0]);
00053     Property *props[n_props];
00054     for (size_t i = 0; i < sizeof (a) / sizeof (a[0]); i++)
00055       props[i] = a[i];
00056     append_properties (n_props, props, c0, c1, c2, c3, c4, c5, c6, c7, c8, c9);
00057   }
00058 };
00059 
00060 // == Property Creation ==
00061 #define RAPICORN_AIDA_PROPERTY(Type, accessor, label, blurb, ...)   \
00062   Rapicorn::Aida::create_property (&Type::accessor, &Type::accessor, #accessor, label, blurb, __VA_ARGS__)
00063 
00064 #define RAPICORN_AIDA_PROPERTY_CHAIN(first,...)                    (*({ \
00065   static Property *__dummy_[] = {};                                     \
00066   static const PropertyList property_list (__dummy_, first, __VA_ARGS__); \
00067   &property_list; }))
00068 
00069 /* --- bool --- */
00070 template<class Class>
00071 struct PropertyBool : Property {
00072   void (Class::*setter) (bool);
00073   bool (Class::*getter) () const;
00074   PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) () const,
00075                 const char *cident, const char *clabel, const char *cblurb,
00076                 const char *chints);
00077   virtual void   set_value   (PropertyHostInterface &obj, const String &svalue);
00078   virtual String get_value   (PropertyHostInterface &obj);
00079   virtual bool   get_range   (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; }
00080 };
00081 template<class Class> inline Property*
00082 create_property (void (Class::*setter) (bool), bool (Class::*getter) () const,
00083                  const char *ident, const char *label, const char *blurb, const char *hints)
00084 { return new PropertyBool<Class> (setter, getter, ident, label, blurb, hints); }
00085 
00086 /* --- range --- */
00087 template<class Class, typename Type>
00088 struct PropertyRange : Property {
00089   Type minimum_value;
00090   Type maximum_value;
00091   Type stepping;
00092   void (Class::*setter) (Type);
00093   Type (Class::*getter) () const;
00094   PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) () const,
00095                  const char *cident, const char *clabel, const char *cblurb,
00096                  Type cminimum_value, Type cmaximum_value,
00097                  Type cstepping, const char *chints);
00098   virtual void   set_value   (PropertyHostInterface &obj, const String &svalue);
00099   virtual String get_value   (PropertyHostInterface &obj);
00100   virtual bool   get_range   (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping);
00101 };
00102 /* int */
00103 template<class Class> inline Property*
00104 create_property (void (Class::*setter) (int), int (Class::*getter) () const,
00105                  const char *ident, const char *label, const char *blurb,
00106                  int min_value, int max_value, int stepping, const char *hints)
00107 { return new PropertyRange<Class,int> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00108 template<class Class> inline Property*
00109 create_property (void (Class::*setter) (int), int (Class::*getter) () const,
00110                  const char *ident, const char *label, const char *blurb, const char *hints)
00111 { return new PropertyRange<Class,int> (setter, getter, ident, label, blurb, INT_MIN, INT_MAX, 1, hints); }
00112 /* int16 */
00113 template<class Class> inline Property*
00114 create_property (void (Class::*setter) (int16), int16 (Class::*getter) () const,
00115                  const char *ident, const char *label, const char *blurb,
00116                  int16 min_value, int16 max_value, int16 stepping, const char *hints)
00117 { return new PropertyRange<Class,int16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00118 /* uint */
00119 template<class Class> inline Property*
00120 create_property (void (Class::*setter) (uint), uint (Class::*getter) () const,
00121                  const char *ident, const char *label, const char *blurb,
00122                  uint min_value, uint max_value, uint stepping, const char *hints)
00123 { return new PropertyRange<Class,uint> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00124 /* uint16 */
00125 template<class Class> inline Property*
00126 create_property (void (Class::*setter) (uint16), uint16 (Class::*getter) () const,
00127                  const char *ident, const char *label, const char *blurb,
00128                  uint16 min_value, uint16 max_value, uint16 stepping, const char *hints)
00129 { return new PropertyRange<Class,uint16> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00130 /* float */
00131 template<class Class> inline Property*
00132 create_property (void (Class::*setter) (float), float (Class::*getter) () const,
00133                  const char *ident, const char *label, const char *blurb,
00134                  float min_value, float max_value, float stepping, const char *hints)
00135 { return new PropertyRange<Class,float> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00136 /* double */
00137 template<class Class> inline Property*
00138 create_property (void (Class::*setter) (double), double (Class::*getter) () const,
00139                  const char *ident, const char *label, const char *blurb,
00140                  double min_value, double max_value, double stepping, const char *hints)
00141 { return new PropertyRange<Class,double> (setter, getter, ident, label, blurb, min_value, max_value, stepping, hints); }
00142 template<class Class> inline Property*
00143 create_property (void (Class::*setter) (double), double (Class::*getter) () const,
00144                  const char *ident, const char *label, const char *blurb, const char *hints)
00145 { return new PropertyRange<Class,double> (setter, getter, ident, label, blurb, DBL_MIN, DBL_MAX, 1, hints); }
00146 
00147 /* --- string --- */
00148 template<class Class>
00149 struct PropertyString : Property {
00150   void   (Class::*setter) (const String&);
00151   String (Class::*getter) () const;
00152   PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) () const,
00153                   const char *cident, const char *clabel, const char *cblurb,
00154                   const char *chints);
00155   virtual void   set_value   (PropertyHostInterface &obj, const String &svalue);
00156   virtual String get_value   (PropertyHostInterface &obj);
00157   virtual bool   get_range   (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; }
00158 };
00159 template<class Class> inline Property*
00160 create_property (void (Class::*setter) (const String&), String (Class::*getter) () const,
00161                  const char *ident, const char *label, const char *blurb, const char *hints)
00162 { return new PropertyString<Class> (setter, getter, ident, label, blurb, hints); }
00163 
00164 // == Enum Properties ==
00165 template<class Class, typename Type>
00166 struct PropertyEnum : Property {
00167   const TypeCode enum_type;
00168   void (Class::*setter) (Type);
00169   Type (Class::*getter) () const;
00170   PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) () const,
00171                 const char *cident, const char *clabel, const char *cblurb,
00172                 const TypeCode &etype, const char *chints);
00173   virtual void   set_value   (PropertyHostInterface &obj, const String &svalue);
00174   virtual String get_value   (PropertyHostInterface &obj);
00175   virtual bool   get_range   (PropertyHostInterface &obj, double &minimum, double &maximum, double &stepping) { return false; }
00176 };
00177 template<class Class, typename Type> inline Property*
00178 create_property (void (Class::*setter) (Type), Type (Class::*getter) () const,
00179                  const char *ident, const char *label, const char *blurb, const char *hints)
00180 {
00181   static const TypeCode etype = TypeCode::from_enum<Type>();
00182   return new PropertyEnum<Class,Type> (setter, getter, ident, label, blurb, etype, hints);
00183 }
00184 
00185 /* --- implementations --- */
00186 /* bool property implementation */
00187 template<class Class>
00188 PropertyBool<Class>::PropertyBool (void (Class::*csetter) (bool), bool (Class::*cgetter) () const,
00189                                    const char *cident, const char *clabel, const char *cblurb,
00190                                    const char *chints) :
00191   Property (cident, clabel, cblurb, chints),
00192   setter (csetter),
00193   getter (cgetter)
00194 {}
00195 
00196 template<class Class> void
00197 PropertyBool<Class>::set_value (PropertyHostInterface &obj, const String &svalue)
00198 {
00199   bool b = string_to_bool (svalue);
00200   Class *instance = dynamic_cast<Class*> (&obj);
00201   (instance->*setter) (b);
00202 }
00203 
00204 template<class Class> String
00205 PropertyBool<Class>::get_value (PropertyHostInterface &obj)
00206 {
00207   Class *instance = dynamic_cast<Class*> (&obj);
00208   bool b = (instance->*getter) ();
00209   return string_from_bool (b);
00210 }
00211 
00212 /* range property implementation */
00213 template<class Class, typename Type>
00214 PropertyRange<Class,Type>::PropertyRange (void (Class::*csetter) (Type), Type (Class::*cgetter) () const,
00215                                           const char *cident, const char *clabel, const char *cblurb,
00216                                           Type cminimum_value, Type cmaximum_value,
00217                                           Type cstepping, const char *chints) :
00218   Property (cident, clabel, cblurb, chints),
00219   minimum_value (cminimum_value),
00220   maximum_value (cmaximum_value),
00221   stepping (cstepping),
00222   setter (csetter),
00223   getter (cgetter)
00224 {
00225   AIDA_ASSERT (minimum_value <= maximum_value);
00226   AIDA_ASSERT (minimum_value + stepping <= maximum_value);
00227 }
00228 
00229 template<class Class, typename Type> void
00230 PropertyRange<Class,Type>::set_value (PropertyHostInterface &obj, const String &svalue)
00231 {
00232   Type v = string_to_type<Type> (svalue);
00233   Class *instance = dynamic_cast<Class*> (&obj);
00234   (instance->*setter) (v);
00235 }
00236 
00237 template<class Class, typename Type> String
00238 PropertyRange<Class,Type>::get_value (PropertyHostInterface &obj)
00239 {
00240   Class *instance = dynamic_cast<Class*> (&obj);
00241   Type v = (instance->*getter) ();
00242   return string_from_type<Type> (v);
00243 }
00244 
00245 template<class Class, typename Type> bool
00246 PropertyRange<Class,Type>::get_range (PropertyHostInterface &obj, double &minimum, double &maximum, double &vstepping)
00247 {
00248   minimum = minimum_value, maximum = maximum_value, vstepping = stepping;
00249   return true;
00250 }
00251 
00252 /* string property implementation */
00253 template<class Class>
00254 PropertyString<Class>::PropertyString (void (Class::*csetter) (const String&), String (Class::*cgetter) () const,
00255                                        const char *cident, const char *clabel, const char *cblurb,
00256                                        const char *chints) :
00257   Property (cident, clabel, cblurb, chints),
00258   setter (csetter),
00259   getter (cgetter)
00260 {}
00261 
00262 template<class Class> void
00263 PropertyString<Class>::set_value (PropertyHostInterface &obj, const String &svalue)
00264 {
00265   Class *instance = dynamic_cast<Class*> (&obj);
00266   (instance->*setter) (svalue);
00267 }
00268 
00269 template<class Class> String
00270 PropertyString<Class>::get_value (PropertyHostInterface &obj)
00271 {
00272   Class *instance = dynamic_cast<Class*> (&obj);
00273   return (instance->*getter) ();
00274 }
00275 
00276 /* enum property implementation */
00277 template<class Class, typename Type>
00278 PropertyEnum<Class,Type>::PropertyEnum (void (Class::*csetter) (Type), Type (Class::*cgetter) () const,
00279                                         const char *cident, const char *clabel, const char *cblurb,
00280                                         const TypeCode &etype, const char *chints) :
00281   Property (cident, clabel, cblurb, chints),
00282   enum_type (etype),
00283   setter (csetter),
00284   getter (cgetter)
00285 {}
00286 
00287 template<class Class, typename Type> void
00288 PropertyEnum<Class,Type>::set_value (PropertyHostInterface &obj, const String &svalue)
00289 {
00290   String error_string;
00291   uint64 value = enum_type.enum_parse (svalue.c_str(), &error_string);
00292   // if (0 && error_string.size() && !value && string_has_int (svalue))
00293   //   value = enum_type.constrain (string_to_int (svalue));
00294   if (!error_string.empty())
00295     print_warning (String() + __PRETTY_FUNCTION__ + ": invalid enum value name '" + enum_type.name() + "': " + error_string);
00296   Type v = Type (value);
00297   Class *instance = dynamic_cast<Class*> (&obj);
00298   (instance->*setter) (v);
00299 }
00300 
00301 template<class Class, typename Type> String
00302 PropertyEnum<Class,Type>::get_value (PropertyHostInterface &obj)
00303 {
00304   Class *instance = dynamic_cast<Class*> (&obj);
00305   Type v = (instance->*getter) ();
00306   return enum_type.enum_string (v);
00307 }
00308 
00309 } } // Rapicorn::Aida
00310 
00311 #endif  // __RAPICORN_AIDA_PROPS_HH__
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines