| « MFC: Doc/View & GetActiveDocument |
Parameter Reflection and Serialization
One aspect that C++ annoyingly lacks is reflection. But, it wouldn't be C++ if there was no way of adding some aspects more
ore less explicitly. I chose to add a few basic classes to my projects in order for the parameters one needs to store or ask the user about to be available through some common interface thereby created. All is pretty straigtforeward C++, no magic #defines or ugly stuff like that.
OK, so let's make an example. Say you write an FTP Client class:
/**
* @ingroup DEMOS
* @class MyFTPClient
* @brief A pseudo ftp-client class to demonstrate parameter reflection.
*
* @author Axel Plinge
*/
Ok, now it has to implement the special interface, so let's just derive.
class MyFTPClient: public hasParameterReflection
{
We'll give it some attributes to be reflected.
protected:
AP_String user; /**< username. */
AP_String pass; /**< password. */
AP_String host; /**< hostname. */
long port; /**< port on host. */
All magic is put in the constructor. We'll assign an unique name for the parameter description, i.e. that of the class.
The initializer list is also used for setting default values.
Inside the constructor, we describe the reflected attributes, i.e. parameters, a line each:
public:
MyFTPClient() :
hasParameterReflection("MyFTPClient"),
host("beer"), port(666), user("drinker"), pass("fun")
{
// att. name label tooltip
addParam(host, "host", "hostname", "the hostname of the server.");
addParam(port, "port", "portnumber","the port number of the service.");
addParam(user, "user", "username", "your username on the server.");
addPassW(pass, "pass", "password", "your password on the server.");
}
Well, actually, there should be some FTP functionality in here. but since this is just an example, let's just show the benefits of the reflection. While we are at it, I'll quickly add some persistence
protected:
AP_String pathname; /**< path of xml file holding our parameters. */
public:
/** save all parameters to a single xml file. */
bool saveParameters(const char* newpathname=0)
{
if (newpathname) pathname=newpathname;
AP_ParameterPersister pp;
return pp.save( param() , pathname );
}
/** load all parameters from a single xml file. */
bool loadParameters(const char* newpathname=0)
{
if (newpathname) pathname=newpathname;
AP_ParameterPersister pp;
return pp.load( param() , pathname );
}
};
Ok, Now the magic can happen anywhere, since hasParameterReflection::param() is a public member and all that is required.
Somewhere in a program, we could now write:
MyFTPClient client;
client.loadParameters("C:\\ftp.xml");
CParamsDialog dlg( client.param(), "FTP Preferences" );
dlg.doModal();
client.saveParameters();
Yielding - guess what - a dialog. It looks like this:
When using the simple persistence, we get an xml file (what else?)
<?xml version="1.0" encoding="iso-8859-1"?>
<MyFTPClient>
<host> "guinness"</host>
<port> 4711</port>
<user> "good"</user>
<pass> "ness"</pass>
</MyFTPClient>
Ok, what happened? All that was required after the class definition was this param(). It returns an instance of AP_ParameterGroup which holds the parameters. That Group can enum its AP_Parameter members so anyone can see them. The parameter class is responsible for holding the value, it has the get/set mechanism for that particular value. Each AP_Parameter has an AP_ParameterDescription attached. This description can tell what type, label etc. the parameter has. Since this data is the same for all instances, it is created once per class. Hence the unique name for the constructor.
And... that's it. The CParamsDialog class knows these interfaces and can therefore do everything required. AP_ParameterPersister just needs to know the value and enumeration interface to store the data.
Yeah, I know, there was just one level. Of course the whole thing can recurse since AP_ParameterGroup is an AP_Parameter itself...
2005-07-26. 13:24:34. 600 words, 2503 views. Categories: programming, C++ , Leave a comment » • Send a trackback »
Trackback address for this post
Trackback URL (right click and copy shortcut/link location)
Feedback awaiting moderation
This post has 166 feedbacks awaiting moderation...
