Interest in a runtime dynamic dispatch library

Hi Everyone, Is there interest in a runtime dynamic index driven dispatch library here? The concept of the library is a bit simple, and is somewhat related to the Boost.Signals library -- but different in intent. Basically the main component of the library is a dynamic callback registry/dispatcher object which maintains callback references to nullary free functions and nullary functors. To illustrate how the library is intended to be used, the following code snippets have been provided: //set up a registry dispatch::dispatcher<void (), int> callbacks; // register a nullary free function f to index 0 callbacks[0] = f; // bind arguments to a single argument function p to index 1 callbacks[1] = boost::bind(p, 1); // get user input then execute appropriate callback int i; cin >> i; callbacks[i](); Feedback would be most appreciated. Thanks and have a great day everyone! -- Dean Michael C. Berris C/C++ Software Architect Orange and Bronze Software Labs http://3w-agility.blogspot.com/ http://cplusplus-soup.blogspot.com/ Mobile: +639287291459 Email: dean [at] orangeandbronze [dot] com

Dean Michael Berris wrote:
//set up a registry dispatch::dispatcher<void (), int> callbacks;
// register a nullary free function f to index 0 callbacks[0] = f;
// bind arguments to a single argument function p to index 1 callbacks[1] = boost::bind(p, 1);
// get user input then execute appropriate callback int i; cin >> i; callbacks[i]();
This can be done with map< int, function<void()> >.

On 6/8/06, Peter Dimov <pdimov@mmltd.net> wrote:
Dean Michael Berris wrote:
//set up a registry dispatch::dispatcher<void (), int> callbacks;
// register a nullary free function f to index 0 callbacks[0] = f;
// bind arguments to a single argument function p to index 1 callbacks[1] = boost::bind(p, 1);
// get user input then execute appropriate callback int i; cin >> i; callbacks[i]();
This can be done with map< int, function<void()> >.
Yes, this is just one of the things that the dispatcher can do. The current implementation (lacking documentation) can be downloaded from http://tinyurl.com/px33v -- there are a few other uses, including a means for defining a strategy for index validation. An example of this usage is shown below (and can also be seen from the unit test): #include <iostream> #include "dispatch.hpp" int function_returns_int (int j) { return j+1; }; struct require_even_strategy { bool operator() (int number) const { return (number != 0) && ((number % 2) == 0); }; }; typedef dispatch::dispatcher<int(), int, require_even_strategy, std::vector> dispatcher_t; int main(int argc, char **argv) { dispatcher_t d; d[2] = boost::bind(function_returns_int, 3); d[4] = boost::bind(function_returns_int, 5); dispatcher_t::collection_type v = d.dispatch(2); std::cout << v[0] << ", " << v[1] << std::endl; return 0; } Future direction is support for asynchronous and thread safe invocations of operator[] and dispatch(). It does implement some of the Boost.Signals functionality in the dispatch() call, but (though I certainly haven't tried yet) I'd think it will work well with signals too. And yes, the dispatcher holds an std::map of wrappers to boost::function<> instances. -- Dean Michael C. Berris C/C++ Software Architect Orange and Bronze Software Labs http://3w-agility.blogspot.com/ http://cplusplus-soup.blogspot.com/ Mobile: +639287291459 Email: dean [at] orangeandbronze [dot] com

Dean Michael Berris wrote:
On 6/8/06, Peter Dimov <pdimov@mmltd.net> wrote:
Dean Michael Berris wrote:
//set up a registry dispatch::dispatcher<void (), int> callbacks;
// register a nullary free function f to index 0 callbacks[0] = f;
// bind arguments to a single argument function p to index 1 callbacks[1] = boost::bind(p, 1);
// get user input then execute appropriate callback int i; cin >> i; callbacks[i](); This can be done with map< int, function<void()> >.
Yes, this is just one of the things that the dispatcher can do. The current implementation (lacking documentation) can be downloaded from http://tinyurl.com/px33v --
Well documentation would be what most of use would really like to see :-) Some days ago I rewrote a message dispatching system that has similar interface to what you present, and implemented on top of Boost.Signals. Some examples: struct is_equal_message : message< is_equal_message, boost::tuple<int,bool> bool (int, double)
{}; namespace { is_equal_message cosnt & is_equal = is_equal_message::get(); } struct is_even_message : message< is_even_message, boost::tuple<int> bool (int) {}; namespace { is_even_message cosnt & is_even = is_even_message::get(); }
bool my_equal(int a, double b) { return double(a) == b; } bool my_even(int a) { return a%2 == 0; } int main (int arc, char** argv) { dispatcher d; d << is_equal[1,true].connect(boost::bind(my_equal,_2,_3)) << is_equal[1,false].connect(boost::bind(my_equal,_3,_2)) << is_even[1].connect(boost::bind(my_even,_2)); std::cout << ( d[is_equal,1,true](12,12) ? "T" : "F" ) << ( d[is_equal,1,false](12,3.14) ? "T" : "F" ) << ( d[is_even,1](2) ? "T" : "F" ) << ( d[is_even,1](1) ? "T" : "F" ) << std::endl; return 0; } Does your code support such varied registration and dispatching?
there are a few other uses, including a means for defining a strategy for index validation. An example of this usage is shown below (and can also be seen from the unit test): [...] typedef dispatch::dispatcher<int(), int, require_even_strategy, std::vector> dispatcher_t;
Hm, now that's an interesting idea, contract based dispatch interfaces. -- -- Grafik - Don't Assume Anything -- Redshift Software, Inc. - http://redshift-software.com -- rrivera/acm.org - grafik/redshift-software.com -- 102708583/icq - grafikrobot/aim - grafikrobot/yahoo

