Unify the code for all event dispatching.

Make the build_chain a template which allows the code to be more generic.
This commit is contained in:
Mark de Wever 2011-02-12 12:56:26 +00:00
parent 180bc511f5
commit f4aeede786
2 changed files with 47 additions and 31 deletions

View file

@ -250,41 +250,30 @@ bool tdispatcher::fire(const tevent event
, ttrigger_keyboard(key, modifier, unicode));
}
/** Helper struct to wrap the functor call. */
class ttrigger_notification
{
public:
void operator()(tsignal_notification_function functor
, tdispatcher& dispatcher
, const tevent event
, bool& handled
, bool& halt)
{
functor(dispatcher, event, handled, halt, NULL);
}
};
bool tdispatcher::fire(const tevent event
, twidget& target
, void*)
{
assert(find<tset_event_notification>(event, tevent_in_set()));
/**
* @todo The firing needs some polishing.
*
* Make sure the events can't be added to pre and post chain since they are
* not used.
*/
// Fire it here directly since we need special handling.
bool handled = false;
bool halt = false;
if(target.has_event(event, child)) {
tsignal<tsignal_notification_function>& signal =
target.signal_notification_queue_.queue[event];
for(std::vector<tsignal_notification_function>::iterator
itor = signal.child.begin();
itor != signal.child.end();
++itor) {
(*itor)(*this, event, handled, halt, NULL);
if(halt) {
assert(handled);
break;
}
}
}
return handled;
return fire_event<tsignal_notification_function>(event
, dynamic_cast<twidget*>(this)
, &target
, ttrigger_notification());
}
void tdispatcher::register_hotkey(const hotkey::HOTKEY_COMMAND id

View file

@ -385,6 +385,7 @@ namespace implementation {
*
* @returns The list of widgets with a handler.
*/
template<class T>
inline std::vector<std::pair<twidget*, tevent> > build_event_chain(
const tevent event
, twidget* dispatcher
@ -409,6 +410,32 @@ inline std::vector<std::pair<twidget*, tevent> > build_event_chain(
return result;
}
/**
* Build the event chain for tsignal_notification_function.
*
* The notification is only send to the receiver it returns an empty chain.
* Since the pre and post queues are unused, it validates whether they are
* empty (using asserts).
*/
template<>
inline std::vector<std::pair<twidget*, tevent> >
build_event_chain<tsignal_notification_function>(
const tevent event
, twidget* dispatcher
, twidget* widget)
{
assert(dispatcher);
assert(widget);
assert(!widget->has_event(
event
, tdispatcher::tevent_type(
tdispatcher::pre
| tdispatcher::post)));
return std::vector<std::pair<twidget*, tevent> >();
}
/**
* Helper function for fire_event.
*
@ -538,7 +565,7 @@ inline bool fire_event(const tevent event
assert(widget);
std::vector<std::pair<twidget*, tevent> > event_chain =
implementation::build_event_chain(event, dispatcher, widget);
implementation::build_event_chain<T>(event, dispatcher, widget);
return implementation::fire_event<T>(event
, event_chain