Garthy
24-01-2011 10:36:04
One limitation that I've noticed with MyGUI is that there *seems* to be no way to easily and automatically properly clean up resources on destruction of a delegate using any of the three main delegate forms (global function, class static function, object and method) as they are all represented by pointers. Please correct me if I'm wrong.
If you need to attach data to a delegate, one means of solving this problem is to use widget user data and store any resources there, knowing they'll be cleaned up by MyGUI::Any's destructor and template magic, and then use a delegate with an object pointer to the resource, knowing that you won't lose it whilst the object lives. This is a nasty and messy solution, and I know, since it's what I did to solve the problem initially.![Wink ;)]({SMILIES_PATH}/icon_wink.gif)
Another way of solving the problem is to add another delegate type, namely one that supports functors. For those that don't know, a functor is an object that encapsulates any information you wish, and can be called like a function, usually through "operator()" in C++, along with associated cleanup of its resources on destruction. Such a type would let you carry any data of your choosing with the delegate, knowing that it will be safely destructed when it falls out of scope. A general functor delegate is quite nice as you could even give it boost::function objects, and also wrap arguments up with boost::bind, which is *incredibly* useful.
I've had a shot at implementing such a thing, and I've had a degree of success. However, the perfect solution requires some fairly hairy template magic in a file that is included multiple times to create multiple sets of templates (namely "MyGUI_Delegate.h" and "MyGUI_DelegateImplement.h"), and frankly this heavy template magic is a bit beyond me. However, I'm happy to share what I did come up with, with the hope it is useful or someone can improve on it.![Smile :)]({SMILIES_PATH}/icon_smile.gif)
Included is a small patch that adds functor delegates to MyGUI. It *seems* to work, but no promises. It's against a fairly recent version of MyGUI from subversion.
An example of usage with boost::bind and boost::function is below:
Now, the ideal would be something like:
But I was unsuccessful in coming up with anything that worked in this way.
There are other ways to solve this problem as well; this is just one of them. I like the functor approach personally as it can be easily expanded to cover a huge range of scenarios.
I'm wondering if functionality like this, or ideally something that would work a bit more like the second block of code above, would be a worthwhile addition to MyGUI?
If you need to attach data to a delegate, one means of solving this problem is to use widget user data and store any resources there, knowing they'll be cleaned up by MyGUI::Any's destructor and template magic, and then use a delegate with an object pointer to the resource, knowing that you won't lose it whilst the object lives. This is a nasty and messy solution, and I know, since it's what I did to solve the problem initially.
![Wink ;)]({SMILIES_PATH}/icon_wink.gif)
Another way of solving the problem is to add another delegate type, namely one that supports functors. For those that don't know, a functor is an object that encapsulates any information you wish, and can be called like a function, usually through "operator()" in C++, along with associated cleanup of its resources on destruction. Such a type would let you carry any data of your choosing with the delegate, knowing that it will be safely destructed when it falls out of scope. A general functor delegate is quite nice as you could even give it boost::function objects, and also wrap arguments up with boost::bind, which is *incredibly* useful.
I've had a shot at implementing such a thing, and I've had a degree of success. However, the perfect solution requires some fairly hairy template magic in a file that is included multiple times to create multiple sets of templates (namely "MyGUI_Delegate.h" and "MyGUI_DelegateImplement.h"), and frankly this heavy template magic is a bit beyond me. However, I'm happy to share what I did come up with, with the hope it is useful or someone can improve on it.
![Smile :)]({SMILIES_PATH}/icon_smile.gif)
Included is a small patch that adds functor delegates to MyGUI. It *seems* to work, but no promises. It's against a fairly recent version of MyGUI from subversion.
An example of usage with boost::bind and boost::function is below:
typedef boost::function<void (MyGUI::WidgetPtr _sender)> Delegate_W_Type;
class SomeClass;
typedef shared_ptr<SomeClass> SomeClassPtr;
static void Delegate_W(SomeClassPtr foo, MyGUI::WidgetPtr _sender)
{
foo->doSomething(_sender);
}
static void setup(MyGUI::Button *w, SomeClassPtr foo)
{
Delegate_W_Type f = boost::bind(Delegate_W, foo, _1);
w->eventMouseButtonClick = MyGUI::newFunctorDelegate<
Delegate_W_Type, MyGUI::WidgetPtr>(f);
}
Now, the ideal would be something like:
class SomeClass;
typedef shared_ptr<SomeClass> SomeClassPtr;
static void Delegate_W(SomeClassPtr foo, MyGUI::WidgetPtr _sender)
{
foo->doSomething(_sender);
}
static void setup(MyGUI::Button *w, SomeClassPtr foo)
{
w->eventMouseButtonClick = MyGUI::newDelegate(
boost::bind(Delegate_W, foo, _1));
}
But I was unsuccessful in coming up with anything that worked in this way.
There are other ways to solve this problem as well; this is just one of them. I like the functor approach personally as it can be easily expanded to cover a huge range of scenarios.
I'm wondering if functionality like this, or ideally something that would work a bit more like the second block of code above, would be a worthwhile addition to MyGUI?