Currently, we create a class per property type, overriding the get and set methods, which are usually just calls back to the owner class's methods. Most (not all) of these could be replaced or helped by a template helper class:
Code: Select all
template <class C, class T>
class PropertyImp : public Property
{
public:
typedef T (C::*GetFunction)() const;
typedef void (C::*SetFunction)(T);
public:
PropertyImp(
const String& name,
const String& help,
GetFunction getter,
SetFunction setter,
const String& defaultValue = "",
bool writesXML = true)
: Property(name, help, defaultValue, writesXML),
d_getter(getter),
d_setter(setter)
{
}
String get(const PropertyReceiver* receiver) const
{
T prop = (static_cast<const C*>(receiver)->*d_getter)();
return PropertyImpHelper::anyToString<T>(prop);
}
void set(PropertyReceiver* receiver, const String& value)
{
T prop = PropertyImpHelper::stringToAny<T>(value);
(static_cast<C*>(receiver)->*d_setter)(prop);
}
private:
GetFunction d_getter;
SetFunction d_setter;
};
It could then be used to streamline the class creation:
Code: Select all
class ContentPaneAutoSized2 : public PropertyImp<ScrolledContainer, bool>
{
public:
ContentPaneAutoSized2();
};
ContentPaneAutoSized2::ContentPaneAutoSized2()
: PropertyImp<ScrolledContainer, bool>(
"ContentPaneAutoSized",
"Property to get/set the setting which controls whether the content pane will auto-size itself. Value is either \"True\" or \"False\".",
&ScrolledContainer::isContentPaneAutoSized,
&ScrolledContainer::setContentPaneAutoSized,
"True")
{
}
ContentPaneAutoSized2 d_autoSizedProperty2;
Alternatively, even more streamlined in this case is ditch the class, and just use:
Code: Select all
PropertyImp<ScrolledContainer, bool> d_autoSizedProperty1(
"ContentPaneAutoSized",
"Property to get/set the setting which controls whether the content pane will auto-size itself. Value is either \"True\" or \"False\".",
&ScrolledContainer::isContentPaneAutoSized,
&ScrolledContainer::setContentPaneAutoSized,
"True");
This simple class would eliminate the need for most of the glue code that currently exists. The only issue is converting string to 'T', which can be solved by specialising stringToAny and anyToString functions for each basic type. These will just call the standard PropertyHelper functions. If this was in a namespace (above named PropertyImpHelper), client code could even re-open it, and specialise their own stringToAny/anyToString functions for their own types. I believe this would allow the use of the helper class even when the get/set return user defined types.