From 277f5ef3a4527efd9a6c0d1f96a8ada6ee455dda Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sat, 23 May 2015 13:35:35 -0700 Subject: [PATCH 01/12] Working experimental first version. --- .../src/EntityTreeRenderer.cpp | 19 +++++++++++++++ .../src/EntityTreeRenderer.h | 4 ++++ .../entities/src/EntityScriptingInterface.cpp | 7 ++++++ .../entities/src/EntityScriptingInterface.h | 8 +++++++ libraries/script-engine/src/ScriptEngine.cpp | 24 +++++++++++++++++++ libraries/script-engine/src/ScriptEngine.h | 8 +++++++ 6 files changed, 70 insertions(+) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c47c24f20a..a41f23a7cc 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -873,6 +873,23 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity); connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity); + connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity); + + connect(entityScriptingInterface, &EntityScriptingInterface::addEntityEventHandler, this, &EntityTreeRenderer::addEntityEventHandler); + connect(entityScriptingInterface, &EntityScriptingInterface::removeEntityEventHandler, this, &EntityTreeRenderer::addEntityEventHandler); +} + +void EntityTreeRenderer::addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { + ScriptEngine* engine = static_cast(handler.engine()); + if (engine) { // In case it's gone by the time we get the signal + engine->addEntityEventHandler(entityID, entityEventName, handler); + } +} +void EntityTreeRenderer::removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { + ScriptEngine* engine = static_cast(handler.engine()); + if (engine) { + engine->removeEntityEventHandler(entityID, entityEventName, handler); + } } QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) { @@ -1187,6 +1204,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons playEntityCollisionSound(myNodeID, entityTree, idB, collision); // And now the entity scripts + emit collisionWithEntity(idA, idB, collision); QScriptValue entityScriptA = loadEntityScript(idA); if (entityScriptA.property("collisionWithEntity").isValid()) { QScriptValueList args; @@ -1196,6 +1214,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons entityScriptA.property("collisionWithEntity").call(entityScriptA, args); } + emit collisionWithEntity(idB, idB, collision); QScriptValue entityScriptB = loadEntityScript(idB); if (entityScriptB.property("collisionWithEntity").isValid()) { QScriptValueList args; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 9768d4a20a..2c841e6f06 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -107,6 +107,7 @@ signals: void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); + void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); public slots: void addingEntity(const EntityItemID& entityID); @@ -121,6 +122,9 @@ public slots: void setDisplayModelElementProxy(bool value) { _displayModelElementProxy = value; } void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; } + void addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + void removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + protected: virtual Octree* createTree() { return new EntityTree(true); } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 351bbc3643..a23bb386ff 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -201,6 +201,13 @@ void EntityScriptingInterface::dumpTree() const { } } +void EntityScriptingInterface::addEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { + emit addEntityEventHandler(entityID, entityEventName, handler); +} +void EntityScriptingInterface::removeEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { + emit removeEntityEventHandler(entityID, entityEventName, handler); +} + QVector EntityScriptingInterface::findEntities(const glm::vec3& center, float radius) const { QVector result; if (_entityTree) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index f1876a836b..c04e55a8a0 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -119,8 +119,16 @@ public slots: Q_INVOKABLE void dumpTree() const; + // Register a function that will handle the given entityEventName on entityID + Q_INVOKABLE void addEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + Q_INVOKABLE void removeEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + signals: + void addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + void removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); + void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); + void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void canAdjustLocksChanged(bool canAdjustLocks); void canRezChanged(bool canRez); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 427944e254..81e30d0265 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -389,6 +389,30 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func } } +void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { + auto entities = DependencyManager::get(); + if (!_registeredHandlers.contains(entityID)) { + _registeredHandlers[entityID] = RegisteredEventHandlers(); + } + _registeredHandlers[entityID][eventName] = handler; + if (eventName == "collisionWithEntity") { + connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, &ScriptEngine::collisionWithEntity); + } + // FIXME: deletingEntity, changingEntityID +} +void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { + // FIXME +} +void ScriptEngine::collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { + if (!_registeredHandlers.contains(idA)) return; + const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[idA]; + if (!handlersOnEntity.contains("collisionWithEntity")) return; + // FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts. + QScriptValue handlerForEvent = handlersOnEntity["collisionWithEntity"]; + QScriptValueList args = QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision); + handlerForEvent.call(QScriptValue(), args); +} + void ScriptEngine::evaluate() { if (_stoppingAllScripts) { return; // bail early diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 45e56850a7..5aab43dff0 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -31,11 +31,14 @@ #include "ScriptCache.h" #include "ScriptUUID.h" #include "Vec3.h" +#include "EntityItemID.h" const QString NO_SCRIPT(""); const unsigned int SCRIPT_DATA_CALLBACK_USECS = floor(((1.0 / 60.0f) * 1000 * 1000) + 0.5); +typedef QHash RegisteredEventHandlers; + class ScriptEngine : public QScriptEngine, public ScriptUser { Q_OBJECT public: @@ -98,6 +101,9 @@ public: virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents); virtual void errorInLoadingScript(const QUrl& url); + void addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); + void removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); + public slots: void loadURL(const QUrl& scriptURL); void stop(); @@ -114,6 +120,7 @@ public slots: QUrl resolvePath(const QString& path) const; void nodeKilled(SharedNodePointer node); + void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); signals: void scriptLoaded(const QString& scriptFilename); @@ -164,6 +171,7 @@ private: ArrayBufferClass* _arrayBufferClass; QHash _outgoingScriptAudioSequenceNumbers; + QHash _registeredHandlers; private: static QSet _allKnownScriptEngines; From 1dd2b7275eec685b19a16706b8f49668a18e402c Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sat, 23 May 2015 18:11:05 -0700 Subject: [PATCH 02/12] Simpler and more uniform version that handles all the standard entity-script events. --- .../src/EntityTreeRenderer.cpp | 16 ---- .../src/EntityTreeRenderer.h | 3 - .../entities/src/EntityScriptingInterface.cpp | 11 ++- libraries/script-engine/src/ScriptEngine.cpp | 91 +++++++++++++++---- libraries/script-engine/src/ScriptEngine.h | 5 +- 5 files changed, 85 insertions(+), 41 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index a41f23a7cc..c5e0e0ccaa 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -874,22 +874,6 @@ void EntityTreeRenderer::connectSignalsToSlots(EntityScriptingInterface* entityS connect(this, &EntityTreeRenderer::enterEntity, entityScriptingInterface, &EntityScriptingInterface::enterEntity); connect(this, &EntityTreeRenderer::leaveEntity, entityScriptingInterface, &EntityScriptingInterface::leaveEntity); connect(this, &EntityTreeRenderer::collisionWithEntity, entityScriptingInterface, &EntityScriptingInterface::collisionWithEntity); - - connect(entityScriptingInterface, &EntityScriptingInterface::addEntityEventHandler, this, &EntityTreeRenderer::addEntityEventHandler); - connect(entityScriptingInterface, &EntityScriptingInterface::removeEntityEventHandler, this, &EntityTreeRenderer::addEntityEventHandler); -} - -void EntityTreeRenderer::addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - ScriptEngine* engine = static_cast(handler.engine()); - if (engine) { // In case it's gone by the time we get the signal - engine->addEntityEventHandler(entityID, entityEventName, handler); - } -} -void EntityTreeRenderer::removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - ScriptEngine* engine = static_cast(handler.engine()); - if (engine) { - engine->removeEntityEventHandler(entityID, entityEventName, handler); - } } QScriptValueList EntityTreeRenderer::createMouseEventArgs(const EntityItemID& entityID, QMouseEvent* event, unsigned int deviceID) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 2c841e6f06..ce40363261 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -121,9 +121,6 @@ public slots: void setDisplayModelBounds(bool value) { _displayModelBounds = value; } void setDisplayModelElementProxy(bool value) { _displayModelElementProxy = value; } void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; } - - void addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); - void removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); protected: virtual Octree* createTree() { return new EntityTree(true); } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index a23bb386ff..e3b48fad61 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -17,6 +17,7 @@ #include "ModelEntityItem.h" #include "ZoneEntityItem.h" #include "EntitiesLogging.h" +#include "../../script-engine/src/ScriptEngine.h" // FIXME EntityScriptingInterface::EntityScriptingInterface() : @@ -202,10 +203,16 @@ void EntityScriptingInterface::dumpTree() const { } void EntityScriptingInterface::addEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - emit addEntityEventHandler(entityID, entityEventName, handler); + ScriptEngine* engine = static_cast(handler.engine()); + if (engine) { // In case it's gone by the time we get the signal + engine->addEntityEventHandler(entityID, entityEventName, handler); + } } void EntityScriptingInterface::removeEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - emit removeEntityEventHandler(entityID, entityEventName, handler); + ScriptEngine* engine = static_cast(handler.engine()); + if (engine) { + engine->removeEntityEventHandler(entityID, entityEventName, handler); + } } QVector EntityScriptingInterface::findEntities(const glm::vec3& center, float radius) const { diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 81e30d0265..df51275ce2 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -389,30 +389,85 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func } } -void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { - auto entities = DependencyManager::get(); - if (!_registeredHandlers.contains(entityID)) { - _registeredHandlers[entityID] = RegisteredEventHandlers(); - } - _registeredHandlers[entityID][eventName] = handler; - if (eventName == "collisionWithEntity") { - connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, &ScriptEngine::collisionWithEntity); - } - // FIXME: deletingEntity, changingEntityID +// Answer the previously registered handler for the given entityID/eventName, else an invalid QScriptValue. +QScriptValue ScriptEngine::getEntityEventHandler(const EntityItemID& entityID, const QString& eventName) { + if (!_registeredHandlers.contains(entityID)) return _illegal; + const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; + if (!handlersOnEntity.contains(eventName)) return _illegal; + // FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts. + return handlersOnEntity[eventName]; } void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { // FIXME } -void ScriptEngine::collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { - if (!_registeredHandlers.contains(idA)) return; - const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[idA]; - if (!handlersOnEntity.contains("collisionWithEntity")) return; - // FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts. - QScriptValue handlerForEvent = handlersOnEntity["collisionWithEntity"]; - QScriptValueList args = QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision); - handlerForEvent.call(QScriptValue(), args); +// FIXME: deletingEntity, changingEntityID +void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { + if (!_registeredHandlers.contains(entityID)) { + _registeredHandlers[entityID] = RegisteredEventHandlers(); + } + _registeredHandlers[entityID][eventName] = handler; + + // The rest connects the Entities signal to the handler here. + auto entities = DependencyManager::get(); + + // Given thunk that generates the arglist, evaluate that thunk only if needed, and call the handler. + auto generalHandler = [=](std::function argGenerator) { + QScriptValue handlerForEvent = getEntityEventHandler(entityID, eventName); + if (handlerForEvent.isValid()) { + QScriptValueList args = argGenerator(); + handlerForEvent.call(QScriptValue(), args); + } + }; + // Two common cases of event handler, differing only in argument signature. + auto singleEntityHandler = [=](const EntityItemID& entityItemID) { + generalHandler([=]() { + return QScriptValueList() << entityItemID.toScriptValue(this); + }); + }; + auto mouseHandler = [=](const EntityItemID& entityItemID, const MouseEvent& event) { + generalHandler([=]() { + return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this); + }); + }; + // This string comparison maze only happens when adding a handler, which isn't often, rather than during events. + // Nonetheless, I wish it were more DRY. Variadic signals from strings? "I know reflection. I've worked with reflection. QT is no reflection." + if (eventName == "enterEntity") { + connect(entities.data(), &EntityScriptingInterface::enterEntity, this, singleEntityHandler); + } else if (eventName == "leaveEntity") { + connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, singleEntityHandler); + + } else if (eventName == "mousePressOnEntity") { + connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, mouseHandler); + } else if (eventName == "mouseMoveOnEntity") { + connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, mouseHandler); + } else if (eventName == "mouseReleaseOnEntity") { + connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, mouseHandler); + + } else if (eventName == "clickDownOnEntity") { + connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, mouseHandler); + } else if (eventName == "holdingClickOnEntity") { + connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, mouseHandler); + } else if (eventName == "clickReleaseOnEntity") { + connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, mouseHandler); + + } else if (eventName == "hoverEnterEntity") { + connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, mouseHandler); + } else if (eventName == "hoverOverEntity") { + connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, mouseHandler); + } else if (eventName == "hoverLeaveEntity") { + connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, mouseHandler); + + } else if (eventName == "collisionWithEntity") { + connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, + [=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { + generalHandler([=]() { + return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision); + }); + }); + } } + void ScriptEngine::evaluate() { if (_stoppingAllScripts) { return; // bail early diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 5aab43dff0..32261be2f3 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -31,7 +31,7 @@ #include "ScriptCache.h" #include "ScriptUUID.h" #include "Vec3.h" -#include "EntityItemID.h" +#include "../../entities/src/EntityItem.h" // FIXME const QString NO_SCRIPT(""); @@ -120,7 +120,6 @@ public slots: QUrl resolvePath(const QString& path) const; void nodeKilled(SharedNodePointer node); - void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); signals: void scriptLoaded(const QString& scriptFilename); @@ -172,6 +171,8 @@ private: QHash _outgoingScriptAudioSequenceNumbers; QHash _registeredHandlers; + QScriptValue _illegal; + QScriptValue getEntityEventHandler(const EntityItemID& entityID, const QString& eventName); private: static QSet _allKnownScriptEngines; From b884d3cf90483792a9daaec91e9a8bbfc0d78883 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sun, 24 May 2015 09:57:12 -0700 Subject: [PATCH 03/12] Handle all the signals. --- .../entities/src/EntityScriptingInterface.cpp | 2 + .../entities/src/EntityScriptingInterface.h | 1 + libraries/script-engine/src/ScriptEngine.cpp | 128 +++++++++--------- libraries/script-engine/src/ScriptEngine.h | 3 +- 4 files changed, 69 insertions(+), 65 deletions(-) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index e3b48fad61..152c1621ef 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -47,6 +47,7 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { if (_entityTree) { disconnect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity); disconnect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity); + disconnect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID); disconnect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities); } @@ -55,6 +56,7 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { if (_entityTree) { connect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity); connect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity); + connect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID); connect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities); } } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index c04e55a8a0..508a566ed2 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -150,6 +150,7 @@ signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); + void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void clearingEntities(); private: diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index df51275ce2..f3ff41f19a 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -389,82 +389,84 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func } } -// Answer the previously registered handler for the given entityID/eventName, else an invalid QScriptValue. -QScriptValue ScriptEngine::getEntityEventHandler(const EntityItemID& entityID, const QString& eventName) { - if (!_registeredHandlers.contains(entityID)) return _illegal; +// Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args +void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function argGenerator) { + if (!_registeredHandlers.contains(entityID)) return; const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; - if (!handlersOnEntity.contains(eventName)) return _illegal; + if (!handlersOnEntity.contains(eventName)) return; // FIXME: Need one more level of indirection. We need to allow multiple handlers per event, registered by different scripts. - return handlersOnEntity[eventName]; + QScriptValue handlerForEvent = handlersOnEntity[eventName]; + if (handlerForEvent.isValid()) { + QScriptValueList args = argGenerator(); + handlerForEvent.call(QScriptValue(), args); + } } +// Unregister the handler for this eventName and entityID. void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { - // FIXME + if (!_registeredHandlers.contains(entityID)) return; + RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; + if (!handlersOnEntity.contains(eventName)) return; + handlersOnEntity.remove(eventName); } // FIXME: deletingEntity, changingEntityID +// Register the handler. void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { - if (!_registeredHandlers.contains(entityID)) { - _registeredHandlers[entityID] = RegisteredEventHandlers(); - } - _registeredHandlers[entityID][eventName] = handler; - - // The rest connects the Entities signal to the handler here. - auto entities = DependencyManager::get(); - - // Given thunk that generates the arglist, evaluate that thunk only if needed, and call the handler. - auto generalHandler = [=](std::function argGenerator) { - QScriptValue handlerForEvent = getEntityEventHandler(entityID, eventName); - if (handlerForEvent.isValid()) { - QScriptValueList args = argGenerator(); - handlerForEvent.call(QScriptValue(), args); - } - }; - // Two common cases of event handler, differing only in argument signature. - auto singleEntityHandler = [=](const EntityItemID& entityItemID) { - generalHandler([=]() { - return QScriptValueList() << entityItemID.toScriptValue(this); - }); - }; - auto mouseHandler = [=](const EntityItemID& entityItemID, const MouseEvent& event) { - generalHandler([=]() { - return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this); - }); - }; - // This string comparison maze only happens when adding a handler, which isn't often, rather than during events. - // Nonetheless, I wish it were more DRY. Variadic signals from strings? "I know reflection. I've worked with reflection. QT is no reflection." - if (eventName == "enterEntity") { - connect(entities.data(), &EntityScriptingInterface::enterEntity, this, singleEntityHandler); - } else if (eventName == "leaveEntity") { - connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, singleEntityHandler); - - } else if (eventName == "mousePressOnEntity") { - connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, mouseHandler); - } else if (eventName == "mouseMoveOnEntity") { - connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, mouseHandler); - } else if (eventName == "mouseReleaseOnEntity") { - connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, mouseHandler); - - } else if (eventName == "clickDownOnEntity") { - connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, mouseHandler); - } else if (eventName == "holdingClickOnEntity") { - connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, mouseHandler); - } else if (eventName == "clickReleaseOnEntity") { - connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, mouseHandler); - - } else if (eventName == "hoverEnterEntity") { - connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, mouseHandler); - } else if (eventName == "hoverOverEntity") { - connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, mouseHandler); - } else if (eventName == "hoverLeaveEntity") { - connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, mouseHandler); - - } else if (eventName == "collisionWithEntity") { + if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script... + // Connect up ALL the handlers to the global entities object's signals. + // (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.) + auto entities = DependencyManager::get(); + connect(entities.data(), &EntityScriptingInterface::deletingEntity, this, + [=](const EntityItemID& entityID) { + _registeredHandlers.remove(entityID); + }); + connect(entities.data(), &EntityScriptingInterface::changingEntityID, this, + [=](const EntityItemID& oldEntityID, const EntityItemID& newEntityID) { + if (!_registeredHandlers.contains(oldEntityID)) return; + _registeredHandlers[newEntityID] = _registeredHandlers[oldEntityID]; + _registeredHandlers.remove(oldEntityID); + }); + + // Two common cases of event handler, differing only in argument signature. + auto makeSingleEntityHandler = [=](const QString& eventName) { + return [=](const EntityItemID& entityItemID) { + generalHandler(entityItemID, eventName, [=]() { + return QScriptValueList() << entityItemID.toScriptValue(this); + }); + }; + }; + auto makeMouseHandler = [=](const QString& eventName) { + return [=](const EntityItemID& entityItemID, const MouseEvent& event) { + generalHandler(entityItemID, eventName, [=]() { + return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this); + }); + }; + }; + connect(entities.data(), &EntityScriptingInterface::enterEntity, this, makeSingleEntityHandler("enterEntity")); + connect(entities.data(), &EntityScriptingInterface::leaveEntity, this, makeSingleEntityHandler("leaveEntity")); + + connect(entities.data(), &EntityScriptingInterface::mousePressOnEntity, this, makeMouseHandler("mousePressOnEntity")); + connect(entities.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, makeMouseHandler("mouseMoveOnEntity")); + connect(entities.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, makeMouseHandler("mouseReleaseOnEntity")); + + connect(entities.data(), &EntityScriptingInterface::clickDownOnEntity, this, makeMouseHandler("clickDownOnEntity")); + connect(entities.data(), &EntityScriptingInterface::holdingClickOnEntity, this, makeMouseHandler("holdingClickOnEntity")); + connect(entities.data(), &EntityScriptingInterface::clickReleaseOnEntity, this, makeMouseHandler("clickReleaseOnEntity")); + + connect(entities.data(), &EntityScriptingInterface::hoverEnterEntity, this, makeMouseHandler("hoverEnterEntity")); + connect(entities.data(), &EntityScriptingInterface::hoverOverEntity, this, makeMouseHandler("hoverOverEntity")); + connect(entities.data(), &EntityScriptingInterface::hoverLeaveEntity, this, makeMouseHandler("hoverLeaveEntity")); + connect(entities.data(), &EntityScriptingInterface::collisionWithEntity, this, [=](const EntityItemID& idA, const EntityItemID& idB, const Collision& collision) { - generalHandler([=]() { + generalHandler(idA, "collisionWithEntity", [=]() { return QScriptValueList () << idA.toScriptValue(this) << idB.toScriptValue(this) << collisionToScriptValue(this, collision); }); }); } + if (!_registeredHandlers.contains(entityID)) { + _registeredHandlers[entityID] = RegisteredEventHandlers(); + } + _registeredHandlers[entityID][eventName] = handler; } diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 32261be2f3..28610fd65c 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -171,8 +171,7 @@ private: QHash _outgoingScriptAudioSequenceNumbers; QHash _registeredHandlers; - QScriptValue _illegal; - QScriptValue getEntityEventHandler(const EntityItemID& entityID, const QString& eventName); + void generalHandler(const EntityItemID& entityID, const QString& eventName, std::function argGenerator); private: static QSet _allKnownScriptEngines; From a0d09c0a6d95125e5dd5d2f3de5b3e3112b14778 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Sun, 24 May 2015 11:48:11 -0700 Subject: [PATCH 04/12] Mulitple independent handlers for same entity/event. --- libraries/script-engine/src/ScriptEngine.cpp | 24 +++++++++++++------- libraries/script-engine/src/ScriptEngine.h | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) 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 From 4266a99d786a23e2a32b615a8374a49dfa5005f9 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 25 May 2015 11:28:33 -0700 Subject: [PATCH 05/12] Put the javascript methods on Script, not Entities, and other minimum-diff cleanup. --- .../entities-renderer/src/EntityTreeRenderer.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 15 --------------- libraries/entities/src/EntityScriptingInterface.h | 7 ------- libraries/script-engine/src/ScriptEngine.cpp | 4 ++-- libraries/script-engine/src/ScriptEngine.h | 6 +++--- 5 files changed, 6 insertions(+), 28 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index ce40363261..1f03e01e7c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -121,7 +121,7 @@ public slots: void setDisplayModelBounds(bool value) { _displayModelBounds = value; } void setDisplayModelElementProxy(bool value) { _displayModelElementProxy = value; } void setDontDoPrecisionPicking(bool value) { _dontDoPrecisionPicking = value; } - + protected: virtual Octree* createTree() { return new EntityTree(true); } diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 152c1621ef..1460e90a4d 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -17,8 +17,6 @@ #include "ModelEntityItem.h" #include "ZoneEntityItem.h" #include "EntitiesLogging.h" -#include "../../script-engine/src/ScriptEngine.h" // FIXME - EntityScriptingInterface::EntityScriptingInterface() : _entityTree(NULL) @@ -204,19 +202,6 @@ void EntityScriptingInterface::dumpTree() const { } } -void EntityScriptingInterface::addEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - ScriptEngine* engine = static_cast(handler.engine()); - if (engine) { // In case it's gone by the time we get the signal - engine->addEntityEventHandler(entityID, entityEventName, handler); - } -} -void EntityScriptingInterface::removeEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler) { - ScriptEngine* engine = static_cast(handler.engine()); - if (engine) { - engine->removeEntityEventHandler(entityID, entityEventName, handler); - } -} - QVector EntityScriptingInterface::findEntities(const glm::vec3& center, float radius) const { QVector result; if (_entityTree) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 508a566ed2..ca6e266e98 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -119,14 +119,7 @@ public slots: Q_INVOKABLE void dumpTree() const; - // Register a function that will handle the given entityEventName on entityID - Q_INVOKABLE void addEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); - Q_INVOKABLE void removeEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); - signals: - void addEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); - void removeEntityEventHandler(EntityItemID entityID, QString entityEventName, QScriptValue handler); - void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); void collisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e1e920da59..039ab8a19b 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -404,7 +404,7 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e } } // Unregister the handlers for this eventName and entityID. -void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { +void ScriptEngine::removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { if (!_registeredHandlers.contains(entityID)) return; RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; QScriptValueList& handlersForEvent = handlersOnEntity[eventName]; @@ -417,7 +417,7 @@ void ScriptEngine::removeEntityEventHandler(const EntityItemID& entityID, const } } // Register the handler. -void ScriptEngine::addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { +void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { if (_registeredHandlers.count() == 0) { // First time any per-entity handler has been added in this script... // Connect up ALL the handlers to the global entities object's signals. // (We could go signal by signal, or even handler by handler, but I don't think the efficiency is worth the complexity.) diff --git a/libraries/script-engine/src/ScriptEngine.h b/libraries/script-engine/src/ScriptEngine.h index 0fd8ed0562..175eff059f 100644 --- a/libraries/script-engine/src/ScriptEngine.h +++ b/libraries/script-engine/src/ScriptEngine.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "AbstractControllerScriptingInterface.h" #include "ArrayBufferClass.h" @@ -31,7 +32,6 @@ #include "ScriptCache.h" #include "ScriptUUID.h" #include "Vec3.h" -#include "../../entities/src/EntityItem.h" // FIXME const QString NO_SCRIPT(""); @@ -101,8 +101,8 @@ public: virtual void scriptContentsAvailable(const QUrl& url, const QString& scriptContents); virtual void errorInLoadingScript(const QUrl& url); - void addEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); - void removeEntityEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); + Q_INVOKABLE void addEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); + Q_INVOKABLE void removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler); public slots: void loadURL(const QUrl& scriptURL); From 599886079d81549a4fa5e8af1a6182682c0c98c2 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 25 May 2015 11:33:12 -0700 Subject: [PATCH 06/12] Restore blank line for minimum diff. --- libraries/entities/src/EntityScriptingInterface.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 1460e90a4d..b888a69a8b 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -18,6 +18,7 @@ #include "ZoneEntityItem.h" #include "EntitiesLogging.h" + EntityScriptingInterface::EntityScriptingInterface() : _entityTree(NULL) { From 1b134d60d5f970494d6d88fb57a015510485d197 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 25 May 2015 15:46:55 -0700 Subject: [PATCH 07/12] Fix typo that messed up the otherEntity for collisions. --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c5e0e0ccaa..a96c1014a2 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1198,7 +1198,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons entityScriptA.property("collisionWithEntity").call(entityScriptA, args); } - emit collisionWithEntity(idB, idB, collision); + emit collisionWithEntity(idB, idA, collision); QScriptValue entityScriptB = loadEntityScript(idB); if (entityScriptB.property("collisionWithEntity").isValid()) { QScriptValueList args; From 069e6237cc6650a44b9027b2038af9831e9f81d8 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Mon, 25 May 2015 16:52:14 -0700 Subject: [PATCH 08/12] Noop change with more declarations, in hopes of convincing MSVS how lambdas work. (Hey, it's worth a try...) --- libraries/script-engine/src/ScriptEngine.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 039ab8a19b..a8755c362c 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -434,16 +434,16 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& }); // Two common cases of event handler, differing only in argument signature. - auto makeSingleEntityHandler = [=](const QString& eventName) { - return [=](const EntityItemID& entityItemID) { - generalHandler(entityItemID, eventName, [=]() { + auto makeSingleEntityHandler = [=](const QString& eventName) -> std::function { + return [=](const EntityItemID& entityItemID) -> void { + generalHandler(entityItemID, eventName, [=]() -> QScriptValueList { return QScriptValueList() << entityItemID.toScriptValue(this); }); }; }; - auto makeMouseHandler = [=](const QString& eventName) { - return [=](const EntityItemID& entityItemID, const MouseEvent& event) { - generalHandler(entityItemID, eventName, [=]() { + auto makeMouseHandler = [=](const QString& eventName) -> std::function { + return [=](const EntityItemID& entityItemID, const MouseEvent& event) -> void { + generalHandler(entityItemID, eventName, [=]() -> QScriptValueList { return QScriptValueList() << entityItemID.toScriptValue(this) << event.toScriptValue(this); }); }; From bbdf9f1d9f81fbec7608d24552c03310812fb514 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 26 May 2015 11:14:23 -0700 Subject: [PATCH 09/12] Remove changingEntityID. --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 9 --------- libraries/entities-renderer/src/EntityTreeRenderer.h | 1 - libraries/entities/src/EntityScriptingInterface.cpp | 2 -- libraries/entities/src/EntityScriptingInterface.h | 1 - libraries/entities/src/EntityTree.h | 1 - libraries/script-engine/src/ScriptEngine.cpp | 6 ------ 6 files changed, 20 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index a96c1014a2..5dbe5a782d 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -113,7 +113,6 @@ void EntityTreeRenderer::init() { connect(entityTree, &EntityTree::deletingEntity, this, &EntityTreeRenderer::deletingEntity); connect(entityTree, &EntityTree::addingEntity, this, &EntityTreeRenderer::addingEntity); connect(entityTree, &EntityTree::entityScriptChanging, this, &EntityTreeRenderer::entitySciptChanging); - connect(entityTree, &EntityTree::changingEntityID, this, &EntityTreeRenderer::changingEntityID); } void EntityTreeRenderer::shutdown() { @@ -1102,14 +1101,6 @@ void EntityTreeRenderer::checkAndCallUnload(const EntityItemID& entityID) { } -void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID) { - if (_entityScripts.contains(oldEntityID)) { - EntityScriptDetails details = _entityScripts[oldEntityID]; - _entityScripts.remove(oldEntityID); - _entityScripts[newEntityID] = details; - } -} - void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) { EntityItem* entity = entityTree->findEntityByEntityItemID(id); if (!entity) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 1f03e01e7c..909aaae209 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -112,7 +112,6 @@ signals: public slots: void addingEntity(const EntityItemID& entityID); void deletingEntity(const EntityItemID& entityID); - void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void entitySciptChanging(const EntityItemID& entityID); void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index b888a69a8b..351bbc3643 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -46,7 +46,6 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { if (_entityTree) { disconnect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity); disconnect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity); - disconnect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID); disconnect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities); } @@ -55,7 +54,6 @@ void EntityScriptingInterface::setEntityTree(EntityTree* modelTree) { if (_entityTree) { connect(_entityTree, &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity); connect(_entityTree, &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity); - connect(_entityTree, &EntityTree::changingEntityID, this, &EntityScriptingInterface::changingEntityID); connect(_entityTree, &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities); } } diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index ca6e266e98..d60a63ffd0 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -143,7 +143,6 @@ signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); - void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void clearingEntities(); private: diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 43cd8780ab..3168495704 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -171,7 +171,6 @@ signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); void entityScriptChanging(const EntityItemID& entityItemID); - void changingEntityID(const EntityItemID& oldEntityID, const EntityItemID& newEntityID); void clearingEntities(); private: diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index a8755c362c..0dc7db758f 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -426,12 +426,6 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& [=](const EntityItemID& entityID) { _registeredHandlers.remove(entityID); }); - connect(entities.data(), &EntityScriptingInterface::changingEntityID, this, - [=](const EntityItemID& oldEntityID, const EntityItemID& newEntityID) { - if (!_registeredHandlers.contains(oldEntityID)) return; - _registeredHandlers[newEntityID] = _registeredHandlers[oldEntityID]; - _registeredHandlers.remove(oldEntityID); - }); // Two common cases of event handler, differing only in argument signature. auto makeSingleEntityHandler = [=](const QString& eventName) -> std::function { From 5608892a159d2818095f6f9f745996511a3033a2 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 26 May 2015 11:16:11 -0700 Subject: [PATCH 10/12] Remove obsolete comment. --- libraries/script-engine/src/ScriptEngine.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 0dc7db758f..e93c55c4aa 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -394,7 +394,6 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e if (!_registeredHandlers.contains(entityID)) return; 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. QScriptValueList handlersForEvent = handlersOnEntity[eventName]; if (!handlersForEvent.isEmpty()) { QScriptValueList args = argGenerator(); From 3a7a290094cc82d095b3d7147e7fd2b42130df77 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Tue, 26 May 2015 11:38:36 -0700 Subject: [PATCH 11/12] Uglify conditional returns. :-) --- libraries/script-engine/src/ScriptEngine.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index e93c55c4aa..91a4e3c397 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -391,9 +391,13 @@ void ScriptEngine::registerGetterSetter(const QString& name, QScriptEngine::Func // Look up the handler associated with eventName and entityID. If found, evalute the argGenerator thunk and call the handler with those args void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& eventName, std::function argGenerator) { - if (!_registeredHandlers.contains(entityID)) return; + if (!_registeredHandlers.contains(entityID)) { + return; + } const RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; - if (!handlersOnEntity.contains(eventName)) return; + if (!handlersOnEntity.contains(eventName)) { + return; + } QScriptValueList handlersForEvent = handlersOnEntity[eventName]; if (!handlersForEvent.isEmpty()) { QScriptValueList args = argGenerator(); @@ -404,7 +408,9 @@ void ScriptEngine::generalHandler(const EntityItemID& entityID, const QString& e } // Unregister the handlers for this eventName and entityID. void ScriptEngine::removeEventHandler(const EntityItemID& entityID, const QString& eventName, QScriptValue handler) { - if (!_registeredHandlers.contains(entityID)) return; + if (!_registeredHandlers.contains(entityID)) { + return; + } RegisteredEventHandlers& handlersOnEntity = _registeredHandlers[entityID]; QScriptValueList& handlersForEvent = handlersOnEntity[eventName]; // QScriptValue does not have operator==(), so we can't use QList::removeOne and friends. So iterate. From 857552ae0bc4395330b2055d5ad489d598e816c8 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 26 May 2015 15:16:23 -0700 Subject: [PATCH 12/12] don't hold back link event for account connect --- domain-server/resources/web/settings/js/settings.js | 1 - 1 file changed, 1 deletion(-) diff --git a/domain-server/resources/web/settings/js/settings.js b/domain-server/resources/web/settings/js/settings.js index 3ef69d817b..c733256fe3 100644 --- a/domain-server/resources/web/settings/js/settings.js +++ b/domain-server/resources/web/settings/js/settings.js @@ -262,7 +262,6 @@ $(document).ready(function(){ $('#' + Settings.FORM_ID).on('click', '#' + Settings.CONNECT_ACCOUNT_BTN_ID, function(e){ $(this).blur(); prepareAccessTokenPrompt(); - e.preventDefault(); }); var panelsSource = $('#panels-template').html()