mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-08 07:22:25 +02:00
fix thread safety issue on JS based fliters
This commit is contained in:
parent
7d48fe9187
commit
7956d737ab
5 changed files with 75 additions and 27 deletions
|
@ -23,17 +23,21 @@ function findAction(name) {
|
|||
}
|
||||
|
||||
|
||||
var hydra = Controller.Hardware.Hydra2;
|
||||
var hydra = Controller.Hardware.Hydra;
|
||||
if (hydra !== undefined) {
|
||||
print("-----------------------------------");
|
||||
var mapping = NewControllers.newMapping("Default");
|
||||
var mapping = Controller.newMapping("Test");
|
||||
var standard = Controller.Standard;
|
||||
print("standard:" + standard);
|
||||
mapping.from(hydra.LeftButton1).to(standard.A);
|
||||
mapping.from(hydra.LeftButton2).to(standard.B);
|
||||
mapping.from(hydra.LeftButton3).to(standard.X);
|
||||
NewControllers.enableMapping("Default");
|
||||
mapping.from(hydra.L1).to(standard.A);
|
||||
mapping.from(hydra.L2).to(standard.B);
|
||||
mapping.from(hydra.L3).to(function (newValue, oldValue, source) {
|
||||
print("hydra.L3 newValue:" + newValue + ", oldValue:" + oldValue + ", source:" + source);
|
||||
});
|
||||
Controller.enableMapping("Test");
|
||||
print("-----------------------------------");
|
||||
} else {
|
||||
print("couldn't find hydra");
|
||||
}
|
||||
|
||||
Object.keys(Controller.Standard).forEach(function (input) {
|
||||
|
|
|
@ -11,3 +11,8 @@
|
|||
namespace controller {
|
||||
|
||||
}
|
||||
|
||||
// FIXME - do we want to include the source Endpoint::Pointer in our calls to JS? If
|
||||
// so we need to marshall this across the invokeMethod() properly
|
||||
//static int EndpointPointerMetaTypeId = qRegisterMetaType<controller::Endpoint::Pointer>("controller::Endpoint::Pointer");
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace controller {
|
|||
* Encapsulates a particular input / output,
|
||||
* i.e. Hydra.Button0, Standard.X, Action.Yaw
|
||||
*/
|
||||
class Endpoint {
|
||||
class Endpoint : public QObject {
|
||||
Q_OBJECT;
|
||||
public:
|
||||
using Pointer = std::shared_ptr<Endpoint>;
|
||||
using List = std::list<Pointer>;
|
||||
|
@ -31,12 +32,12 @@ namespace controller {
|
|||
using ReadLambda = std::function<float()>;
|
||||
using WriteLambda = std::function<void(float)>;
|
||||
|
||||
Endpoint(const UserInputMapper::Input& id) : _id(id) {}
|
||||
Endpoint(const UserInputMapper::Input& input) : _input(input) {}
|
||||
virtual float value() = 0;
|
||||
virtual void apply(float newValue, float oldValue, const Pointer& source) = 0;
|
||||
const UserInputMapper::Input& getId() { return _id; }
|
||||
const UserInputMapper::Input& getInput() { return _input; }
|
||||
protected:
|
||||
UserInputMapper::Input _id;
|
||||
UserInputMapper::Input _input;
|
||||
};
|
||||
|
||||
class LambdaEndpoint : public Endpoint {
|
||||
|
@ -53,4 +54,8 @@ namespace controller {
|
|||
};
|
||||
}
|
||||
|
||||
// FIXME - do we want to include the source Endpoint::Pointer in our calls to JS? If
|
||||
// so we need to marshall this across the invokeMethod() properly
|
||||
//Q_DECLARE_METATYPE(controller::Endpoint::Pointer);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QEventLoop>
|
||||
#include <QThread>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <DependencyManager.h>
|
||||
|
@ -60,24 +61,37 @@ namespace controller {
|
|||
QJSValue _callable;
|
||||
};
|
||||
|
||||
class ScriptEndpoint : public Endpoint {
|
||||
public:
|
||||
ScriptEndpoint(const QScriptValue& callable)
|
||||
: Endpoint(UserInputMapper::Input::INVALID_INPUT), _callable(callable) {
|
||||
float ScriptEndpoint::value() {
|
||||
if (QThread::currentThread() == thread()) {
|
||||
updateValue();
|
||||
}
|
||||
return _lastValue;
|
||||
}
|
||||
|
||||
void ScriptEndpoint::updateValue() {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "updateValue", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
virtual float value() {
|
||||
float result = (float)_callable.call().toNumber();
|
||||
return result;
|
||||
}
|
||||
_lastValue = (float)_callable.call().toNumber();
|
||||
}
|
||||
|
||||
virtual void apply(float newValue, float oldValue, const Pointer& source) {
|
||||
_callable.call(QScriptValue(), QScriptValueList({ QScriptValue(newValue) }));
|
||||
}
|
||||
void ScriptEndpoint::apply(float newValue, float oldValue, const Pointer& source) {
|
||||
internalApply(newValue, oldValue, source->getInput().getID());
|
||||
}
|
||||
|
||||
private:
|
||||
QScriptValue _callable;
|
||||
};
|
||||
void ScriptEndpoint::internalApply(float newValue, float oldValue, int sourceID) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "internalApply", Qt::QueuedConnection,
|
||||
Q_ARG(float, newValue),
|
||||
Q_ARG(float, oldValue),
|
||||
Q_ARG(int, sourceID));
|
||||
return;
|
||||
}
|
||||
_callable.call(QScriptValue(),
|
||||
QScriptValueList({ QScriptValue(newValue), QScriptValue(oldValue), QScriptValue(sourceID) }));
|
||||
}
|
||||
|
||||
class CompositeEndpoint : public Endpoint, Endpoint::Pair {
|
||||
public:
|
||||
|
@ -108,9 +122,9 @@ namespace controller {
|
|||
virtual void apply(float newValue, float oldValue, const Pointer& source) override {
|
||||
|
||||
_currentValue += newValue;
|
||||
if (!(_id == UserInputMapper::Input::INVALID_INPUT)) {
|
||||
if (!(_input == UserInputMapper::Input::INVALID_INPUT)) {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
userInputMapper->deltaActionState(UserInputMapper::Action(_id.getChannel()), newValue);
|
||||
userInputMapper->deltaActionState(UserInputMapper::Action(_input.getChannel()), newValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,7 +341,7 @@ namespace controller {
|
|||
}
|
||||
|
||||
// Standard controller destinations can only be can only be used once.
|
||||
if (userInputMapper->getStandardDeviceID() == destination->getId().getDevice()) {
|
||||
if (userInputMapper->getStandardDeviceID() == destination->getInput().getDevice()) {
|
||||
writtenEndpoints.insert(destination);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QThread>
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVariant>
|
||||
|
||||
|
@ -138,6 +139,25 @@ namespace controller {
|
|||
MappingMap _mappingsByName;
|
||||
MappingStack _activeMappings;
|
||||
};
|
||||
|
||||
class ScriptEndpoint : public Endpoint {
|
||||
Q_OBJECT;
|
||||
public:
|
||||
ScriptEndpoint(const QScriptValue& callable)
|
||||
: Endpoint(UserInputMapper::Input::INVALID_INPUT), _callable(callable) {
|
||||
}
|
||||
|
||||
virtual float value();
|
||||
virtual void apply(float newValue, float oldValue, const Pointer& source);
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void updateValue();
|
||||
Q_INVOKABLE virtual void internalApply(float newValue, float oldValue, int sourceID);
|
||||
private:
|
||||
QScriptValue _callable;
|
||||
float _lastValue = 0.0f;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue