ItemInfo.hpp File Reference
#include "Item.hpp"
#include "ItemRegistry.hpp"
#include "PropertyAccessor.hpp"

## Macros

#define ATTRIBUTE_DEFAULT_VALUE(propname, valexpr)

#define ATTRIBUTE_DISPLAYED_IF(propname, boolexpr)

#define ATTRIBUTE_INSERT(propname, valexpr)

#define ATTRIBUTE_MAX_VALUE(propname, valstring)

#define ATTRIBUTE_MIN_VALUE(propname, valstring)

#define ATTRIBUTE_QUANTITY(propname, quantityname)

#define ATTRIBUTE_RELEVANT_IF(propname, boolexpr)

#define ATTRIBUTE_REQUIRED_IF(propname, boolexpr)

#define ATTRIBUTE_SUB_PROPERTIES_HERE(itemtype)

#define ATTRIBUTE_TYPE_ALLOWED_IF(itemtype, boolexpr)

#define ATTRIBUTE_TYPE_DISPLAYED_IF(itemtype, boolexpr)

#define ATTRIBUTE_TYPE_INSERT(itemtype, valexpr)

#define ENUM_DEF(enumtype, ...)

#define ENUM_END()

#define ENUM_VAL(enumtype, enumvalue, title)

#define ITEM_ABSTRACT(itemtype, basetype, title)

#define ITEM_CONCRETE(itemtype, basetype, title)

#define ITEM_END()

#define PROPERTY_BOOL(propname, title)

#define PROPERTY_DOUBLE(propname, title)

#define PROPERTY_DOUBLE_LIST(propname, title)

#define PROPERTY_ENUM(propname, enumtype, title)

#define PROPERTY_INT(propname, title)

#define PROPERTY_ITEM(propname, itemtype, title)

#define PROPERTY_ITEM_LIST(propname, itemtype, title)

#define PROPERTY_STRING(propname, title)

## Detailed Description

The ItemInfo macros provided in this header file are used in the C++ class definition of a client Item subclass to declare metadata for the class and for its discoverable properties. Assuming that all Item subclasses in a given inheritance tree properly use these macros to declare their discoverable properties, a SMILE schema definition can be derived from the metadata generated by the macros. This schema definition can then be used to save and restore a hierarchy of client items to and from a SMILE data set in XML format. Alternatively, the schema definition itself can be saved to an XML representation for use in a generic SMILE tool as described above. Refer to the documentation of the Item class for more information on client items and their use.

Using the ItemInfo macros

The C++ class definition of each client Item subclass must declare metadata for the class and for its discoverable properties (if there are any) through the macros provided here. There are macros to declare four kinds of objects:

• The ITEM macros declare the item defined by the subclass in which they reside, including the immediate base class and a human readable description.
• The PROPERTY macros declare a discoverable property of the item, including the property name and type and a human readable description.
• The ATTRIBUTE macros declare an attribute of the item or of the most recently declared property, such as for example a default value.
• The ENUM macros declare an enumeration type that can be used as the type for a discoverable property.

Each PROPERTY macro generates the following items in the class definition:

• A private data member declaration for the property, using the property name with an underscore prefix. This data member can be read and written in the class implementation; however it is recommended to treat the data member read-only, except in very rare cases.
• A public getter for the property value, using the property name. This getter can be freely used inside and outside the class implementation.
• A brief Doxygen comment block for the getter, including the human readable string provided as a macro argument. To provide additional documentation for a property, place an appropriate Doxygen comment block after the ItemInfo macros as shown below.
• A private setter with an undocumented name used by the SMILE library to initialize the property value when constructing a new SMILE item hierarchy. The SMILE library guarantees that the property value after construction conforms to the requirements listed in the SMILE schema (such as range limits and default values). The private scope helps ensure that this guarantee is not inadvertently broken by client code. If a public or protected setter is absolutely required, it can be seperately provided.
• A private and undocumented function to load the metadata used by the SMILE library when deriving a SMILE schema for this client Item class hierarchy.

The ItemInfo macro invocations must be placed at the top of the class definition. If any of the discoverable properties use an enumeration type, these types must be declared first. It is not possible to use an enumeration type declared in another class or scope. For each enumeration type, the declaration sequence is as follows:

