[Debian-astro-commits] [gyoto] 137/221: document Property and Value
Thibaut Jean-Claude Paumard
thibaut at moszumanska.debian.org
Fri May 22 20:52:40 UTC 2015
This is an automated email from the git hooks/post-receive script.
thibaut pushed a commit to branch master
in repository gyoto.
commit fb5078b9c3c295ac72c0b1e5c76962cb269489ec
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date: Tue Dec 9 17:43:19 2014 +0100
document Property and Value
---
doc/doxyfile.in | 4 +-
include/GyotoObject.h | 26 +++++-
include/GyotoProperty.h | 236 ++++++++++++++++++++++++++++++++++++++++++++++--
include/GyotoValue.h | 56 +++++++++++-
lib/Property.C | 6 --
5 files changed, 309 insertions(+), 19 deletions(-)
diff --git a/doc/doxyfile.in b/doc/doxyfile.in
index abe596a..d55054a 100644
--- a/doc/doxyfile.in
+++ b/doc/doxyfile.in
@@ -1244,7 +1244,9 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = DOXYGEN_RUN
+PREDEFINED = DOXYGEN_RUN GYOTO_OBJECT="GYOTO_OBJECT \
+ static Property const properties[]; \
+ virtual Property const * getProperties() const"
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/include/GyotoObject.h b/include/GyotoObject.h
index 02c3f31..dc7faeb 100644
--- a/include/GyotoObject.h
+++ b/include/GyotoObject.h
@@ -41,7 +41,7 @@ namespace Gyoto {
/**
* Any derived class that does define Properties (i.e. the macro
* GYOTO_PROPERTY_START() is called somewhere in the .C file) must
- * call the GYOTO_OBJECT macro in a "public:" section of the class
+ * call the #GYOTO_OBJECT macro in a "public:" section of the class
* declaration. Else, the property list is inherited from the direct
* parent, and calling GYOTO_PROPERTY_START() in the .C file leads to
* a compile-time error.
@@ -66,7 +66,7 @@ namespace Gyoto {
* 1. declare (in the class declaration, .h file) and define (.C
* file) the pair or quadruplet of accessors for your Property
* (see Property class documentation;
- * 2. call the GYOTO_OBJECT macro in in a public section of the
+ * 2. call the #GYOTO_OBJECT macro in in a public section of the
* class declaration (in the .h file):
* \code
* class A: public Object {
@@ -113,6 +113,28 @@ class Gyoto::Object
std::string kind_;
public:
GYOTO_OBJECT;
+ /** \fn virtual Property const * Object::getProperties() const
+ * \brief Get list of properties
+ *
+ * This method is declared automatically by the #GYOTO_OBJECT macro
+ * and defined automatically by the #GYOTO_PROPERTY_END macro.
+ */
+ /** \property static Property const properties[]
+ * \brief Property list
+ *
+ * This static member is declared automatically by the #GYOTO_OBJECT
+ * macro and defined automatically by the #GYOTO_PROPERTY_START,
+ * #GYOTO_PROPERTY_END and GYOTO_PROPERTY_* macros.
+ *
+ * The list of properties is implemented as a static array of
+ * Property instances. The last item in a Property of type
+ * Property::empty_t, which evaluates to false, so the list can be
+ * considered to be NULL-terminated (it is actually rather
+ * false-terminated). This empty_t last item can be a link to
+ * another Property list: for instance, the last item in
+ * Gyoto::Astrobj::Standard::properties is a link to
+ * Gyoto::Astrobj::Generic::properties.
+ */
/// Constructor setting kind
Object (std::string const &kind) ;
diff --git a/include/GyotoProperty.h b/include/GyotoProperty.h
index caf5eb6..cfba481 100644
--- a/include/GyotoProperty.h
+++ b/include/GyotoProperty.h
@@ -1,6 +1,6 @@
/**
- * \file GyotoObject.h
- * \brief Introspectbale objects
+ * \file GyotoProperty.h
+ * \brief Introspectable properties
*/
/*
@@ -41,6 +41,10 @@ namespace Gyoto {
template <class T> class SmartPointer;
}
+/// Start Property list
+/**
+ * \param class Class for which we are defining a Property list
+ */
#define GYOTO_PROPERTY_START(class) \
Property const class::properties[] = {
@@ -168,66 +172,234 @@ namespace Gyoto {
return class::properties; \
}
+/// Property that can be set and got using standard methods
/**
- * \brief Property
+ * The Property API makes it easy to declare the parameters that can
+ * be set in a class.
+ *
+ * Developpers who simply write classes (deriving from
+ * Astrobj::Generic, , Metric::Generic, Spectrum::Generic) need not
+ * know the inners of the Property class and interact with it only
+ * using macros to declare the parameters they need to read from XML.
+ *
+ * To make use of the Property framework, a class
+ * must derive from Gyoto::Object and use the #GYOTO_OBJECT in a
+ * public section of the class declaration (i.e. in the .h
+ * file). Then, in the corresponding .C file, the GYOTO_PROPERTY_*
+ * macros are used as follows (note the absence of punctuation after
+ * the macros):
+ * \code
+ * GYOTO_PROPERTY_START(MyClass)
+ * GYOTO_PROPERTY_<type>(MyClass, PropertyName, accessor)
+ * ...
+ * GYOTO_PROPERTY_END(MyClass, ParentClass::properties)
+ * \endcode
+ *
+ * In the above, #GYOTO_PROPERTY_START starts the definition of the
+ * static member MyClass::properties. Each GYOTO_PROPERTY_<type> macro
+ * declares a new property. #GYOTO_PROPERTY_END ends the definition of
+ * the property list, with an optional pointer to the parent's class
+ * Property list, and defines the MyClass::getProperties() method.
+ *
+ * The underlying accessors must always be defined, both to set and to
+ * get the property. For the sake of simplicity, only a limited number
+ * of data types are allowed:
+ * - double: see #GYOTO_PROPERTY_DOUBLE, #GYOTO_PROPERTY_DOUBLE_UNIT;
+ * - long: see #GYOTO_PROPERTY_LONG;
+ * - unsigned long: see #GYOTO_PROPERTY_UNSIGNED_LONG
+ * (a.k.a. size_t: see #GYOTO_PROPERTY_SIZE_T, this may break on
+ * architectures where size_t is not the same as unsigned long);
+ * - bool: see #GYOTO_PROPERTY_BOOL;
+ * - std::vector<double>: see #GYOTO_PROPERTY_VECTOR_DOUBLE
+ * and #GYOTO_PROPERTY_VECTOR_DOUBLE_UNIT;
+ * - Gyoto::SmartPointers to various base classes: Screen,
+ * Metric::Generic, Astrobj::Generic, Spectrum::Generic and
+ * Spectrometer::Generic. See #GYOTO_PROPERTY_METRIC,
+ * #GYOTO_PROPERTY_SCREEN, #GYOTO_PROPERTY_ASTROBJ,
+ * #GYOTO_PROPERTY_SPECTRUM and #GYOTO_PROPERTY_SPECTROMETER.
+ *
+ * For the floating point data-types (double and vector<double>), two
+ * additional accessors supporting units can be provided. The
+ * accessors must have the same name and have specific prototypes, see
+ * the various function pointer typedefs, e.g. #set_double_t and
+ * #get_double_t.
+ *
+ * The type used in these accessors may not be the same as the type of
+ * the underlying class member. For instance, to read an array, it was
+ * chosen to use the std::vector<double> type because it is easy to
+ * read such a vector from XML and to thus determine dynamically the
+ * number of elements provided. But this type is slow, so it is
+ * expected that the class member will rather be a C-style array
+ * (double arr[]) or something else entirely. It is not forbidden to
+ * have a set of high-level accessors for the Property interface on
+ * top of lower-level, more efficient accessors to be used in
+ * compiled, static code:
+ *
+ * \code
+ * void MyClass::arrayMember(double const * const tab) {
+ * for (int i=0; i<5; ++i) member_[i]=tab[i];
+ * }
+ * void MyClass::arrayMemberVector(std::vector<double> const &vect) {
+ * if (vect.size()!=5) throwError("Please provide 5 elements");
+ * for (int i=0; i<5; ++i) member_[i]=vect[i];
+ * }
+ * double const * MyClass::arrayMember() const {return member_;}
+ * std::vector<double> MyClass::arrayMemberVector() const {
+ * std::vector<double> v(5, 0.);
+ * for (int i=0; i<5; ++i) v[i]=member_[i];
+ * return v;
+ * }
+ * \endcode
+ *
+ * In this example, assuming MyClass is based directly on Object and
+ * member_ is the only parameter to read from XML, the Property list
+ * may be defined as:
+ * \code
+ * GYOTO_PROPERTY_START(MyClass)
+ * GYOTO_PROPERTY_VECTOR_DOUBLE(MyClass, ArrayMember, arrayMemberVector)
+ * GYOTO_PROPERTY_END(MyClass, Object::properties)
+ * \endcode
+ *
+ * Again, nothing more is required to read and write ArrayMember from
+ * XML and from Yorick.
*/
class Gyoto::Property
{
private:
public:
- enum type_e {double_t, long_t, unsigned_long_t, bool_t,
- string_t, filename_t,
- vector_double_t, metric_t, screen_t, astrobj_t, spectrum_t, spectrometer_t,
- empty_t};
+ /// Possible type of a Property instance
+ /**
+ * These are all the values that Property::type may take.
+ */
+ enum type_e {
+ /// Type is double
+ double_t,
+ /// Type is long
+ long_t,
+ /// Type is unsigned long (a.k.a. size_t)
+ unsigned_long_t,
+ /// Type is bool
+ bool_t,
+ /// Type is std::string
+ string_t,
+ /// Type is std::string and holds a file name
+ /**
+ * In this case, the value may be changed to include relative or
+ * absolute path. The prefix "`pwd`/" forces path to be
+ * interpreted relative to the current working directory. If the
+ * value starts with "/", it is interpreted as an absolute
+ * path. Otherwise, when reading from XML, the path is interpreted
+ * relative to the XML file.
+ */
+ filename_t,
+ /// Type is std::vector<double>
+ vector_double_t,
+ /// Type is Gyoto::SmartPointer<Gyoto::Metric::Generic>
+ metric_t,
+ /// Type is Gyoto::SmartPointer<Gyoto::Screen::Generic>
+ screen_t,
+ /// Type is Gyoto::SmartPointer<Gyoto::Astrobj::Generic>
+ astrobj_t,
+ /// Type is Gyoto::SmartPointer<Gyoto::Spectrum::Generic>
+ spectrum_t,
+ /// Type is Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>
+ spectrometer_t,
+ /// Property is empty
+ /**
+ * In this case (and only in this case):
+ * 1. #Gyoto::Property::operator bool() const return false;
+ * 2. Property::parent may be different from NULL and point to
+ * another array of Property instances, that should be
+ * interpreted as appended to this list.
+ */
+ empty_t};
+ /// Name of this instance
std::string name;
+ /// Name if false
+ /**
+ * Only if #type is #empty_t
+ */
std::string name_false;
+ /// Type of this instance
int type;
+ /// Prototype for an accessor to set a double
typedef void (Object::* set_double_t)(double val);
+ /// Prototype for an accessor to get a double
typedef double (Object::* get_double_t)() const;
+ /// Prototype for an accessor to set a double, with unit
typedef void (Object::* set_double_unit_t)(double val,
std::string const &unit);
+ /// Prototype for an accessor to get a double, with unit
typedef double (Object::* get_double_unit_t)(std::string const &unit) const;
+ /// Prototype for an accessor to set a long
typedef void (Object::* set_long_t)(long val);
+ /// Prototype for an accessor to get a long
typedef long (Object::* get_long_t)() const;
+ /// Prototype for an accessor to set an unsigned long
typedef void (Object::* set_unsigned_long_t)(unsigned long val);
+ /// Prototype for an accessor to get an unsigned long
typedef unsigned long (Object::* get_unsigned_long_t)() const;
+ /// Prototype for an accessor to set a bool
typedef void (Object::* set_bool_t)(bool val);
+ /// Prototype for an accessor to get a bool
typedef bool (Object::* get_bool_t)() const;
+ /// Prototype for an accessor to set a string
typedef void (Object::* set_string_t)(std::string const&);
+ /// Prototype for an accessor to get a string
typedef std::string (Object::* get_string_t)() const;
+ /// Prototype for an accessor to set a filename
typedef void (Object::* set_fname_t)(std::string const&);
+ /// Prototype for an accessor to get a filename
typedef std::string (Object::* get_fname_t)() const;
+ /// Prototype for an accessor to set a std::vector<double>
typedef void (Object::* set_vector_double_t)(std::vector<double> const&);
+ /// Prototype for an accessor to get a std::vector<double>
typedef std::vector<double> (Object::* get_vector_double_t)() const;
+ /// Prototype for an accessor to set a std::vector<double>, with unit
typedef void (Object::* set_vector_double_unit_t)(std::vector<double> const&, std::string const &);
+ /// Prototype for an accessor to get a std::vector<double>, with unit
typedef std::vector<double> (Object::* get_vector_double_unit_t)(std::string const &) const;
+ /// Prototype for an accessor to set a Gyoto::SmartPointer<Gyoto::Metric::Generic>
typedef void (Object::* set_metric_t)
(Gyoto::SmartPointer<Gyoto::Metric::Generic>);
+ /// Prototype for an accessor to get a Gyoto::SmartPointer<Gyoto::Metric::Generic>
typedef Gyoto::SmartPointer<Gyoto::Metric::Generic>
(Object::* get_metric_t)() const;
+ /// Prototype for an accessor to set a Gyoto::SmartPointer<Gyoto::Screen>
typedef void (Object::* set_screen_t)
(Gyoto::SmartPointer<Gyoto::Screen>);
+ /// Prototype for an accessor to get a Gyoto::SmartPointer<Gyoto::Screen>
typedef Gyoto::SmartPointer<Gyoto::Screen>
(Object::* get_screen_t)() const;
+ /// Prototype for an accessor to set a Gyoto::SmartPointer<Gyoto::Astrobj::Generic>
typedef void (Object::* set_astrobj_t)
(Gyoto::SmartPointer<Gyoto::Astrobj::Generic>);
+ /// Prototype for an accessor to get a Gyoto::SmartPointer<Gyoto::Astrobj::Generic>
typedef Gyoto::SmartPointer<Gyoto::Astrobj::Generic>
(Object::* get_astrobj_t)() const;
+ /// Prototype for an accessor to set a Gyoto::SmartPointer<Gyoto::Spectrum::Generic>
typedef void (Object::* set_spectrum_t)
(Gyoto::SmartPointer<Gyoto::Spectrum::Generic>);
+ /// Prototype for an accessor to get a Gyoto::SmartPointer<Gyoto::Spectrum::Generic>
typedef Gyoto::SmartPointer<Gyoto::Spectrum::Generic>
(Object::* get_spectrum_t)() const;
+ /// Prototype for an accessor to set a Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>
typedef void (Object::* set_spectrometer_t)
(Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>);
+ /// Prototype for an accessor to get a Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>
typedef Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>
(Object::* get_spectrometer_t)() const;
+ /// Union holding an accessor to set any type
+ /**
+ * Right type is stored in #type
+ */
union setter_t {
set_double_t set_double;
set_long_t set_long;
@@ -241,6 +413,10 @@ class Gyoto::Property
set_spectrum_t set_spectrum;
set_spectrometer_t set_spectrometer;
};
+ /// Union holding an accessor to get any type
+ /**
+ * Right type is stored in #type
+ */
union getter_t {
get_double_t get_double;
get_long_t get_long;
@@ -254,85 +430,127 @@ class Gyoto::Property
get_spectrum_t get_spectrum;
get_spectrometer_t get_spectrometer;
};
+ /// Union holding an accessor to set double or vector<double> with unit
+ /**
+ * Right type is stored in #type
+ */
union setter_unit_t {
set_double_unit_t set_double;
set_vector_double_unit_t set_vdouble;
};
+ /// Union holding an accessor to get double or vector<double> with unit
union getter_unit_t {
get_double_unit_t get_double;
get_vector_double_unit_t get_vdouble;
};
+
+ /// Pointer to the setter method
+ /**
+ * Right type is stored in #type
+ */
setter_t setter;
+ /// Pointer to the getter method
+ /**
+ * Right type is stored in #type
+ */
getter_t getter;
+ /// Pointer to the setter (with unit) method
+ /**
+ * Right type is stored in #type
+ */
setter_unit_t setter_unit;
+ /// Pointer to the getter (with unit) method
+ /**
+ * Right type is stored in #type
+ */
getter_unit_t getter_unit;
+ /// True if #Gyoto::Property::type is not #Gyoto::Property::empty_t
operator bool() const ;
+ /// If #type is #empty_t, link to another Property list
Property const * const parent;
+ /// Constructor for #type==#empty_t
Property(Property const * const ancestor);
+ /// Constructor for #type==#long_t
Property(std::string name,
set_long_t set_long,
get_long_t get_long);
+ /// Constructor for #type==#unsigned_long_t
Property(std::string name,
set_unsigned_long_t set_unsigned_long,
get_unsigned_long_t get_unsigned_long);
+ /// Constructor for #type==#double_t, without unit support
Property(std::string name,
set_double_t set_double,
get_double_t get_double);
+ /// Constructor for #type==#double_t, with unit support
Property(std::string name,
set_double_t set_double,
get_double_t get_double,
set_double_unit_t set_double_unit,
get_double_unit_t get_double_unit);
+ /// Constructor for #type==#bool_t
Property(std::string name,
std::string name_false,
set_bool_t set_bool,
get_bool_t get_bool);
+ /// Constructor for #type==#string_t or #filename_t
+ /**
+ * \param name name of the Property
+ * \param set_string pointer to the setter accessor
+ * \param get_string pointer to the getter accessor
+ * \param is_filename true means #type=#filename_t
+ */
Property(std::string name,
set_string_t set_string,
get_string_t get_string,
bool is_filename);
+ /// Constructor for #type==#vector_double_t, without unit support
Property(std::string name,
set_vector_double_t set_vdouble,
get_vector_double_t get_vdouble);
+ /// Constructor for #type==#vector_double_t, with unit support
Property(std::string name,
set_vector_double_t set_vdouble,
get_vector_double_t get_vdouble,
set_vector_double_unit_t set_vdouble_unit,
get_vector_double_unit_t get_vdouble_unit);
+ /// Constructor for #type==#metric_t
Property(std::string name,
set_metric_t set_metric,
get_metric_t get_metric);
+ /// Constructor for #type==#screen_t
Property(std::string name,
set_screen_t set_screen,
get_screen_t get_screen);
+ /// Constructor for #type==#astrobj_t
Property(std::string name,
set_astrobj_t set_astrobj,
get_astrobj_t get_astrobj);
+ /// Constructor for #type==#spectrum_t
Property(std::string name,
set_spectrum_t set_spectrum,
get_spectrum_t get_spectrum);
+ /// Constructor for #type==#spectrometer_t
Property(std::string name,
set_spectrometer_t set_spectrometer,
get_spectrometer_t get_spectrometer);
- Property const * find(std::string name) const;
-
};
#endif
diff --git a/include/GyotoValue.h b/include/GyotoValue.h
index fb0c57a..46e0447 100644
--- a/include/GyotoValue.h
+++ b/include/GyotoValue.h
@@ -39,56 +39,110 @@ namespace Gyoto {
namespace Spectrometer {class Generic;}
class Screen;
}
-
+/// Container for the value of a Property
+/**
+ * The Value class is very similar to the C union type (although not
+ * as memory efficient): it can hold several type of values, but only
+ * one at a time. Care must be taken to ensure only the member that
+ * was set is retrieved. The purpose of the Value class is to be used
+ * together with the Property class: code determines dynamicaly the
+ * type of a Property, reads the corresponding value appropriateley
+ * (e.g. from XML or from the Yorick prompt), stores the value in a
+ * Value instance, and sets the Property using the Object::set()
+ * method. Likewise, the Object::get() method returns a
+ * Gyoto::Value. Property::type must be used to determine which member
+ * of the Value is meaningful.
+ *
+ * Casting between Value and the various data type it can hold is
+ * normally automatic, but the members can also be accessed
+ * explicitly make code more easy to read and less ambiguous.
+ */
class Gyoto::Value {
public:
+ /// Constructor
Value();
+
+ /// Destructor
~Value();
+ /// Assignement operator
Value& operator=(Value const&);
+ /// A double value
double Double;
+ /// Construct/cast from double
Value(double);
+ /// Cast to double
operator double() const;
+ /// A boolean value
bool Bool;
+ /// Construct/cast from boolean
Value(bool);
+ /// Cast to bool
operator bool() const;
+ /// A long value
long Long;
+ /// Construct/cast from long
Value(long);
+ /// Cast to long
operator long() const;
+ /// An unsigned long (a.k.a. size_t)
unsigned long ULong;
+ /// Construct/cast from unsigned long
Value(unsigned long);
+ /// Cast to unsigned long
operator unsigned long() const;
+ /// A string value
std::string String;
+ /// Construct/cast from string
Value(std::string);
+ /// Cast to string
operator std::string() const;
+ /// A vector of double values
std::vector<double> VDouble;
+ /// Construct/cast from vector of doubles
Value(std::vector<double>);
+ /// Cast to vector of doubles
operator std::vector<double>() const;
+ /// A Metric object
Gyoto::SmartPointer<Gyoto::Metric::Generic> Metric;
+ /// Cast from Metric object
Value(Gyoto::SmartPointer<Gyoto::Metric::Generic>);
+ /// Cast to Metric object
operator Gyoto::SmartPointer<Gyoto::Metric::Generic>();
+ /// An Astrobj Object
Gyoto::SmartPointer<Gyoto::Astrobj::Generic> Astrobj;
+ /// Cast from Astrobj
Value(Gyoto::SmartPointer<Gyoto::Astrobj::Generic>);
+ /// Cast to Astrobj
operator Gyoto::SmartPointer<Gyoto::Astrobj::Generic>();
+ /// A Spectrum object
Gyoto::SmartPointer<Gyoto::Spectrum::Generic> Spectrum;
+ /// Cast from Spectrum
Value(Gyoto::SmartPointer<Gyoto::Spectrum::Generic>);
+ /// Cast to Spectrum
operator Gyoto::SmartPointer<Gyoto::Spectrum::Generic>();
+ /// A Spectrometer object
Gyoto::SmartPointer<Gyoto::Spectrometer::Generic> Spectrometer;
+ /// Cast from Spectrometer
Value(Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>);
+ /// Cast to Spectrometer
operator Gyoto::SmartPointer<Gyoto::Spectrometer::Generic>();
+ /// A Screen object
Gyoto::SmartPointer<Gyoto::Screen> Screen;
+ /// Cast from Screen
Value(Gyoto::SmartPointer<Gyoto::Screen>);
+ /// Cast to Screen
operator Gyoto::SmartPointer<Gyoto::Screen>();
};
diff --git a/lib/Property.C b/lib/Property.C
index e1daf58..720f5b1 100644
--- a/lib/Property.C
+++ b/lib/Property.C
@@ -75,10 +75,4 @@ Property::Property(string n,
getter_unit.get_vdouble=getu;
}
-Property const * Property::find(std::string n) const {
- if (type == empty_t) return parent;
- if (name == n || (type == bool_t && name_false == n)) return this;
- return this + 1;
-}
-
Property::operator bool() const { return type != empty_t; }
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git
More information about the Debian-astro-commits
mailing list