Merge pull request #6250 from jherico/peek

Adding peek support for endpoints
This commit is contained in:
Brad Hefta-Gaub 2015-10-31 16:09:27 -07:00
commit 286905c20c
19 changed files with 74 additions and 42 deletions

View file

@ -910,8 +910,8 @@ var leftController = new MyController(LEFT_HAND);
var MAPPING_NAME = "com.highfidelity.handControllerGrab";
var mapping = Controller.newMapping(MAPPING_NAME);
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).to(rightController.eitherTrigger);
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).to(leftController.eitherTrigger);
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).peek().to(rightController.eitherTrigger);
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).peek().to(leftController.eitherTrigger);
Controller.enableMapping(MAPPING_NAME);

View file

@ -513,7 +513,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
// and someone else wires it to CONTEXT_MENU, I don't want both to occur when
// I press the button. The exception is if I'm wiring a control back to itself
// in order to adjust my interface, like inverting the Y axis on an analog stick
if (!source->readable()) {
if (!route->peek && !source->readable()) {
if (debugRoutes && route->debug) {
qCDebug(controllers) << "Source unreadable";
}
@ -539,7 +539,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
// Fetch the value, may have been overriden by previous loopback routes
if (source->isPose()) {
Pose value = getPose(source);
Pose value = getPose(source, route->peek);
static const Pose IDENTITY_POSE { vec3(), quat() };
if (debugRoutes && route->debug) {
if (!value.valid) {
@ -554,7 +554,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
destination->apply(value, source);
} else {
// Fetch the value, may have been overriden by previous loopback routes
float value = getValue(source);
float value = getValue(source, route->peek);
if (debugRoutes && route->debug) {
qCDebug(controllers) << "Value was " << value;
@ -691,8 +691,8 @@ void UserInputMapper::enableMapping(const QString& mappingName, bool enable) {
}
}
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint) {
return endpoint->value();
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint, bool peek) {
return peek ? endpoint->peek() : endpoint->value();
}
float UserInputMapper::getValue(const Input& input) const {
@ -704,11 +704,11 @@ float UserInputMapper::getValue(const Input& input) const {
return endpoint->value();
}
Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint) {
Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint, bool peek) {
if (!endpoint->isPose()) {
return Pose();
}
return endpoint->pose();
return peek ? endpoint->peekPose() : endpoint->pose();
}
Pose UserInputMapper::getPose(const Input& input) const {
@ -742,6 +742,7 @@ static const QString JSON_NAME = QStringLiteral("name");
static const QString JSON_CHANNELS = QStringLiteral("channels");
static const QString JSON_CHANNEL_FROM = QStringLiteral("from");
static const QString JSON_CHANNEL_DEBUG = QStringLiteral("debug");
static const QString JSON_CHANNEL_PEEK = QStringLiteral("peek");
static const QString JSON_CHANNEL_WHEN = QStringLiteral("when");
static const QString JSON_CHANNEL_TO = QStringLiteral("to");
static const QString JSON_CHANNEL_FILTERS = QStringLiteral("filters");
@ -953,6 +954,7 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) {
result->json = QString(QJsonDocument(obj).toJson());
result->source = parseSource(obj[JSON_CHANNEL_FROM]);
result->debug = obj[JSON_CHANNEL_DEBUG].toBool();
result->debug = obj[JSON_CHANNEL_PEEK].toBool();
if (!result->source) {
qWarning() << "Invalid route source " << obj[JSON_CHANNEL_FROM];
return Route::Pointer();

View file

@ -38,8 +38,8 @@ namespace controller {
class UserInputMapper : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
Q_ENUMS(Action)
SINGLETON_DEPENDENCY
Q_ENUMS(Action)
public:
// FIXME move to unordered set / map
@ -135,8 +135,8 @@ namespace controller {
int recordDeviceOfType(const QString& deviceName);
QHash<const QString&, int> _deviceCounts;
static float getValue(const EndpointPointer& endpoint);
static Pose getPose(const EndpointPointer& endpoint);
static float getValue(const EndpointPointer& endpoint, bool peek = false);
static Pose getPose(const EndpointPointer& endpoint, bool peek = false);
friend class RouteBuilderProxy;
friend class MappingBuilderProxy;

View file

@ -36,12 +36,13 @@ namespace controller {
using WriteLambda = std::function<void(float)>;
Endpoint(const Input& input) : _input(input) {}
virtual float value() = 0;
virtual float value() { return peek(); }
virtual float peek() const = 0;
virtual void apply(float value, const Pointer& source) = 0;
virtual Pose pose() { return Pose(); }
virtual Pose peekPose() const { return Pose(); };
virtual Pose pose() { return peekPose(); }
virtual void apply(const Pose& value, const Pointer& source) {}
virtual bool isPose() { return _input.isPose(); }
virtual bool isPose() const { return _input.isPose(); }
virtual bool writeable() const { return true; }
virtual bool readable() const { return true; }
virtual void reset() { }
@ -58,7 +59,7 @@ namespace controller {
LambdaEndpoint(ReadLambda readLambda, WriteLambda writeLambda = [](float) {})
: Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) { }
virtual float value() override { return _readLambda(); }
virtual float peek() const override { return _readLambda(); }
virtual void apply(float value, const Pointer& source) override { _writeLambda(value); }
private:
@ -73,10 +74,10 @@ namespace controller {
: Endpoint(id) {
}
virtual float value() override { return _currentValue; }
virtual float peek() const override { return _currentValue; }
virtual void apply(float value, const Pointer& source) override { _currentValue = value; }
virtual Pose pose() override { return _currentPose; }
virtual Pose peekPose() const override { return _currentPose; }
virtual void apply(const Pose& value, const Pointer& source) override {
_currentPose = value;
}

View file

@ -26,6 +26,7 @@ namespace controller {
Filter::List filters;
QString json;
bool debug { false };
bool peek { false };
using Pointer = std::shared_ptr<Route>;
using List = std::list<Pointer>;

View file

@ -52,6 +52,11 @@ QObject* RouteBuilderProxy::debug(bool enable) {
return this;
}
QObject* RouteBuilderProxy::peek(bool enable) {
_route->peek = enable;
return this;
}
QObject* RouteBuilderProxy::when(const QScriptValue& expression) {
_route->conditional = _parent.conditionalFor(expression);
return this;

View file

@ -38,6 +38,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE void to(const QScriptValue& destination);
Q_INVOKABLE QObject* debug(bool enable = true);
Q_INVOKABLE QObject* peek(bool enable = true);
Q_INVOKABLE QObject* when(const QScriptValue& expression);
Q_INVOKABLE QObject* clamp(float min, float max);
Q_INVOKABLE QObject* hysteresis(float min, float max);
@ -48,7 +49,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* constrainToInteger();
Q_INVOKABLE QObject* constrainToPositiveInteger();
private:
private:
void to(const Endpoint::Pointer& destination);
void conditional(const Conditional::Pointer& conditional);
void addFilter(Filter::Pointer filter);

View file

@ -18,7 +18,7 @@ namespace controller {
class EndpointConditional : public Conditional {
public:
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0f; }
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
private:
Endpoint::Pointer _endpoint;
};

View file

@ -23,10 +23,10 @@ class ActionEndpoint : public Endpoint {
public:
ActionEndpoint(const Input& id = Input::INVALID_INPUT) : Endpoint(id) { }
virtual float value() override { return _currentValue; }
virtual float peek() const { return _currentValue; }
virtual void apply(float newValue, const Pointer& source) override;
virtual Pose pose() override { return _currentPose; }
virtual Pose peekPose() const { return _currentPose; }
virtual void apply(const Pose& value, const Pointer& source) override;
virtual void reset() override;

View file

@ -27,13 +27,19 @@ AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPU
}
}
float AnyEndpoint::peek() const {
float result = 0;
for (auto& child : _children) {
result = std::max(result, child->peek());
}
return result;
}
// Fetching the value must trigger any necessary side effects of value() on ALL the children.
float AnyEndpoint::value() {
float result = 0;
for (auto& child : _children) {
float childResult = child->value();
if (childResult != 0.0f) {
result = childResult;
}
result = std::max(result, child->value());
}
return result;
}

View file

@ -19,6 +19,7 @@ class AnyEndpoint : public Endpoint {
public:
using Endpoint::apply;
AnyEndpoint(Endpoint::List children);
virtual float peek() const override;
virtual float value() override;
virtual void apply(float newValue, const Endpoint::Pointer& source) override;
virtual bool writeable() const override;

View file

@ -21,9 +21,7 @@ public:
using Pointer = std::shared_ptr<ArrayEndpoint>;
ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { }
virtual float value() override {
return 0.0;
}
virtual float peek() const override { return 0.0f; }
virtual void apply(float value, const Endpoint::Pointer& source) override {
for (auto& child : _children) {

View file

@ -24,6 +24,12 @@ bool CompositeEndpoint::readable() const {
return first->readable() && second->readable();
}
float CompositeEndpoint::peek() const {
float result = first->peek() * -1.0f + second->peek();
return result;
}
// Fetching via value() must trigger any side effects of value() on the children
float CompositeEndpoint::value() {
float result = first->value() * -1.0f + second->value();
return result;

View file

@ -18,6 +18,7 @@ namespace controller {
using Endpoint::apply;
CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second);
virtual float peek() const override;
virtual float value() override;
virtual void apply(float newValue, const Pointer& source) override;
virtual bool readable() const override;

View file

@ -13,10 +13,10 @@
#include "../../UserInputMapper.h"
using namespace controller;
float InputEndpoint::value(){
_read = true;
float InputEndpoint::peek() const {
if (isPose()) {
return pose().valid ? 1.0f : 0.0f;
return peekPose().valid ? 1.0f : 0.0f;
}
auto userInputMapper = DependencyManager::get<UserInputMapper>();
auto deviceProxy = userInputMapper->getDevice(_input);
@ -26,8 +26,12 @@ float InputEndpoint::value(){
return deviceProxy->getValue(_input);
}
Pose InputEndpoint::pose() {
float InputEndpoint::value(){
_read = true;
return peek();
}
Pose InputEndpoint::peekPose() const {
if (!isPose()) {
return Pose();
}
@ -39,3 +43,8 @@ Pose InputEndpoint::pose() {
return deviceProxy->getPose(_input.channel);
}
Pose InputEndpoint::pose() {
_read = true;
return peekPose();
}

View file

@ -20,9 +20,11 @@ public:
: Endpoint(id) {
}
virtual float peek() const override;
virtual float value() override;
// FIXME need support for writing back to vibration / force feedback effects
virtual void apply(float newValue, const Pointer& source) override {}
virtual Pose peekPose() const override;
virtual Pose pose() override;
virtual void apply(const Pose& value, const Pointer& source) override { }

View file

@ -24,9 +24,8 @@ public:
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
}
virtual float value() {
float result = (float)_callable.call().toNumber();
return result;
virtual float peek() const {
return (float)const_cast<JSEndpoint*>(this)->_callable.call().toNumber();
}
virtual void apply(float newValue, const Pointer& source) {

View file

@ -12,8 +12,8 @@
using namespace controller;
float ScriptEndpoint::value() {
updateValue();
float ScriptEndpoint::peek() const {
const_cast<ScriptEndpoint*>(this)->updateValue();
return _lastValueRead;
}

View file

@ -24,8 +24,8 @@ public:
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
}
virtual float value();
virtual void apply(float newValue, const Pointer& source);
virtual float peek() const override;
virtual void apply(float newValue, const Pointer& source) override;
protected:
Q_INVOKABLE void updateValue();