[Debian-astro-commits] [gyoto] 136/221: Document Object class
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 bca056121fdfa7d741fa2ef84fc8a61c1c63dda8
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date: Tue Dec 9 14:27:56 2014 +0100
Document Object class
---
doc/doxyfile.in | 6 +-
include/GyotoObject.h | 239 +++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 211 insertions(+), 34 deletions(-)
diff --git a/doc/doxyfile.in b/doc/doxyfile.in
index 3860d5f..abe596a 100644
--- a/doc/doxyfile.in
+++ b/doc/doxyfile.in
@@ -1210,13 +1210,13 @@ ENABLE_PREPROCESSING = YES
# compilation will be performed. Macro expansion can be done in a controlled
# way by setting EXPAND_ONLY_PREDEF to YES.
-MACRO_EXPANSION = NO
+MACRO_EXPANSION = YES
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
# then the macro expansion is limited to the macros specified with the
# PREDEFINED and EXPAND_AS_DEFINED tags.
-EXPAND_ONLY_PREDEF = NO
+EXPAND_ONLY_PREDEF = YES
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
# in the INCLUDE_PATH (see below) will be search if a #include is found.
@@ -1251,7 +1251,7 @@ PREDEFINED = DOXYGEN_RUN
# The macro definition that is found in the sources will be used.
# Use the PREDEFINED tag if you want to use a different macro definition.
-EXPAND_AS_DEFINED =
+EXPAND_AS_DEFINED = GYOTO_OBJECT
# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
# doxygen's preprocessor will remove all function-like macros that are alone
diff --git a/include/GyotoObject.h b/include/GyotoObject.h
index fec7ff9..02c3f31 100644
--- a/include/GyotoObject.h
+++ b/include/GyotoObject.h
@@ -1,6 +1,6 @@
/**
* \file GyotoObject.h
- * \brief Introspectbale objects
+ * \brief Introspectable objects
*/
/*
@@ -38,48 +38,177 @@ namespace Gyoto {
}
/// Declare class::properties and class::getProperties()
+/**
+ * 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
+ * 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.
+ */
#define GYOTO_OBJECT \
static Property const properties[]; \
virtual Property const * getProperties() const
+/// Object with properties
/**
- * \brief Object with properties
+ * The Object API allows declaring a list of Properties that can be
+ * set and retrieved using a common, text-based interface. This
+ * interface simplifies a lot how to read and write XML, as well as
+ * writing bindings for interpreted langages (e.g. the Yorick
+ * interface).
+ *
+ * In fact, any class member that has an interface implemented as a
+ * Property can be readily read and written from/to XML as well as
+ * from the Yorick plug-in, without the need for any additional code.
+ *
+ * To declare a Property list:
+ * 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
+ * class declaration (in the .h file):
+ * \code
+ * class A: public Object {
+ * public:
+ * GYOTO_OBJECT;
+ * A();
+ * virtual ~A();
+ * ...
+ * };
+ * \endcode
+ * 3. call the various GYOTO_PROPERTY_* macros in the corresponding
+ * .C file (see the documentation of the Property class).
+ *
+ * It is possible to get a Property by name (Assume \a A is a class
+ * deriving from Object):
+ * \code
+ * A myobj();
+ * Property const *prop=NULL;
+ * prop = myobj.property("PropertyName");
+ * if (!prop) throwError("No Property by that name in this object");
+ * \endcode
+ * It then becomes possible to set or get the Property from or to a
+ * Value:
+ * \code
+ * myobj.set(*prop, size_t(12));
+ * size_t val = myobj.get(*prop);
+ * \endcode
+ * Of course the type of the Value instance and of the Property
+ * instance must match. Refer to the documentation of these to classes
+ * for details.
+ *
*/
class Gyoto::Object
{
protected:
+ /// The "kind" that is output in the XML entity
+ /**
+ * E.g. for an Astrobj, fillElement() will ensure
+ * \code
+ * <Astrobj kind="kind_">...</Astrobj>
+ * \endcode
+ * is written.
+ */
std::string kind_;
public:
GYOTO_OBJECT;
+
+ /// Constructor setting kind
Object (std::string const &kind) ;
+
+ /// Default constructor
Object () ;
+
+ /// Deep copy constructor
Object (Object const &orig) ;
+
+ /// Virtual destructor
virtual ~Object();
+
+ /// Set Value of a Property
void set(Property const &p, Value val);
+
+ /// Set Value (expressed in unit) of a Property
void set(Property const &p, Value val, std::string const &unit);
+ /// Get Value of a Property
Value get(Property const &p) const;
+
+ /// Get Value of a Property, converted to unit
Value get(Property const &p, std::string const &unit) const;
+ /// Find property by name
+ /**
+ * Look into the Property list for a Property whose \a name (or
+ * \a name_false, for a boolean Property) is \a pname. Return a const
+ * pointer to the first such property found, or NULL if none is
+ * found.
+ */
Property const * property(std::string const pname) const;
#ifdef GYOTO_USE_XERCES
- virtual void fillProperty(Gyoto::FactoryMessenger *fmp, Property const &p) const ;
+ /// Output a single Property to XML
+ /**
+ * The base implementation decides what to do based on the \a
+ * p.type. The format matches how setParameters() an setParameter()
+ * would interpret the XML descition.
+ *
+ * Overriding this method should be avoided, but makes sense in some
+ * cases (for instance Screen::fillProperty() selects a different
+ * unit for \a Distance based on its magnitude, so that stellar
+ * sizes are expressed in solar radii while smaller sizes can be
+ * expressed in meters and larger sizes in parsecs).
+ *
+ * Overriding implementation should fall-back on calling the
+ * implementation in the direct parent class:
+ * \code
+ * class A: public Object {};
+ * class B: public A {
+ * using B::setParameter;
+ * virtual void fillProperty(Gyoto::FactoryMessenger *fmp,
+ * Property const &p) const ;
+ * };
+ * void B::fillProperty(Gyoto::FactoryMessenger *fmp,
+ * Property const &p) const {
+ * if (name=="Duff") fmp->doSomething();
+ * else A::fillProperty(fmp, p);
+ * }
+ * \endcode
+ */
+ virtual void fillProperty(Gyoto::FactoryMessenger *fmp,
+ Property const &p) const ;
- /// Called from Factory
+ /// Fill the XML element for this Object
/**
- * Object implementations should impement fillElement to save their
- * parameters to XML and call the Metric::fillElement(fmp) for the
- * shared properties
+ * The base implementation simply calls fillProperty() for each
+ * Property defined for the Object.
+ *
+ * Derived classes should avoid overriding fillElement(). It may
+ * make sense occasionally, e.g. to make sure that the metric is
+ * output first.
+ *
+ * To customize how a given Property is rendered, it is better to
+ * override fillProperty().
+ *
+ * If this method is overriden, the implementation should in general
+ * call fillElement() on the direct base.
*/
virtual void fillElement(Gyoto::FactoryMessenger *fmp) const ;
+
+ /// \brief Main loop for parsing Properties from XML description
/**
- * \brief Main loop in Subcontractor_t function
+ * This function queries the FactoryMessenger for elements to parse,
+ * and tries to matche each element to a Property to set it
+ * accordingly.
+ *
+ * Any class that tries to be buildable from XML must supply a
+ * subcontractor (for base classes such as Metric, Astrobj, Spectrum
+ * and Spectrometer, it is done as a template that must be
+ * specialized for each class).
*
- * The Subcontractor_t function for each Metric kind should look
- * somewhat like this (templated as
- * Gyoto::Metric::Subcontractor<MyKind>):
+ * This subcontractor typically looks somewhat like this:
\code
SmartPointer<Metric::Generic>
Gyoto::Metric::MyKind::Subcontractor(FactoryMessenger* fmp) {
@@ -89,32 +218,48 @@ Gyoto::Metric::MyKind::Subcontractor(FactoryMessenger* fmp) {
}
\endcode
*
- * Each metric kind should implement setParameter(string name,
- * string content, string unit) to interpret the individual XML
- * elements. setParameters() can be overloaded in case the specific
- * Metric class needs low level access to the FactoryMessenger. See
- * Gyoto::Astrobj::UniformSphere::setParameters().
+ * Although this is discouraged, it is possible to override the
+ * following functions to customize how XML entities are parsed:
+ * - setParameters() if low-level access to the
+ * FactoryMessenger is required;
+ * - setParameter(std::string name,
+ * std::string content,
+ * std::string unit)
+ * to interpret an entity that does not match a Property
+ * (e.g. alternative name);
+ * - setParameter(Gyoto::Property const &p,
+ * std::string const &name,
+ * std::string const &content,
+ * std::string const &unit)
+ * to change how a Property is interpreted.
*/
virtual void setParameters(Gyoto::FactoryMessenger *fmp) ;
#endif
/**
* \brief Set parameter by name
*
- * Assume MyKind is a subclass of Metric::Generic which has two
- * members (a string StringMember and a double DoubleMember):
-\code
-int MyKind::setParameter(std::string name, std::string content, std::string unit) {
- if (name=="StringMember") setStringMember(content);
- else if (name=="DoubleMember") setDoubleMemeber(atof(content.c_str()), unit);
- else return Generic::setParameter(name, content, unit);
- return 0;
-}
-\endcode
- * If MyKind is not a direct subclass of Generic, it should call the
- * corresponding setParameter() implementation instead of
- * Generic::setParameter().
+ * This function is used when parsing an XML description, if no
+ * Property of this \a name is found. Overriding implementation should
+ * fall-back on calling the direct's parent implementation:
+ *
+ * \code
+ * class A: public Object {};
+ * class B: public A {
+ * using B::setParameter;
+ * virtual int setParameter(std::string name,
+ * std::string content,
+ * std::string unit);
+ * };
+ * int B::setParameter(std::string name,
+ * std::string content,
+ * std::string unit) {
+ * if (name=="Duff") doSomething(content, unit);
+ * else return A::setParameter(name, content, unit);
+ * return 0; // name was known
+ * }
+ * \endcode
*
- * \param name XML name of the parameter
+ * \param name XML name of the parameter (XML entity)
* \param content string representation of the value
* \param unit string representation of the unit
* \return 0 if this parameter is known, 1 if it is not.
@@ -123,7 +268,39 @@ int MyKind::setParameter(std::string name, std::string content, std::string unit
std::string content,
std::string unit);
- virtual void setParameter(Gyoto::Property const &p,
+ /**
+ * \brief Set parameter by Property (and name)
+ *
+ * This function is used when parsing an XML description, if
+ * Property (\a p) of this \a name is found (i.e. either \a p.name or
+ * \a p.name_false is equal to \a name). Implementation should fall-back
+ * on calling the direct's parent implementation:
+ *
+ * \code
+ * class A: public Object {};
+ * class B: public A {
+ * using B::setParameter;
+ * virtual void setParameter(Gyoto::Property const &p,
+ * std::string name,
+ * std::string content,
+ * std::string unit);
+ * };
+ * void B::setParameter(Gyoto::Property const &p,
+ * std::string name,
+ * std::string content,
+ * std::string unit) {
+ * if (name=="Duff") doSomething(content, unit);
+ * else A::setParameter(p, name, content, unit);
+ * }
+ * \endcode
+ *
+ * \param p Property that matches \a name (\a p.name == \a name or
+ * \a p.name_false == \a name)
+ * \param name XML name of the parameter (XML entity)
+ * \param content string representation of the value
+ * \param unit string representation of the unit
+ */
+ virtual void setParameter(Gyoto::Property const &p,
std::string const &name,
std::string const &content,
std::string const &unit);
--
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