OMNI_BIND
MACRO

OMNI_BIND - A helper macro for binding to the omni::delegate.

SYNOPSIS top

This macro is a helper macro. It's purpose is to make binding to an omni::delegate less verbose when needing to bind to a non-static class member function.

This macro is only for non-static class members (i.e. a class/struct member function) since binding to a static function is already less verbose (e.g. you can simply say omni::delegate d = &some_function);

The macro is a variadic macro that expands to one of the defined OMNI_BIND macros where each helper macro is defined as such:
#define OMNI_BIND0(Ret, Class, Function, Obj) omni::delegate<Ret>::bind<Class, &Class::Function>(Obj)
Where Ret is the function return type, Class is the class type, Function is the member function of the Class specified (only the function name, not the full scope as the macro will expand this), and lastly Obj is the instance object needing to be passed in.

For each omni::delegate type there is an associated OMNI_BIND macro. The omni::delegate1 type would be OMNI_BIND1, for omni::delegate2 OMNI_BIND2 and so on, where the additional parameters are a part of the macro. So OMNI_BIND1 is defined as the following:
#define OMNI_BIND1(Ret, PT1, Class, Function, Obj) omni::delegate1<Ret, PT1>::bind<Class, &Class::Function>(Obj)
The Ret, Class, Function and Obj macro parameters are the same as the OMNI_BIND macro; PT1 is the 1st function parameter type, if you used OMNI_BIND2, etc., additional function parameter types will be specified in the macro parameters as well (e.g. PT2 for OMNI_BIND2, PT2 and PT3 for OMNI_BIND3 and so on).

DESCRIPTION top

When binding a function to an omni::delegate (or an omni::event), you can use the static bind function of the delegate class to attach a non-static class member function by specifying the full delegate signature and the class, it's function and the associated instance to bind to; as an example, using the omni::delegate1 which takes one parameter in the function signature:
my_class obj;
omni::delegate1<void, int> my_delegate = omni::delegate1<void, int>::bind<my_class, &my_class::class_function>(obj);
my_event += my_delegate;
// or 
omni::event1<void, int> my_event;
my_event += omni::delegate1<void, int>::bind<my_class, &my_class::class_function>(obj);
// or
typedef omni::event1<void, int> event_t;
event_t my_event;
my_event += event_t::delegate_t::bind<my_class, &my_class::class_function>(obj);
As you can see, this can get very verbose when working with more complex function signatures and class types. To help alleviate some of this verbosity in the code you could instead elect to use this helper macro, example (using code from above):
my_class obj;
omni::event1<void, int> my_event;
my_event += omni_bind(void, int, my_class, class_function, obj);
// or 
omni::delegate1<void, int> my_delegate = omni_bind(void, int, my_class, class_function, obj);
my_event += my_delegate;
Since this is just a helper macro, it's intended use is mostly to help the verbosity of binding a member function. You could alternatively typedef a more complex delegate type and perform similar functionality, example:
typedef omni::event1<void, int> event_t;
typedef event_t::delegate_t delegate_t;
// or typedef omni::delegate1<void, int> delegate_t;
my_class obj;
event_t my_event;
my_event += delegate_t::bind<my_class, &my_class::class_function>(obj);
// or 
delegate_t my_delegate = delegate_t::bind<my_class, &my_class::class_function>(obj);
my_event += my_delegate;

CONSIDERATIONS top

This macro is only applicable to binding of non-static member functions (namespace functions are not non-static member functions and can be addressed the same as a non-member function).

Example:
class my_class {
    public:
        void some_function(int p) { /* code */ }
};

namespace my_ns {
    void some_function(int p) { /* code */ }
}

void some_function(int p) { /* code */ }

my_class obj;
omni::delegate1<void, int> d1 = omni_bind(void, int, my_class, some_function, obj); // OK
omni::delegate1<void, int> d2 = omni_bind(void, int, my_ns, some_function, obj); // FAIL (my_ns is not a class)
omni::delegate1<void, int> d3 = omni_bind(void, int, my_class, &some_function, obj); // FAIL (expands &my_class::&some_function)

// d2 and d3 could simply be written as such:

omni::delegate1<void, int> d2 = &my_ns::some_function;
omni::delegate1<void, int> d3 = &::some_funciton;

PLATFORM SPECIFIC top

No platform specific notes.

NOTES top

None.