On 6/12/06, Rene Rivera <grafik.list@redshift-software.com> wrote:
Dean Michael Berris wrote:
Yes, this is just one of the things that the dispatcher can do. The current implementation (lacking documentation) can be downloaded from http://tinyurl.com/px33v --
Well documentation would be what most of use would really like to see :-)
Yes, as I've been thinking more and more about it, I now also feel like I should get into writing documentation for this. :)
[...] dispatcher d; d << is_equal[1,true].connect(boost::bind(my_equal,_2,_3)) << is_equal[1,false].connect(boost::bind(my_equal,_3,_2)) << is_even[1].connect(boost::bind(my_even,_2)); std::cout << ( d[is_equal,1,true](12,12) ? "T" : "F" ) << ( d[is_equal,1,false](12,3.14) ? "T" : "F" ) << ( d[is_even,1](2) ? "T" : "F" ) << ( d[is_even,1](1) ? "T" : "F" ) << std::endl; return 0; }
Does your code support such varied registration and dispatching?
I have been mulling around the concept of allowing registration of functions that take on different signatures, but the current state of the library will need to be reworked to allow this kind of support. In large part, it would duplicate a lot of the approaches taken by Boost.Signals and encounter the same problems. In the end though, the ultimate aim is to be able to support functions of different signatures and register them into a single dispatcher. The only stumbling block I'm encountering is with the actual implementation of the overloads required to make it work -- and maybe have to anticipate the forwarding problem, since I'll be dealing with function pointers during runtime. Supporting something like this is pretty tough work, as I can only imagine the stuff that needs to be done to ensure runtime correctness so that the following will be valid (and will perform as expected): int my_method_1(const std::string & str) { std::cout << str; return 1; } void my_method_2(unsigned long long ull, const std::string & mt) { std::cout << ull << ", " << mt; }; //... somewhere registered: d[0] = boost::bind(my_method_1, _2); d[1] = boost::bind(my_method_2, _2, _3); //... somewhere else still int index; d[index]("Hello, World!"); If in case I can figure out (or others can help me figure out, or even implement) how to make the registration and dispatch as generic as possible without restricting that all registered functions be nullary functions, then I might try implementing the generic registration and dispatch. In any case, if anybody knows of a better way than looking at Boost.Signal and seeing how it's written (which I've already done, though partially ...) without having to go into the trouble of "reinventing the wheel", I'd certainly appreciate the pointers. :)
there are a few other uses, including a means for defining a strategy for index validation. An example of this usage is shown below (and can also be seen from the unit test): [...] typedef dispatch::dispatcher<int(), int, require_even_strategy, std::vector> dispatcher_t;
Hm, now that's an interesting idea, contract based dispatch interfaces.
It's usually (as far as the projects I've dealt with) a recurring pattern, where a router is necessary to perform the required action based on the actual message received. There are some restrictions on the message format/composition/characteristics that need to be ensured regardless of the actual message content -- and this can be programmed as a strategy for determining validity of the message to guide the dispatcher. Since there really is no way to (that I know of) anticipate user input during compile time, the least I can come up with is to allow for a generic approach to allow for validating messages (indexes). This can also be used to decide many different things during runtime, and even change the behavior of the dispatcher as it runs. Currently, the strategy is used for validation purposes only -- but may and will most probably change to allow the following, and call the appropriate callback: dispatch::dispatcher <int (), std::string, string_normalizer> d; d["message"] = do_something; d["MeSsAgE"](); // will perform as though d["message"] was referenced d["mEsSaGe"](); // same as above... d[" message "](); // same as above... // and many variations of "message" that can be normalized I'm still adding more and more types of dispatchers, and currently waiting for more interest before I even think of proposing the library (of course, not in its current form) to the Boost C++ Library community. If there's enough interest, I'd be glad to go through the rogorous process of proposing the library for inclusion (and designing it with that in mind) in the (hopefully near) future. Right now though, it's being used in one of the projects I'm working on which will be released under the GPL -- but the library itself is already released under the Boost License. (And since I'm the author of both the library and the other project, I don't expect to encounter any issues with licensing, though IANAL). -- Dean Michael C. Berris C/C++ Software Architect Orange and Bronze Software Labs http://3w-agility.blogspot.com/ http://cplusplus-soup.blogspot.com/ Mobile: +639287291459 Email: dean [at] orangeandbronze [dot] com
participants (3)
-
Dean Michael Berris
-
Peter Dimov
-
Rene Rivera