mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-28 07:48:37 -04:00
event: Support C++11 lambdas as event handlers
It's unfortunate that we now have three maps on EventHandler for three different types of functions. I'd love to unify them all under std::function, but the fact that it doesn't support comparison means the behavior would be different. Perhaps in the future we can create a new interface or deprecate the existing behaviors and unify everything under std::function.
This commit is contained in:
parent
4af5bc9e6d
commit
653cc3e091
@ -104,6 +104,20 @@ dispatch_event(const Event *event) {
|
||||
}
|
||||
}
|
||||
|
||||
// now for lambda hooks
|
||||
LambdaHooks::const_iterator lhi;
|
||||
lhi = _lambdahooks.find(event->get_name());
|
||||
|
||||
if (lhi != _lambdahooks.end()) {
|
||||
// found one
|
||||
const LambdaFunctions &functions = (*lhi).second;
|
||||
|
||||
size_t num_functions = functions.size();
|
||||
for (size_t i = 0; i < num_functions; ++i) {
|
||||
functions[i](event);
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, check for futures that need to be triggered.
|
||||
Futures::iterator fi;
|
||||
fi = _futures.find(event->get_name());
|
||||
@ -189,6 +203,19 @@ add_hook(const string &event_name, EventCallbackFunction *function,
|
||||
return _cbhooks[event_name].insert(CallbackFunction(function, data)).second;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the indicated function to the list of those that will be called when
|
||||
* the named event is thrown. Returns true if the function was successfully
|
||||
* added, false if it was already defined on the indicated event name. This
|
||||
* version stores an arbitrary C++ lambda.
|
||||
*/
|
||||
void EventHandler::
|
||||
add_hook(const string &event_name, EventLambda function) {
|
||||
assert(!event_name.empty());
|
||||
assert(function);
|
||||
_lambdahooks[event_name].push_back(function);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if there is any hook added on the indicated event name, false
|
||||
* otherwise.
|
||||
@ -212,6 +239,14 @@ has_hook(const string &event_name) const {
|
||||
}
|
||||
}
|
||||
|
||||
LambdaHooks::const_iterator lhi;
|
||||
lhi = _lambdahooks.find(event_name);
|
||||
if (lhi != _lambdahooks.end()) {
|
||||
if (!(*lhi).second.empty()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -306,6 +341,14 @@ remove_hooks(const string &event_name) {
|
||||
_cbhooks.erase(chi);
|
||||
}
|
||||
|
||||
LambdaHooks::iterator lhi = _lambdahooks.find(event_name);
|
||||
if (lhi != _lambdahooks.end()) {
|
||||
if (!(*lhi).second.empty()) {
|
||||
any_removed = true;
|
||||
}
|
||||
_lambdahooks.erase(lhi);
|
||||
}
|
||||
|
||||
return any_removed;
|
||||
}
|
||||
|
||||
@ -344,6 +387,7 @@ void EventHandler::
|
||||
remove_all_hooks() {
|
||||
_hooks.clear();
|
||||
_cbhooks.clear();
|
||||
_lambdahooks.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,6 +23,10 @@
|
||||
#include "pset.h"
|
||||
#include "pmap.h"
|
||||
|
||||
#ifndef CPPPARSER
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
class EventQueue;
|
||||
|
||||
/**
|
||||
@ -40,6 +44,12 @@ public:
|
||||
typedef void EventFunction(const Event *);
|
||||
typedef void EventCallbackFunction(const Event *, void *);
|
||||
|
||||
#ifdef CPPPARSER
|
||||
typedef EventFunction EventLambda;
|
||||
#else
|
||||
typedef std::function<void (const Event *)> EventLambda;
|
||||
#endif
|
||||
|
||||
PUBLISHED:
|
||||
explicit EventHandler(EventQueue *ev_queue);
|
||||
~EventHandler() {}
|
||||
@ -58,6 +68,7 @@ public:
|
||||
bool add_hook(const std::string &event_name, EventFunction *function);
|
||||
bool add_hook(const std::string &event_name, EventCallbackFunction *function,
|
||||
void *data);
|
||||
void add_hook(const std::string &event_name, EventLambda function);
|
||||
bool has_hook(const std::string &event_name) const;
|
||||
bool has_hook(const std::string &event_name, EventFunction *function) const;
|
||||
bool has_hook(const std::string &event_name, EventCallbackFunction *function,
|
||||
@ -78,10 +89,13 @@ protected:
|
||||
typedef std::pair<EventCallbackFunction*, void*> CallbackFunction;
|
||||
typedef pset<CallbackFunction> CallbackFunctions;
|
||||
typedef pmap<std::string, CallbackFunctions> CallbackHooks;
|
||||
typedef pvector<EventLambda> LambdaFunctions;
|
||||
typedef pmap<std::string, LambdaFunctions> LambdaHooks;
|
||||
typedef pmap<std::string, PT(AsyncFuture)> Futures;
|
||||
|
||||
Hooks _hooks;
|
||||
CallbackHooks _cbhooks;
|
||||
LambdaHooks _lambdahooks;
|
||||
Futures _futures;
|
||||
EventQueue &_queue;
|
||||
|
||||
|
@ -310,6 +310,39 @@ define_key(const string &event_name, const string &description,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up a handler for the indicated key. When the key is pressed in a
|
||||
* window, the given callback will be called. The description is a one-line
|
||||
* description of the function of the key, for display to the user.
|
||||
*/
|
||||
void PandaFramework::
|
||||
define_key(const string &event_name, const string &description,
|
||||
EventHandler::EventLambda function) {
|
||||
if (_event_handler.has_hook(event_name)) {
|
||||
// If there is already a hook for the indicated keyname, we're most likely
|
||||
// replacing a previous definition of a key. Search for the old
|
||||
// definition and remove it.
|
||||
KeyDefinitions::iterator di;
|
||||
di = _key_definitions.begin();
|
||||
while (di != _key_definitions.end() && (*di)._event_name != event_name) {
|
||||
++di;
|
||||
}
|
||||
if (di != _key_definitions.end()) {
|
||||
_key_definitions.erase(di);
|
||||
}
|
||||
}
|
||||
|
||||
// Now add a new hook for the keyname, and also add the new description.
|
||||
_event_handler.add_hook(event_name, function);
|
||||
|
||||
if (!description.empty()) {
|
||||
KeyDefinition keydef;
|
||||
keydef._event_name = event_name;
|
||||
keydef._description = description;
|
||||
_key_definitions.push_back(keydef);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fills in the indicated window properties structure according to the normal
|
||||
* window properties for this application.
|
||||
|
@ -56,6 +56,9 @@ public:
|
||||
const std::string &description,
|
||||
EventHandler::EventCallbackFunction *function,
|
||||
void *data);
|
||||
void define_key(const std::string &event_name,
|
||||
const std::string &description,
|
||||
EventHandler::EventLambda function);
|
||||
|
||||
INLINE void set_window_title(const std::string &title);
|
||||
virtual void get_default_window_props(WindowProperties &props);
|
||||
|
Loading…
x
Reference in New Issue
Block a user