• A regular Doxygen comment block documenting the enumeration type
• The ENUM_DEF macro
• One or more ENUM_VAL macros
• The ENUM_END macro

The item, property, and attribute declarations are placed after any enumeration type declarations, in the following order:

• The ITEM_ABSTRACT or ITEM_CONCRETE macro followed by zero or more ATTRIBUTE macros that apply to this item
• Zero or more property blocks, each consisting of a PROPERTY macro followed by zero or more ATTRIBUTE macros that apply to this property
• The ITEM_END macro

It is not allowed to place other C++ statements between the ItemInfo macros. Also, it is not allowed to place Doxygen comment blocks between the ItemInfo macros, other than comment blocks documenting an enumeration type as mentioned above. To provide additional documentation for a property, place a Doxygen comment block after the last ItemInfo macro with an explicit reference to the documented property as shown in the example below.

Conditionals

The SMILE system supports dynamically adjusting displayed options and default values to choices made earlier in the configuration process. These earlier choices may represent various aspects of the configuration, including the level of expertise selected by the user, some overall mode configured early on, or the value of the option just preceding this one.

When processing a SMILE dataset, the system maintains two sets of names with a different scope. The global set contains names that stay around for the duration of the configuration session. The local set contains names that stay around only while considering the properties of a particular type; a fresh local set is created for each type instance. By definition, the global set contains names that start with an uppercase letter, and the local set contains names that start with a lowercase letter. As a result, the two sets form disjoint namespaces. After the first character (which must be a letter), a name can include any mix of letters and digits (and no other characters).

Names are never removed from a set (although the current local set is regularly discarded and replaced by a new one as a whole). Names are inserted in each of these sets as the dataset gets processed according to the rules set forth by the SMILE specification. Boolean expressions and conditional value expressions can then be evaluated as they occur in type and property attributes, replacing names contained in one of the sets by true, and other names by false.

Example

class ColorDecorator : public ShapeDecorator
{
/// This enumeration lists the supported colors. Select 'Custom' to allow
/// specifying arbitrary red, green, and blue intensities.
ENUM_DEF(Color, White, Red, Green, Blue, Custom)
ENUM_VAL(Color, White, "the white color")
ENUM_VAL(Color, Red, "the red color")
ENUM_VAL(Color, Green, "the green color")
ENUM_VAL(Color, Blue, "the blue color")
ENUM_VAL(Color, Custom, "a custom RGB color")
ENUM_END()

ITEM_CONCRETE(ColorDecorator, ShapeDecorator, "a decorator that sets the color of a shape")
PROPERTY_ENUM(color, Color, "the color of the decorated shape")
PROPERTY_DOUBLE_LIST(rgb, "the red, green, blue intensities of the decorated shape")
ATTRIBUTE_RELEVANT_IF(rgb, "colorCustom")
ITEM_END()

/// \fn rgb
/// This is extra documentation for the \em rgb property.
...
};


Configuring Doxygen for the ItemInfo macros

To properly document the functions generated by the ItemInfo macros, set the following tags in the Doxygen configuration file:

EXCLUDE_SYMBOLS  = ii_*
MACRO_EXPANSION  = YES
INCLUDE_PATH     = schema
ALIASES          = function{1}="\fn \1 \n"


The first setting causes the private and undocumented "item info" functions to be excluded from the Doxygen output. The second setting causes Doxygen to parse the source code expansion of macros looking for comment blocks. This allows the macros provided here to automatically document the getters for discoverable properties. The include path should be set to the directory containing the ItemInfo.hpp file. The function alias is defined to allow terminating the fn command argument with a newline character without actually placing the remaining text in the comment block on the next line. This is used by the Doxygen documentation blocks inside the macro definitions, because the Doxygen preprocessor always places the complete contents of a macro expansion on a single line.

## ◆ ATTRIBUTE_DEFAULT_VALUE

 #define ATTRIBUTE_DEFAULT_VALUE ( propname, valexpr )

This macro sets the default value for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the default value (as a quoted string) in the form of a conditional value expression, which is evaluated against the names in the current global and local name sets. Each value in the conditional expression must have a format that can be properly converted to the property data type.

## ◆ ATTRIBUTE_DISPLAYED_IF

 #define ATTRIBUTE_DISPLAYED_IF ( propname, boolexpr )

