XPLC |
"The best way to predict the future is to invent it." -- Alan Kay |
Main |
FAQ |
Project |
Documentation |
Download |
Links |
The GenericComponent template is a helper to let you avoid the tedium of implementing IObject's methods yourself for all your components.
It is very simple to use:
Suppose an example component declared as follow (assume IFoo has a single method called doFoo):
class FooComponent: public IFoo { public: virtual void doFoo(); };
This component needs a map that looks like the following (this goes in the source file):
UUID_MAP_BEGIN(FooComponent) UUID_MAP_ENTRY(IObject) UUID_MAP_ENTRY(IFoo) UUID_MAP_END
As you see, we simply started the map with UUID_MAP_BEGIN, used the UUID_MAP_ENTRY macro once per supported interface and finished the map with UUID_MAP_END.
Now, if your component derives from more than one interface, say from both IFoo and IBar (which, you have guessed it, has a single method named doBar), a quirk of C++ makes the simple and obvious addition of a UUID_MAP_ENTRY(IBar) not possible, unfortunately. The reason is that there is now two IObject interfaces available, the one from IFoo and the one from IBar, and the compiler doesn't know which one to pick. Here is how the class is defined:
class AdvancedComponent: public IFoo, public IBar { public: virtual void doFoo(); virtual void doBar(); };
You have to use the UUID_MAP_ENTRY_2 macro to declare the so-called ambiguous interfaces, which allow you to specify which one you want to the compiler, as follows:
UUID_MAP_BEGIN(AdvancedComponent) UUID_MAP_ENTRY_2(IObject, IFoo) UUID_MAP_ENTRY(IFoo) UUID_MAP_ENTRY(IBar) UUID_MAP_END
The second parameter simply specifies whose IObject will be chosen. Why use IFoo over IBar? Using any other interface that has also derive from the ambiguous interface will also work correctly, but using the first interface your component derives from is slightly more efficient with most C++ compilers, so you should prefer using the first one.
And this is all there is to it!