mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
Merge pull request #7605 from jherico/route_log_errors
Fixing logging errors on initial load of controller routes
This commit is contained in:
commit
5287c174b4
9 changed files with 106 additions and 53 deletions
|
@ -2,9 +2,6 @@
|
|||
"name": "Standard to Action",
|
||||
"when": "Application.NavigationFocused",
|
||||
"channels": [
|
||||
{ "disabled_from": { "makeAxis" : [ "Standard.DD", "Standard.DU" ] }, "to": "Actions.UiNavVertical" },
|
||||
{ "disabled_from": { "makeAxis" : [ "Standard.DL", "Standard.DR" ] }, "to": "Actions.UiNavLateral" },
|
||||
{ "disabled_from": { "makeAxis" : [ "Standard.LB", "Standard.RB" ] }, "to": "Actions.UiNavGroup" },
|
||||
{ "from": "Standard.DU", "to": "Actions.UiNavVertical" },
|
||||
{ "from": "Standard.DD", "to": "Actions.UiNavVertical", "filters": "invert" },
|
||||
{ "from": "Standard.DL", "to": "Actions.UiNavLateral", "filters": "invert" },
|
||||
|
|
|
@ -402,6 +402,11 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt
|
|||
}
|
||||
}
|
||||
|
||||
static const QString STATE_IN_HMD = "InHMD";
|
||||
static const QString STATE_SNAP_TURN = "SnapTurn";
|
||||
static const QString STATE_GROUNDED = "Grounded";
|
||||
static const QString STATE_NAV_FOCUSED = "NavigationFocused";
|
||||
|
||||
bool setupEssentials(int& argc, char** argv) {
|
||||
unsigned int listenPort = 0; // bind to an ephemeral port by default
|
||||
const char** constArgv = const_cast<const char**>(argv);
|
||||
|
@ -471,6 +476,7 @@ bool setupEssentials(int& argc, char** argv) {
|
|||
DependencyManager::set<InterfaceActionFactory>();
|
||||
DependencyManager::set<AudioInjectorManager>();
|
||||
DependencyManager::set<MessagesClient>();
|
||||
controller::StateController::setStateVariables({ { STATE_IN_HMD, STATE_SNAP_TURN, STATE_GROUNDED, STATE_NAV_FOCUSED } });
|
||||
DependencyManager::set<UserInputMapper>();
|
||||
DependencyManager::set<controller::ScriptingInterface, ControllerScriptingInterface>();
|
||||
DependencyManager::set<InterfaceParentFinder>();
|
||||
|
@ -925,6 +931,11 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
|
||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
||||
} else if (action == controller::toInt(controller::Action::UI_NAV_SELECT)) {
|
||||
if (!offscreenUi->navigationFocused()) {
|
||||
auto reticlePosition = getApplicationCompositor().getReticlePosition();
|
||||
offscreenUi->toggleMenu(_glWidget->mapFromGlobal(QPoint(reticlePosition.x, reticlePosition.y)));
|
||||
}
|
||||
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
|
||||
auto oldPos = getApplicationCompositor().getReticlePosition();
|
||||
getApplicationCompositor().setReticlePosition({ oldPos.x + state, oldPos.y });
|
||||
|
@ -937,28 +948,23 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
}
|
||||
});
|
||||
|
||||
// A new controllerInput device used to reflect current values from the application state
|
||||
_applicationStateDevice = std::make_shared<controller::StateController>();
|
||||
_applicationStateDevice = userInputMapper->getStateDevice();
|
||||
|
||||
_applicationStateDevice->addInputVariant(QString("InHMD"), controller::StateController::ReadLambda([]() -> float {
|
||||
return (float)qApp->isHMDMode();
|
||||
}));
|
||||
_applicationStateDevice->addInputVariant(QString("SnapTurn"), controller::StateController::ReadLambda([]() -> float {
|
||||
return (float)qApp->getMyAvatar()->getSnapTurn();
|
||||
}));
|
||||
_applicationStateDevice->addInputVariant(QString("Grounded"), controller::StateController::ReadLambda([]() -> float {
|
||||
return (float)qApp->getMyAvatar()->getCharacterController()->onGround();
|
||||
}));
|
||||
_applicationStateDevice->addInputVariant(QString("NavigationFocused"), controller::StateController::ReadLambda([]() -> float {
|
||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||
return offscreenUi->navigationFocused() ? 1.0 : 0.0;
|
||||
}));
|
||||
|
||||
userInputMapper->registerDevice(_applicationStateDevice);
|
||||
_applicationStateDevice->setInputVariant(STATE_IN_HMD, []() -> float {
|
||||
return qApp->isHMDMode() ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_SNAP_TURN, []() -> float {
|
||||
return qApp->getMyAvatar()->getSnapTurn() ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_GROUNDED, []() -> float {
|
||||
return qApp->getMyAvatar()->getCharacterController()->onGround() ? 1 : 0;
|
||||
});
|
||||
_applicationStateDevice->setInputVariant(STATE_NAV_FOCUSED, []() -> float {
|
||||
return DependencyManager::get<OffscreenUi>()->navigationFocused() ? 1 : 0;
|
||||
});
|
||||
|
||||
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
|
||||
userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
|
||||
userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID());
|
||||
|
||||
// force the model the look at the correct directory (weird order of operations issue)
|
||||
scriptEngines->setScriptsLocation(scriptEngines->getScriptsLocation());
|
||||
|
|
|
@ -33,8 +33,10 @@ static QVariantMap createDeviceMap(const controller::InputDevice::Pointer device
|
|||
for (const auto& inputMapping : userInputMapper->getAvailableInputs(device->getDeviceID())) {
|
||||
const auto& input = inputMapping.first;
|
||||
const auto inputName = QString(inputMapping.second).remove(SANITIZE_NAME_EXPRESSION);
|
||||
#ifdef DEBUG
|
||||
qCDebug(controllers) << "\tInput " << input.getChannel() << (int)input.getType()
|
||||
<< QString::number(input.getID(), 16) << ": " << inputName;
|
||||
#endif
|
||||
deviceMap.insert(inputName, input.getID());
|
||||
}
|
||||
return deviceMap;
|
||||
|
|
|
@ -19,32 +19,39 @@
|
|||
|
||||
namespace controller {
|
||||
|
||||
static QStringList stateVariables;
|
||||
|
||||
void StateController::setStateVariables(const QStringList& newStateVariables) {
|
||||
stateVariables = newStateVariables;
|
||||
}
|
||||
|
||||
StateController::StateController() : InputDevice("Application") {
|
||||
_deviceID = UserInputMapper::STATE_DEVICE;
|
||||
for (const auto& variable : stateVariables) {
|
||||
_namedReadLambdas[variable] = []()->float{ return 0; };
|
||||
}
|
||||
}
|
||||
|
||||
StateController::~StateController() {
|
||||
}
|
||||
|
||||
void StateController::update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) {}
|
||||
|
||||
void StateController::focusOutEvent() {}
|
||||
|
||||
void StateController::addInputVariant(QString name, ReadLambda lambda) {
|
||||
_namedReadLambdas.push_back(NamedReadLambda(name, lambda));
|
||||
void StateController::setInputVariant(const QString& name, ReadLambda lambda) {
|
||||
// All state variables must be predeclared;
|
||||
Q_ASSERT(_namedReadLambdas.contains(name));
|
||||
_namedReadLambdas[name] = lambda;
|
||||
}
|
||||
|
||||
Input::NamedVector StateController::getAvailableInputs() const {
|
||||
Input::NamedVector availableInputs;
|
||||
int i = 0;
|
||||
for (auto& pair : _namedReadLambdas) {
|
||||
availableInputs.push_back(Input::NamedPair(Input(_deviceID, i, ChannelType::BUTTON), pair.first));
|
||||
for (const auto& name : stateVariables) {
|
||||
availableInputs.push_back(Input::NamedPair(Input(_deviceID, i, ChannelType::BUTTON), name));
|
||||
i++;
|
||||
}
|
||||
return availableInputs;
|
||||
}
|
||||
|
||||
EndpointPointer StateController::createEndpoint(const Input& input) const {
|
||||
return std::make_shared<LambdaEndpoint>(_namedReadLambdas[input.getChannel()].second);
|
||||
auto name = stateVariables[input.getChannel()];
|
||||
ReadLambda& readLambda = const_cast<QHash<QString, ReadLambda>&>(_namedReadLambdas)[name];
|
||||
return std::make_shared<LambdaRefEndpoint>(readLambda);
|
||||
}
|
||||
|
||||
}
|
|
@ -24,26 +24,28 @@ class StateController : public QObject, public InputDevice {
|
|||
Q_PROPERTY(QString name READ getName)
|
||||
|
||||
public:
|
||||
using Pointer = std::shared_ptr<StateController>;
|
||||
using ReadLambda = std::function<float()>;
|
||||
using NamedReadLambda = QPair<QString, ReadLambda>;
|
||||
|
||||
static void setStateVariables(const QStringList& stateVariables);
|
||||
|
||||
StateController();
|
||||
|
||||
const QString& getName() const { return _name; }
|
||||
|
||||
// Device functions
|
||||
virtual Input::NamedVector getAvailableInputs() const override;
|
||||
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
StateController();
|
||||
virtual ~StateController();
|
||||
void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override {}
|
||||
void focusOutEvent() override {}
|
||||
|
||||
using ReadLambda = std::function<float()>;
|
||||
using NamedReadLambda = QPair<QString, ReadLambda>;
|
||||
|
||||
void addInputVariant(QString name, ReadLambda lambda);
|
||||
|
||||
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
||||
void setInputVariant(const QString& name, ReadLambda lambda);
|
||||
|
||||
EndpointPointer createEndpoint(const Input& input) const override;
|
||||
|
||||
protected:
|
||||
QVector<NamedReadLambda> _namedReadLambdas;
|
||||
QHash<QString, ReadLambda> _namedReadLambdas;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -44,13 +44,15 @@
|
|||
|
||||
|
||||
namespace controller {
|
||||
const uint16_t UserInputMapper::ACTIONS_DEVICE = Input::INVALID_DEVICE - 0xFF;
|
||||
const uint16_t UserInputMapper::STANDARD_DEVICE = 0;
|
||||
const uint16_t UserInputMapper::ACTIONS_DEVICE = Input::INVALID_DEVICE - 0x00FF;
|
||||
const uint16_t UserInputMapper::STATE_DEVICE = Input::INVALID_DEVICE - 0x0100;
|
||||
}
|
||||
|
||||
// Default contruct allocate the poutput size with the current hardcoded action channels
|
||||
controller::UserInputMapper::UserInputMapper() {
|
||||
registerDevice(std::make_shared<ActionsDevice>());
|
||||
registerDevice(_stateDevice = std::make_shared<StateController>());
|
||||
registerDevice(std::make_shared<StandardController>());
|
||||
}
|
||||
|
||||
|
@ -138,7 +140,6 @@ void UserInputMapper::loadDefaultMapping(uint16 deviceID) {
|
|||
return;
|
||||
}
|
||||
|
||||
|
||||
auto mapping = loadMappings(proxyEntry->second->getDefaultMappingConfigs());
|
||||
if (mapping) {
|
||||
auto prevMapping = _mappingsByDevice[deviceID];
|
||||
|
@ -235,6 +236,10 @@ void fixBisectedAxis(float& full, float& negative, float& positive) {
|
|||
|
||||
void UserInputMapper::update(float deltaTime) {
|
||||
Locker locker(_lock);
|
||||
|
||||
static uint64_t updateCount = 0;
|
||||
++updateCount;
|
||||
|
||||
// Reset the axis state for next loop
|
||||
for (auto& channel : _actionStates) {
|
||||
channel = 0.0f;
|
||||
|
@ -694,11 +699,17 @@ Pose UserInputMapper::getPose(const Input& input) const {
|
|||
return getPose(endpoint);
|
||||
}
|
||||
|
||||
Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile) {
|
||||
Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile, bool enable) {
|
||||
Locker locker(_lock);
|
||||
if (jsonFile.isEmpty()) {
|
||||
return Mapping::Pointer();
|
||||
}
|
||||
// Each mapping only needs to be loaded once
|
||||
static QSet<QString> loaded;
|
||||
if (loaded.contains(jsonFile)) {
|
||||
return Mapping::Pointer();
|
||||
}
|
||||
loaded.insert(jsonFile);
|
||||
QString json;
|
||||
{
|
||||
QFile file(jsonFile);
|
||||
|
@ -707,7 +718,11 @@ Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile) {
|
|||
}
|
||||
file.close();
|
||||
}
|
||||
return parseMapping(json);
|
||||
auto result = parseMapping(json);
|
||||
if (enable) {
|
||||
enableMapping(result->name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
MappingPointer UserInputMapper::loadMappings(const QStringList& jsonFiles) {
|
||||
|
@ -961,7 +976,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();
|
||||
result->peek = obj[JSON_CHANNEL_PEEK].toBool();
|
||||
if (!result->source) {
|
||||
qWarning() << "Invalid route source " << obj[JSON_CHANNEL_FROM];
|
||||
return Route::Pointer();
|
||||
|
@ -1033,7 +1048,7 @@ Mapping::Pointer UserInputMapper::parseMapping(const QJsonValue& json) {
|
|||
Route::Pointer route = parseRoute(channelIt);
|
||||
|
||||
if (!route) {
|
||||
qWarning() << "Couldn't parse route:" << mapping->name << channelIt;
|
||||
qWarning() << "Couldn't parse route:" << mapping->name << QString(QJsonDocument(channelIt.toObject()).toJson());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "DeviceProxy.h"
|
||||
#include "StandardControls.h"
|
||||
#include "Actions.h"
|
||||
#include "StateController.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
|
@ -55,8 +56,9 @@ namespace controller {
|
|||
using uint16 = uint16_t;
|
||||
using uint32 = uint32_t;
|
||||
|
||||
static const uint16_t ACTIONS_DEVICE;
|
||||
static const uint16_t STANDARD_DEVICE;
|
||||
static const uint16_t ACTIONS_DEVICE;
|
||||
static const uint16_t STATE_DEVICE;
|
||||
|
||||
UserInputMapper();
|
||||
virtual ~UserInputMapper();
|
||||
|
@ -100,10 +102,11 @@ namespace controller {
|
|||
const DevicesMap& getDevices() { return _registeredDevices; }
|
||||
uint16 getStandardDeviceID() const { return STANDARD_DEVICE; }
|
||||
InputDevice::Pointer getStandardDevice() { return _registeredDevices[getStandardDeviceID()]; }
|
||||
StateController::Pointer getStateDevice() { return _stateDevice; }
|
||||
|
||||
MappingPointer newMapping(const QString& mappingName);
|
||||
MappingPointer parseMapping(const QString& json);
|
||||
MappingPointer loadMapping(const QString& jsonFile);
|
||||
MappingPointer loadMapping(const QString& jsonFile, bool enable = false);
|
||||
MappingPointer loadMappings(const QStringList& jsonFiles);
|
||||
|
||||
void loadDefaultMapping(uint16 deviceID);
|
||||
|
@ -120,6 +123,7 @@ namespace controller {
|
|||
// GetFreeDeviceID should be called before registering a device to use an ID not used by a different device.
|
||||
uint16 getFreeDeviceID() { return _nextFreeDeviceID++; }
|
||||
DevicesMap _registeredDevices;
|
||||
StateController::Pointer _stateDevice;
|
||||
uint16 _nextFreeDeviceID = STANDARD_DEVICE + 1;
|
||||
|
||||
std::vector<float> _actionStates = std::vector<float>(toInt(Action::NUM_ACTIONS), 0.0f);
|
||||
|
|
|
@ -12,5 +12,8 @@
|
|||
// warning LNK4221: This object file does not define any previously undefined public symbols,
|
||||
// so it will not be used by any link operation that consumes this library
|
||||
//
|
||||
//#include "Endpoint.h"
|
||||
#include "Endpoint.h"
|
||||
|
||||
namespace controller {
|
||||
Endpoint::WriteLambda DEFAULT_WRITE_LAMBDA = [](float) {};
|
||||
}
|
||||
|
|
|
@ -67,6 +67,23 @@ namespace controller {
|
|||
WriteLambda _writeLambda;
|
||||
};
|
||||
|
||||
extern Endpoint::WriteLambda DEFAULT_WRITE_LAMBDA;
|
||||
|
||||
class LambdaRefEndpoint : public Endpoint {
|
||||
public:
|
||||
using Endpoint::apply;
|
||||
LambdaRefEndpoint(const ReadLambda& readLambda, const WriteLambda& writeLambda = DEFAULT_WRITE_LAMBDA)
|
||||
: Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) {
|
||||
}
|
||||
|
||||
virtual float peek() const override { return _readLambda(); }
|
||||
virtual void apply(float value, const Pointer& source) override { _writeLambda(value); }
|
||||
|
||||
private:
|
||||
const ReadLambda& _readLambda;
|
||||
const WriteLambda& _writeLambda;
|
||||
};
|
||||
|
||||
|
||||
class VirtualEndpoint : public Endpoint {
|
||||
public:
|
||||
|
|
Loading…
Reference in a new issue