This macro sets the displayedIf attribute for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the Boolean expression to be set as the displayedIf attribute value (as a quoted string). In other words, the property will be displayed only if the specified Boolean expression evaluates to true against the names in the current global and local name sets.

## ◆ ATTRIBUTE_INSERT

 #define ATTRIBUTE_INSERT ( propname, valexpr )

This macro sets the insert attribute for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the conditional value expression to be set as the insert attribute value (as a quoted string). The value of the expression (after evaluation against the names in the current global and local name sets) provides a list of extra names to be inserted in the global and/or local name set when a value is entered for this property, in addition to the name automatically associated with the property.

## ◆ ATTRIBUTE_MAX_VALUE

 #define ATTRIBUTE_MAX_VALUE ( propname, valstring )

This macro sets the maximum value for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the maximum value (as a quoted string) in a format that can be properly converted to the property data type.

## ◆ ATTRIBUTE_MIN_VALUE

 #define ATTRIBUTE_MIN_VALUE ( propname, valstring )

This macro sets the minimum value for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the minimum value (as a quoted string) in a format that can be properly converted to the property data type.

## ◆ ATTRIBUTE_QUANTITY

 #define ATTRIBUTE_QUANTITY ( propname, quantityname )

This macro sets the name of the physical quantity represented by this double or double list property. The first argument repeats the property name (as an identifier). The second argument specifies the quantity name (as a quoted string). The specified quantity name must match one of the quantity names provided in the schema definition and determines the allowed and default units for the property values. Refer to the documentation of the UnitDef and ItemRegistry classes for more information. If the specified string is empty, or if this attribute is omitted, the property values are dimensionless.

## ◆ ATTRIBUTE_RELEVANT_IF

 #define ATTRIBUTE_RELEVANT_IF ( propname, boolexpr )

This macro sets the relevantIf attribute for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the Boolean expression to be set as the relevantIf attribute value (as a quoted string). In other words, the property will be relevant only if the specified Boolean expression evaluates to true against the names in the current global and local name sets.

## ◆ ATTRIBUTE_REQUIRED_IF

 #define ATTRIBUTE_REQUIRED_IF ( propname, boolexpr )

This macro sets the requiredIf attribute for the most recently declared property. The first argument repeats the property name (as an identifier). The second argument specifies the Boolean expression to be set as the requiredIf attribute value (as a quoted string). In other words, the property is required if the specified Boolean expression evaluates to true against the names in the current global and local name sets, and optional otherwise.

## ◆ ATTRIBUTE_SUB_PROPERTIES_HERE

 #define ATTRIBUTE_SUB_PROPERTIES_HERE ( itemtype )

This macro sets the subPropertyIndex attribute for the item type being declared to a value depending on the position of the macro in the list of property definitions. As a result, properties of subtypes will be listed at the position where the macro appears. If the macro does not occur, by default properties of subtypes are listed after all properties of the base type. The macro's first and only argument repeats the type name.

## ◆ ATTRIBUTE_TYPE_ALLOWED_IF

 #define ATTRIBUTE_TYPE_ALLOWED_IF ( itemtype, boolexpr )

This macro sets the allowedIf attribute for the item type being declared. The first argument repeats the type name. The second argument specifies the Boolean expression to be set as the allowedIf attribute value (as a quoted string). The values of allowedIf attributes for all direct and indirect base types of this type are ANDed with this value. The final value (after evaluation against the names in the current global and local name sets) indicates whether this type is allowed in that dataset.

## ◆ ATTRIBUTE_TYPE_DISPLAYED_IF

 #define ATTRIBUTE_TYPE_DISPLAYED_IF ( itemtype, boolexpr )

This macro sets the displayedIf attribute for the item type being declared. The first argument repeats the type name. The second argument specifies the Boolean expression to be set as the displayedIf attribute value (as a quoted string). The values of displayedIf attributes for all direct and indirect base types of this type are ANDed with this value. The final value (after evaluation against the names in the current global and local name sets) indicates whether this type is displayed as one of the choices.

## ◆ ATTRIBUTE_TYPE_INSERT

 #define ATTRIBUTE_TYPE_INSERT ( itemtype, valexpr )

This macro sets the insert attribute for the item type being declared. The first argument repeats the type name. The second argument specifies the conditional value expression to be set as the insert attribute value (as a quoted string). The value of the expression (after evaluation against the names in the current global and local name sets) provides a list of extra names to be inserted in the global and/or local name set when an item of this type is added to the dataset, in addition to the names of the type and its ancestors.

## ◆ ENUM_DEF

 #define ENUM_DEF ( enumtype, ... )

This macro declares a scoped enumeration type (enum class) that can be used as the data type of a discoverable property. The first argument specifies the enumeration type name (as an identifier). The subsequent arguments (there must be at least one) specify the enumeration values (as identifiers) for the type. The ENUM_DEF invocation must be followed by an ENUM_VAL invocation for each of the enumeration values in the list, in the same order, and by an ENUM_END invocation to terminate the sequence.

## ◆ ENUM_END

 #define ENUM_END ( )

This macro marks the end of the sequence started by an ENUM_DEF invocation to declare an enumeration type.

## ◆ ENUM_VAL

 #define ENUM_VAL ( enumtype, enumvalue, title )

This macro declares one of the values of an enumeration type declared with the ENUM_DEF macro. The first argument repeats the enumeration type name (as an identifier). The second argument specifies the enumeration value being declared by this macro invocation (as an identifier). The third argument provides a human readable description for the enumeration value (as a quoted string).

## ◆ ITEM_ABSTRACT

 #define ITEM_ABSTRACT ( itemtype, basetype, title )

This macro starts the ItemInfo metadata section for an abstract SMILE item type. An abstract type serves as the base type for other types. It is impossible to construct an instance of an abstract type. The first argument specifies the name of the class in which this macro invocation occurs (as an identifier). The class name corresponds to the type name of the SMILE items represented by the class. The second argument specifies the name of the immediate base class of this class (as an identifier). The third argument provides a human readable description for items of this type (as a quoted string).

## ◆ ITEM_CONCRETE

 #define ITEM_CONCRETE ( itemtype, basetype, title )

This macro starts the ItemInfo metadata section for a concrete SMILE item type. In other words, actual item instances of this type can be constructed. On rare occasions, a concrete type can also serve as the base type for another concrete type. The first argument specifies the name of the class in which this macro invocation occurs (as an identifier). The class name corresponds to the type name of the SMILE items represented by the class. The second argument specifies the name of the immediate base class of this class (as an identifier). The third argument provides a human readable description for items of this type (as a quoted string).

## ◆ ITEM_END

 #define ITEM_END ( )

This macro marks the end of the ItemInfo metadata section.

## ◆ PROPERTY_BOOL

 #define PROPERTY_BOOL ( propname, title )

This macro declares a Boolean property. The first argument specifies the name of the property (as an identifier). The second argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_DOUBLE

 #define PROPERTY_DOUBLE ( propname, title )

This macro declares a double property (floating point value). The first argument specifies the name of the property (as an identifier). The second argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_DOUBLE_LIST

 #define PROPERTY_DOUBLE_LIST ( propname, title )

This macro declares a double list property (list of floating point values). The first argument specifies the name of the property (as an identifier). The second argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_ENUM

 #define PROPERTY_ENUM ( propname, enumtype, title )

This macro declares an enumeration property. The first argument specifies the name of the property (as an identifier). The second argument specifies the name of the enumeration type (as an identifier). The third argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_INT

 #define PROPERTY_INT ( propname, title )

This macro declares an integer property. The first argument specifies the name of the property (as an identifier). The second argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_ITEM

 #define PROPERTY_ITEM ( propname, itemtype, title )

This macro declares an item property (aggregating pointer to another item). The first argument specifies the name of the property (as an identifier). The second argument specifies the type name of the item being held by this property (as an identifier). The third argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_ITEM_LIST

 #define PROPERTY_ITEM_LIST ( propname, itemtype, title )

This macro declares an item list property (list of aggregating pointers to another item). The first argument specifies the name of the property (as an identifier). The second argument specifies the type name of the items being held by this property (as an identifier). The third argument provides a human readable description for this property (as a quoted string).

## ◆ PROPERTY_STRING

 #define PROPERTY_STRING ( propname, title )

This macro declares a string property. The first argument specifies the name of the property (as an identifier). The second argument provides a human readable description for this property (as a quoted string).