That's really cool! I love it :-D
Thank you!
I'll see if I can explain how it works, and maybe you could tell me where I'm wrong/not-quite-right?
The
Dispatcher class is used to map pairs of shape types with the desired corresponding function, and use this map to call these functions when required. In Dispatcher class:
(*)
BaseFunction structure and the derived
Function structure template encapsulate a response function to a particular pair of
Shapes. Constructor specified in the
Function structure template takes a
Callback type, which has just been defined as
typedef void (*Callback)(T1 &,T2 &); or "a pointer to a function returning void and taking parameters T1&, and T2&, determined upon template specialisation".
(*) An STL
map container is used with
pair keys to map shape-type combinations to the desired function.
(*) A boolean 'symmetric' is used to indicate whether or not if (s1,s2) cannot be found in the map, we should search for (s2,s1) instead and call its function:
typedef map<Key, BaseFunction*> DispatchMap. This is the purpose of the
Function template inheriting from the
BaseFunction structure, otherwise the typedef of
DispatchMap would need to be a template too, to keep
Function<> generic.
(*)
Add function template. Takes a
Function structure as a parameter. The
Add function adds the
Function structure to the private member
DispatchMap, with a
pair containing the
two shape types as the key (if the key is found within the map already, then the new key and value overwrite the old; this is not a multimap).
(*)
Call function. Takes two
Shapes and a
boolean that allows the caller to specify whether the key (s2,s1) should be tried if (s1,s2) is not found. If the dispatcher has its symmetric boolean == false, then this flag is ignored and (s2,s1) is never tried. The
Call function searches for the key (types of the two parameter shapes) in the private
DispatchMap instance, if found,
the corresponding function is called.
-------------------------------------------------------------------------------------------
What I don't understand are the
get_type() and
get_type_static() methods. Why set
static int type=0; and what is
&type referring to?
Thanks again for your help! I love this solution :-D
Tom.
-------------------------------------------------------------------------------------------
For anyone else who reads this some time in the future - here are a few references I found handy while going through the code:
Void pointers (e.g.
void*) ==>
http://theoryx5.uwinnipeg.ca/programming/node87.html
Function pointer declarations with a typedef (e.g.
typedef void (*Callback)(T1 &,T2 &);) ==>
http://www.devx.com/tips/Tip/13829 - Function Pointer Declarations With a typedef
Also, in the following:
1 2 3 4 5 6 7 8 9
|
it=dispatch_map.find(type);
if (it==dispatch_map.end())
{
if (symmetric && check_symmetric)
return Call(s2,s1,false);
else return;
}
(*it->second)(s1,s2);
|
it is an iterator for the STL
map container. After
it = dispatch_map.find(type), if
it == dispatch_map.end(), then this means that find() reached the end of the map without finding
type as a key. In this case, if the functions are symmetric, we can try searching for (s2,s1) in the map instead of (s1,s2). Otherwise, return because there are no other options.
If this is not the case, the required function was found, and
it->second points to it. Thus
(*it->second) is like using the function name, and
(*it->second)(s1,s2); is like calling the function.