February 13, 2005

CDL use cases

These are some use cases for my C++ metaprogramming framework. First some CDL:
// Texture.h
#ifndef GUARD_Texture_H
#define GUARD_Texture_H

#include "Object.h" // physical dependency on base class

#include "StringPtr.h" // no physical dependency on referenced classes
#include "ArrayPtr.h"
#include "MipMapPtr.h"

CDL class Texture: public Object
{
public:

PROPERTY
Ptr<String> GetName() const;
void SetName(const Ptr<String> &);

PROPERTY
Ptr<Enumeration> GetMipMaps() const;
void SetMipMaps(const Ptr<Enumeration> &);

PROPERTY
Ptr<Palette> GetPalette() const;
void SetPalette(const Ptr<Palette> &);

private:

Ptr<String> name;
Array< Ptr<MipMap> > mipmaps;
Ptr<Palette> palette;
};

#endif // ifndef GUARD_Texture_H

It's just a C++ header file, limited to a restricted sub-language enforced by the CDL preprocessor. Notice that Texture.h is not physically dependent on String, Array or MipMap but rather on smart pointers to these types. Unlike conventional smart pointers, these are template classes specialized on the referenced type, which means they can provide access to the referenced type's public API without a physical dependency. They might be implemented like this:
// TexturePtr.h
// AUTOMATICALLY GENERATED!

class Texture; // forward declaration

template <>
class Ptr<Texture>
{
public:
// ...
Ptr<String> GetName() const;
void SetName(const Ptr<String> &) const;
// ...

private:
Texture *pointer;
};

// TexturePtr.cpp
// AUTOMATICALLY GENERATED!

#include "Texture.h" // physical dependency here
#include "TexturePtr.h"

Ptr<String> Ptr<Texture>::GetName() const
{
// trampoline to implementation
return pointer->GetName();
}

Texture.h is not just input to the CDL preprocessor. It is also compiled as part of the program like any other header file. So the member functions might be implemented like this:
// Texture.cpp

#include "Texture.h"

Ptr<String> Texture::GetName() const
{
return name;
}

Texture.cpp is not CDL. CDL is only concerned with the class definition, not the implementation of the functions.

The CDL preprocessor will automatically generate some code based on the CDL class definition. For example, it could automatically generate serialization code. So without the programmer having to write any additional serialization code, they can just write this:
void TestSave()
{
Ptr<Texture> texture = New<Texture>();
texture.SetName("Stone");

Ptr<MipMap> mipmap = New<MipMap>(128, 128);
Array< Ptr<MipMap> > mipmaps = NewArray< Ptr<MipMap> >(1);
mipmaps[0] = mipmap;

texture.SetMipMaps(mipmaps.GetEnumeration());

SaveXML(texture, "file.xml");

// texture, array and mipmap automatically freed through reference counting
}

SaveXML and LoadXML invoke code that is automatically generated by the CDL preprocessor. The output might look like this:
<Texture>
<Name>Stone</Name>
<MipMaps>
<MipMap>
<Width>128</Width>
<Height>128></Height>
<!-- ... -->
</MipMap>
</MipMaps>
<Palette>
<null/>
</Palette>
</Texture>

Then the programmer can write this to load the data:
void TestLoad()
{
Ptr<Object> object = LoadXML("file.xml");
Ptr<Texture> texture = DynamicCast<Texture>(object);
}

Comments: Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?