diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index f3ff41f19a..e1e920da59 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -395,20 +395,27 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; if (!handlersOnEntity.contains(eventName)) return; // FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts. - QScriptValue handlerForEvent = handlersOnEntity[eventName]; - if (handlerForEvent.isValid()) { + QScriptValueList handlersForEvent = handlersOnEntity[eventName]; + if (!handlersForEvent.isEmpty()) { QScriptValueList args = argGenerator(); - handlerForEvent.call(QScriptValue(), args); + for (int i = 0; i < handlersForEvent.count(); ++i) { + handlersForEvent[i].call(QScriptValue(), args); + } } } -// Unregister the handler for this eventName and entityID. +// Unregister the handlers for this eventName and entityID. void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { if (!_registeredHandlers.contains(entityID)) return; RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; - if (!handlersOnEntity.contains(eventName)) return; - handlersOnEntity.remove(eventName); + QScriptValueList& handlersForEvent = handlersOnEntity[eventName]; + // QScriptValue does not have operator==(), so we can't use QList::removeOne and friends. So iterate. + for (int i = 0; i < handlersForEvent.count(); ++i) { + if (handlersForEvent[i].equals(handler)) { + handlersForEvent.removeAt(i); + return; // Design choice: since comparison is relatively expensive, just remove the first matching handler. + } + } } -// FIXME: deletingEntity, changingEntityID // Register the handler. void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script... @@ -466,7 +473,8 @@ void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QSt if (!_registeredHandlers.contains(entityID)) { _registeredHandlers[entityID] = RegisteredEventHandlers(); } - _registeredHandlers[entityID][eventName] = handler; + QScriptValueList& handlersForEvent = _registeredHandlers[entityID][eventName]; + handlersForEvent << handler; // Note that the same handler can be added many times. See removeEntityEventHandler(). } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 28610fd65c..0fd8ed0562 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -37,7 +37,7 @@ const QString NO_SCRIPT(""); const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5); -typedef QHash RegisteredEventHandlers; +typedef QHash RegisteredEventHandlers; class ScriptEngine : public QScriptEngine, public ScriptUser { Q_OBJECT