diff --git a/src/control/controlobjectscript.cpp b/src/control/controlobjectscript.cpp index 2a14e079ac96..62fbd81e1266 100644 --- a/src/control/controlobjectscript.cpp +++ b/src/control/controlobjectscript.cpp @@ -40,15 +40,7 @@ void ControlObjectScript::slotValueChanged(double value, QObject*) { // itself. Otherwise the this may crash since the disconnect call // happens during conn.function.call() in the middle of the loop below. QList connections = m_connectedScriptFunctions; - for(auto&& conn: connections) { - QScriptValueList args; - args << QScriptValue(value); - args << QScriptValue(getKey().group); - args << QScriptValue(getKey().item); - QScriptValue result = conn.function.call(conn.context, args); - if (result.isError()) { - qWarning() << "ControllerEngine: Invocation of callback" << conn.id - << "failed:" << result.toString(); - } + for (auto&& conn: connections) { + conn.executeCallback(value); } } diff --git a/src/controllers/controllerengine.cpp b/src/controllers/controllerengine.cpp index 002a8e4a8472..2de070e3a544 100644 --- a/src/controllers/controllerengine.cpp +++ b/src/controllers/controllerengine.cpp @@ -807,6 +807,23 @@ QScriptValue ControllerEngine::connectControl( return QScriptValue(false); } +/* -------- ------------------------------------------------------ + Purpose: Execute a ControllerEngineConnection's callback + Input: the value of the connected ControlObject to pass to the callback + -------- ------------------------------------------------------ */ +void ControllerEngineConnection::executeCallback(double value) const { + QScriptValueList args; + args << QScriptValue(value); + args << QScriptValue(key.group); + args << QScriptValue(key.item); + QScriptValue func = function; // copy function because QScriptValue::call is not const + QScriptValue result = func.call(context, args); + if (result.isError()) { + qWarning() << "ControllerEngine: Invocation of callback" << id + << "failed:" << result.toString(); + } +} + /* -------- ------------------------------------------------------ Purpose: (Dis)connects a ControllerEngineConnection Input: the ControllerEngineConnection to disconnect @@ -835,13 +852,16 @@ void ControllerEngineConnectionScriptValue::disconnect() { Input: the ControllerEngineConnection to trigger -------- ------------------------------------------------------ */ void ControllerEngine::triggerControl(const ControllerEngineConnection conn) { - ControlObjectScript* coScript = getControlObjectScript(conn.key.group, conn.key.item); + if (m_pEngine == nullptr) { + return; + } - if (m_pEngine == nullptr || coScript == nullptr) { + ControlObjectScript* coScript = getControlObjectScript(conn.key.group, conn.key.item); + if (coScript == nullptr) { return; } - coScript->emitValueChanged(); + conn.executeCallback(coScript->get()); } void ControllerEngineConnectionScriptValue::trigger() { diff --git a/src/controllers/controllerengine.h b/src/controllers/controllerengine.h index 3902df74bdf6..2ee4d0440f74 100644 --- a/src/controllers/controllerengine.h +++ b/src/controllers/controllerengine.h @@ -33,6 +33,8 @@ class ControllerEngineConnection { QScriptValue function; ControllerEngine *ce; QScriptValue context; + + void executeCallback(double value) const; }; class ControllerEngineConnectionScriptValue : public QObject { diff --git a/src/test/controllerengine_test.cpp b/src/test/controllerengine_test.cpp index fb8324410b85..df1e8a483153 100644 --- a/src/test/controllerengine_test.cpp +++ b/src/test/controllerengine_test.cpp @@ -335,3 +335,28 @@ TEST_F(ControllerEngineTest, connectControl_DisconnectByConnectionObject) { // The counter should have been incremented exactly once. EXPECT_DOUBLE_EQ(1.0, pass->get()); } + +TEST_F(ControllerEngineTest, connectControl_TriggerByConnectionObject) { + // Test that triggering using the 'trigger' method on the connection + // object returned from connectControl works. + auto co = std::make_unique(ConfigKey("[Test]", "co")); + auto counter = std::make_unique(ConfigKey("[Test]", "counter")); + + ScopedTemporaryFile script(makeTemporaryFile( + "var incrementCounterCO = function () {" + " var counter = engine.getValue('[Test]', 'counter');" + " engine.setValue('[Test]', 'counter', counter + 1);" + "};" + "var connection1 = engine.connectControl('[Test]', 'co', incrementCounterCO);" + // Make a second connection with the same ControlObject + // to check that triggering a connection object only triggers that callback, + // not every callback connected to its ControlObject. + "var connection2 = engine.connectControl('[Test]', 'co', incrementCounterCO);" + "connection1.trigger();" + )); + + cEngine->evaluate(script->fileName()); + EXPECT_FALSE(cEngine->hasErrors(script->fileName())); + // The counter should have been incremented exactly once. + EXPECT_DOUBLE_EQ(1.0, counter->get()); +}