00001 #ifndef DVUTIL_DISPATCHER_H 00002 #define DVUTIL_DISPATCHER_H 00003 // $Id: dispatch.h,v 1.3 2003/08/11 09:38:12 dvermeir Exp $ 00004 00005 namespace Dv { 00006 namespace Util { 00007 /** A class template framework to dispatch control based on some 00008 * value. 00009 * 00010 * The framework assumes that there are two objects: 00011 * 00012 * @code 00013 * Input input; // represents input for application 00014 * Application application; // represents application 00015 * @endcode 00016 * 00017 * The Application class has a number of handler functions 00018 * @code 00019 * Application::handle_value_1(Input& input, const Value& value) 00020 * Application::handle_value_2(Input& input, const Value& value) 00021 * @endcode 00022 * one of which should be called. Which one to call depends 00023 * on a certain available value. 00024 * 00025 * The class template below makes it easy to dispatch to the correct 00026 * handler-function, based on the given value. 00027 * 00028 * To use, an instance should define 00029 * @a Dispatcher<Application,Input,Value>::table as in the 00030 * example below. 00031 * @code 00032 * typedef std::string Value; 00033 * Dispatcher<Application,Input,Value>::Entry 00034 * Dispatcher<Application,Input,Value>::table[] = { 00035 * { "", &Application::default_handler }, 00036 * { "a", &Application::handle_a }, 00037 * { "b", &Application::handle_b }, 00038 * { "c", &Application::handle_c }, 00039 * { "", 0 } // sentinel 00040 * }; 00041 * @endcode 00042 * 00043 * The Application class could then define an @a Application::main 00044 * function as follows. 00045 * @code 00046 * class Application { 00047 * public: 00048 * bool main(Input& input, const Value& value) { 00049 * return Dispatcher<Application,Input,Value>::handle(*this, input, value); 00050 * } 00051 * }; 00052 * @endcode 00053 * @sa Dv::Cgi::Cgi 00054 */ 00055 template <class Application, typename Input, typename Value> 00056 class Dispatcher { 00057 public: 00058 /** Handler type */ 00059 typedef bool (Application::*Handler)(Input& input, const Value& value); 00060 /** Type of entry in dispatch table: if value is key, h will be 00061 * called */ 00062 typedef struct { Value key; Handler h; } Entry; 00063 /** Actual dispatch table. 00064 * Define as in the example below. 00065 * @code 00066 * Dispatcher<Application,Input,std::string>::Entry 00067 * Dispatcher<Application,Input,std::string>::table[] = { 00068 * { "", &Application::default_handler }, 00069 * { "a", &Application::handle_a }, 00070 * { "b", &Application::handle_b }, 00071 * { "c", &Application::handle_c }, 00072 * { "", 0 } // sentinel 00073 * @endcode 00074 */ 00075 static Entry table[]; 00076 /** Main handler function. It will use @a value to dispatch a call to the 00077 * appropriate handler function. 00078 * An actual example can be found in @a test-dispatch.C in the 00079 * source directory. 00080 * @param a application defining handler functions. 00081 * @param input object. 00082 * @param value used to select the handler function. 00083 */ 00084 static bool handle(Application& a, Input& input, const Value& value) { 00085 for (Entry* e(table); (e->h) ; ++e) 00086 if (e->key==value) 00087 return (a.*(e->h))(input, value); 00088 return false; 00089 } 00090 }; 00091 00092 }} 00093 #endif
dvutil-1.0.10 | [ 5 December, 2009] |