Merge branch 'qml-keyboard' of github.com:sethalves/hifi into qml-keyboard

This commit is contained in:
Seth Alves 2016-09-09 10:16:09 -07:00
commit 25786f273d
29 changed files with 216 additions and 78 deletions

View file

@ -368,11 +368,11 @@ void DomainServer::setupNodeListAndAssignments() {
const QString CUSTOM_LOCAL_PORT_OPTION = "metaverse.local_port"; const QString CUSTOM_LOCAL_PORT_OPTION = "metaverse.local_port";
QVariant localPortValue = _settingsManager.valueOrDefaultValueForKeyPath(CUSTOM_LOCAL_PORT_OPTION); QVariant localPortValue = _settingsManager.valueOrDefaultValueForKeyPath(CUSTOM_LOCAL_PORT_OPTION);
unsigned short domainServerPort = (unsigned short) localPortValue.toUInt(); int domainServerPort = localPortValue.toInt();
QVariantMap& settingsMap = _settingsManager.getSettingsMap(); QVariantMap& settingsMap = _settingsManager.getSettingsMap();
unsigned short domainServerDTLSPort = 0; int domainServerDTLSPort = INVALID_PORT;
if (_isUsingDTLS) { if (_isUsingDTLS) {
domainServerDTLSPort = DEFAULT_DOMAIN_SERVER_DTLS_PORT; domainServerDTLSPort = DEFAULT_DOMAIN_SERVER_DTLS_PORT;

View file

@ -18,11 +18,13 @@ var EventBridge;
this._callbacks = []; this._callbacks = [];
this._messages = []; this._messages = [];
this.scriptEventReceived = { this.scriptEventReceived = {
connect: function (cb) { self._callbacks.push(cb); } connect: function (callback) {
self._callbacks.push(callback);
}
}; };
this.emitWebEvent = function (message) { this.emitWebEvent = function (message) {
self._messages.push(message); self._messages.push(message);
} };
}; };
EventBridge = new TempEventBridge(); EventBridge = new TempEventBridge();
@ -31,11 +33,11 @@ var EventBridge;
// replace the TempEventBridge with the real one. // replace the TempEventBridge with the real one.
var tempEventBridge = EventBridge; var tempEventBridge = EventBridge;
EventBridge = channel.objects.eventBridgeWrapper.eventBridge; EventBridge = channel.objects.eventBridgeWrapper.eventBridge;
tempEventBridge._callbacks.forEach(function (cb) { tempEventBridge._callbacks.forEach(function (callback) {
EventBridge.scriptEventReceived.connect(cb); EventBridge.scriptEventReceived.connect(callback);
}); });
tempEventBridge._messages.forEach(function (msg) { tempEventBridge._messages.forEach(function (message) {
EventBridge.emitWebEvent(msg); EventBridge.emitWebEvent(message);
}); });
}); });
})(); })();

View file

@ -13,7 +13,18 @@
var numWarnings = 0; var numWarnings = 0;
function shouldRaiseKeyboard() { function shouldRaiseKeyboard() {
return document.activeElement.nodeName == "INPUT" || document.activeElement.nodeName == "TEXTAREA"; if (document.activeElement.nodeName == "INPUT" || document.activeElement.nodeName == "TEXTAREA") {
return true;
} else {
// check for contenteditable attribute
for (var i = 0; i < document.activeElement.attributes.length; i++) {
if (document.activeElement.attributes[i].name === "contenteditable" &&
document.activeElement.attributes[i].value === "true") {
return true;
}
}
return false;
}
}; };
setInterval(function () { setInterval(function () {

View file

@ -1,6 +1,6 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.2 import QtQuick.Controls 1.2
import QtWebEngine 1.1 import QtWebEngine 1.2
import "controls-uit" import "controls-uit"
import "styles" as HifiStyles import "styles" as HifiStyles
@ -223,6 +223,9 @@ ScrollingWindow {
var newWindow = component.createObject(desktop); var newWindow = component.createObject(desktop);
request.openIn(newWindow.webView) request.openIn(newWindow.webView)
} }
onWindowCloseRequested: {
root.destroy();
}
Component.onCompleted: { Component.onCompleted: {
desktop.initWebviewProfileHandlers(webview.profile) desktop.initWebviewProfileHandlers(webview.profile)

View file

@ -15,7 +15,7 @@ WebEngineView {
id: root id: root
property var newUrl; property var newUrl;
profile.httpUserAgent: "Mozilla/5.0 Chrome/38.0 (HighFidelityInterface)" profile: desktop.browserProfile
Component.onCompleted: { Component.onCompleted: {
console.log("Connecting JS messaging to Hifi Logging") console.log("Connecting JS messaging to Hifi Logging")
@ -60,9 +60,4 @@ WebEngineView {
} }
} }
} }
// This breaks the webchannel used for passing messages. Fixed in Qt 5.6
// See https://bugreports.qt.io/browse/QTBUG-49521
//profile: desktop.browserProfile
} }

View file

@ -10,11 +10,11 @@ Item {
property alias mouseArea: mouseArea1 property alias mouseArea: mouseArea1
function resetToggledMode(mode) { function resetToggledMode(mode) {
toggled = mode toggled = mode;
if (toggled) { if (toggled) {
state = "mouseDepressed" state = "mouseDepressed";
} else { } else {
state = "" state = "";
} }
} }
@ -26,52 +26,52 @@ Item {
onCanceled: { onCanceled: {
if (toggled) { if (toggled) {
keyItem.state = "mouseDepressed" keyItem.state = "mouseDepressed";
} else { } else {
keyItem.state = "" keyItem.state = "";
} }
} }
onClicked: { onClicked: {
mouse.accepted = true mouse.accepted = true;
webEntity.synthesizeKeyPress(glyph) webEntity.synthesizeKeyPress(glyph);
if (toggle) { if (toggle) {
toggled = !toggled toggled = !toggled;
} }
} }
onDoubleClicked: { onDoubleClicked: {
mouse.accepted = true mouse.accepted = true;
} }
onEntered: { onEntered: {
keyItem.state = "mouseOver" keyItem.state = "mouseOver";
} }
onExited: { onExited: {
if (toggled) { if (toggled) {
keyItem.state = "mouseDepressed" keyItem.state = "mouseDepressed";
} else { } else {
keyItem.state = "" keyItem.state = "";
} }
} }
onPressed: { onPressed: {
keyItem.state = "mouseClicked" keyItem.state = "mouseClicked";
mouse.accepted = true mouse.accepted = true;
} }
onReleased: { onReleased: {
if (containsMouse) { if (containsMouse) {
keyItem.state = "mouseOver" keyItem.state = "mouseOver";
} else { } else {
if (toggled) { if (toggled) {
keyItem.state = "mouseDepressed" keyItem.state = "mouseDepressed";
} else { } else {
keyItem.state = "" keyItem.state = "";
} }
} }
mouse.accepted = true mouse.accepted = true;
} }
} }

View file

@ -7,8 +7,8 @@ Item {
property bool shiftMode: false property bool shiftMode: false
function resetShiftMode(mode) { function resetShiftMode(mode) {
shiftMode = mode shiftMode = mode;
shiftKey.resetToggledMode(mode) shiftKey.resetToggledMode(mode);
} }
function toUpper(str) { function toUpper(str) {
@ -59,7 +59,7 @@ Item {
function alphaKeyClickedHandler(mouseArea) { function alphaKeyClickedHandler(mouseArea) {
// reset shift mode to false after first keypress // reset shift mode to false after first keypress
if (shiftMode) { if (shiftMode) {
resetShiftMode(false) resetShiftMode(false);
} }
} }
@ -333,7 +333,7 @@ Item {
width: 89 width: 89
glyph: "&123" glyph: "&123"
mouseArea.onClicked: { mouseArea.onClicked: {
keyboardBase.parent.punctuationMode = true keyboardBase.parent.punctuationMode = true;
} }
} }

View file

@ -44,13 +44,13 @@ Item {
webChannel.registeredObjects: [eventBridgeWrapper] webChannel.registeredObjects: [eventBridgeWrapper]
Component.onCompleted: { Component.onCompleted: {
console.log("Connecting JS messaging to Hifi Logging") console.log("Connecting JS messaging to Hifi Logging");
// Ensure the JS from the web-engine makes it to our logging // Ensure the JS from the web-engine makes it to our logging
root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) { root.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message); console.log("Web Entity JS message: " + sourceID + " " + lineNumber + " " + message);
}); });
root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)" root.profile.httpUserAgent = "Mozilla/5.0 Chrome (HighFidelityInterface)";
} }
// FIXME hack to get the URL with the auth token included. Remove when we move to Qt 5.6 // FIXME hack to get the URL with the auth token included. Remove when we move to Qt 5.6

View file

@ -46,8 +46,20 @@ OriginalDesktop.Desktop {
} }
} }
property var toolbars: ({})
Component { id: toolbarBuilder; Toolbar { } } Component { id: toolbarBuilder; Toolbar { } }
// This used to create sysToolbar dynamically with a call to getToolbar() within onCompleted.
// Beginning with QT 5.6, this stopped working, as anything added to toolbars too early got
// wiped during startup.
Toolbar {
id: sysToolbar;
objectName: "com.highfidelity.interface.toolbar.system";
// Magic: sysToolbar.x and y come from settings, and are bound before the properties specified here are applied.
x: sysToolbar.x;
y: sysToolbar.y;
}
property var toolbars: (function (map) { // answer dictionary preloaded with sysToolbar
map[sysToolbar.objectName] = sysToolbar;
return map; })({});
Component.onCompleted: { Component.onCompleted: {
WebEngine.settings.javascriptCanOpenWindows = true; WebEngine.settings.javascriptCanOpenWindows = true;
@ -55,7 +67,6 @@ OriginalDesktop.Desktop {
WebEngine.settings.spatialNavigationEnabled = false; WebEngine.settings.spatialNavigationEnabled = false;
WebEngine.settings.localContentCanAccessRemoteUrls = true; WebEngine.settings.localContentCanAccessRemoteUrls = true;
var sysToolbar = desktop.getToolbar("com.highfidelity.interface.toolbar.system");
var toggleHudButton = sysToolbar.addButton({ var toggleHudButton = sysToolbar.addButton({
objectName: "hudToggle", objectName: "hudToggle",
imageURL: "../../../icons/hud.svg", imageURL: "../../../icons/hud.svg",

View file

@ -0,0 +1,19 @@
import QtQuick 2.5
import Qt.labs.settings 1.0
import "../../dialogs"
PreferencesDialog {
id: root
objectName: "NetworkingPreferencesDialog"
title: "Networking Settings"
showCategories: ["Networking"]
property var settings: Settings {
category: root.objectName
property alias x: root.x
property alias y: root.y
property alias width: root.width
property alias height: root.height
}
}

View file

@ -400,12 +400,10 @@ static const QString STATE_GROUNDED = "Grounded";
static const QString STATE_NAV_FOCUSED = "NavigationFocused"; static const QString STATE_NAV_FOCUSED = "NavigationFocused";
bool setupEssentials(int& argc, char** argv) { 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); const char** constArgv = const_cast<const char**>(argv);
const char* portStr = getCmdOption(argc, constArgv, "--listenPort"); const char* portStr = getCmdOption(argc, constArgv, "--listenPort");
if (portStr) { const int listenPort = portStr ? atoi(portStr) : INVALID_PORT;
listenPort = atoi(portStr);
}
// Set build version // Set build version
QCoreApplication::setApplicationVersion(BuildInfo::VERSION); QCoreApplication::setApplicationVersion(BuildInfo::VERSION);

View file

@ -522,6 +522,11 @@ Menu::Menu() {
// Developer > Network >>> // Developer > Network >>>
MenuWrapper* networkMenu = developerMenu->addMenu("Network"); MenuWrapper* networkMenu = developerMenu->addMenu("Network");
action = addActionToQMenuAndActionHash(networkMenu, MenuOption::Networking);
connect(action, &QAction::triggered, [] {
DependencyManager::get<OffscreenUi>()->toggle(QUrl("hifi/dialogs/NetworkingPreferencesDialog.qml"),
"NetworkingPreferencesDialog");
});
addActionToQMenuAndActionHash(networkMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches())); addActionToQMenuAndActionHash(networkMenu, MenuOption::ReloadContent, 0, qApp, SLOT(reloadResourceCaches()));
addCheckableActionToQMenuAndActionHash(networkMenu, addCheckableActionToQMenuAndActionHash(networkMenu,
MenuOption::DisableActivityLogger, MenuOption::DisableActivityLogger,

View file

@ -129,6 +129,7 @@ namespace MenuOption {
const QString MuteEnvironment = "Mute Environment"; const QString MuteEnvironment = "Mute Environment";
const QString MuteFaceTracking = "Mute Face Tracking"; const QString MuteFaceTracking = "Mute Face Tracking";
const QString NamesAboveHeads = "Names Above Heads"; const QString NamesAboveHeads = "Names Above Heads";
const QString Networking = "Networking...";
const QString NoFaceTracking = "None"; const QString NoFaceTracking = "None";
const QString OctreeStats = "Entity Statistics"; const QString OctreeStats = "Entity Statistics";
const QString OnePointCalibration = "1 Point Calibration"; const QString OnePointCalibration = "1 Point Calibration";

View file

@ -332,4 +332,19 @@ void setupPreferences() {
preferences->addPreference(preference); preferences->addPreference(preference);
} }
} }
{
static const QString RENDER("Networking");
auto nodelist = DependencyManager::get<NodeList>();
{
static const int MIN_PORT_NUMBER { 0 };
static const int MAX_PORT_NUMBER { 65535 };
auto getter = [nodelist] { return static_cast<int>(nodelist->getSocketLocalPort()); };
auto setter = [nodelist](int preset) { nodelist->setSocketLocalPort(static_cast<quint16>(preset)); };
auto preference = new IntSpinnerPreference(RENDER, "Listening Port", getter, setter);
preference->setMin(MIN_PORT_NUMBER);
preference->setMax(MAX_PORT_NUMBER);
preferences->addPreference(preference);
}
}
} }

View file

@ -512,7 +512,7 @@ void OpenGLDisplayPlugin::compositeOverlay() {
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
} else { } else {
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize()));
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
} }
}); });
@ -536,7 +536,7 @@ void OpenGLDisplayPlugin::compositePointer() {
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
}); });
} else { } else {
batch.setViewportTransform(ivec4(uvec2(0), _currentFrame->framebuffer->getSize())); batch.setViewportTransform(ivec4(uvec2(0), _compositeFramebuffer->getSize()));
batch.draw(gpu::TRIANGLE_STRIP, 4); batch.draw(gpu::TRIANGLE_STRIP, 4);
} }
}); });
@ -726,7 +726,7 @@ bool OpenGLDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
} }
ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye) const { ivec4 OpenGLDisplayPlugin::eyeViewport(Eye eye) const {
uvec2 vpSize = _currentFrame->framebuffer->getSize(); uvec2 vpSize = _compositeFramebuffer->getSize();
vpSize.x /= 2; vpSize.x /= 2;
uvec2 vpPos; uvec2 vpPos;
if (eye == Eye::Right) { if (eye == Eye::Right) {

View file

@ -39,8 +39,8 @@ static int MAX_WINDOW_SIZE = 4096;
static float OPAQUE_ALPHA_THRESHOLD = 0.99f; static float OPAQUE_ALPHA_THRESHOLD = 0.99f;
void WebEntityAPIHelper::synthesizeKeyPress(QString key) { void WebEntityAPIHelper::synthesizeKeyPress(QString key) {
if (_ptr) { if (_renderableWebEntityItem) {
_ptr->synthesizeKeyPress(key); _renderableWebEntityItem->synthesizeKeyPress(key);
} }
} }
@ -57,10 +57,10 @@ void WebEntityAPIHelper::emitWebEvent(const QVariant& message) {
QMetaObject::invokeMethod(this, "emitWebEvent", Qt::QueuedConnection, Q_ARG(QVariant, message)); QMetaObject::invokeMethod(this, "emitWebEvent", Qt::QueuedConnection, Q_ARG(QVariant, message));
} else { } else {
// special case to handle raising and lowering the virtual keyboard // special case to handle raising and lowering the virtual keyboard
if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD" && _ptr) { if (message.type() == QVariant::String && message.toString() == "_RAISE_KEYBOARD" && _renderableWebEntityItem) {
_ptr->setKeyboardRaised(true); _renderableWebEntityItem->setKeyboardRaised(true);
} else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD" && _ptr) { } else if (message.type() == QVariant::String && message.toString() == "_LOWER_KEYBOARD" && _renderableWebEntityItem) {
_ptr->setKeyboardRaised(false); _renderableWebEntityItem->setKeyboardRaised(false);
} else { } else {
emit webEventReceived(message); emit webEventReceived(message);
} }
@ -83,7 +83,7 @@ RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemI
_touchDevice.setMaximumTouchPoints(4); _touchDevice.setMaximumTouchPoints(4);
_webEntityAPIHelper = new WebEntityAPIHelper; _webEntityAPIHelper = new WebEntityAPIHelper;
_webEntityAPIHelper->setPtr(this); _webEntityAPIHelper->setRenderableWebEntityItem(this);
_webEntityAPIHelper->moveToThread(qApp->thread()); _webEntityAPIHelper->moveToThread(qApp->thread());
// forward web events to EntityScriptingInterface // forward web events to EntityScriptingInterface
@ -94,7 +94,7 @@ RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemI
} }
RenderableWebEntityItem::~RenderableWebEntityItem() { RenderableWebEntityItem::~RenderableWebEntityItem() {
_webEntityAPIHelper->setPtr(nullptr); _webEntityAPIHelper->setRenderableWebEntityItem(nullptr);
_webEntityAPIHelper->deleteLater(); _webEntityAPIHelper->deleteLater();
destroyWebSurface(); destroyWebSurface();
qDebug() << "Destroyed web entity " << getID(); qDebug() << "Destroyed web entity " << getID();

View file

@ -27,8 +27,8 @@ class RenderableWebEntityItem;
class WebEntityAPIHelper : public QObject { class WebEntityAPIHelper : public QObject {
Q_OBJECT Q_OBJECT
public: public:
void setPtr(RenderableWebEntityItem* ptr) { void setRenderableWebEntityItem(RenderableWebEntityItem* renderableWebEntityItem) {
_ptr = ptr; _renderableWebEntityItem = renderableWebEntityItem;
} }
Q_INVOKABLE void synthesizeKeyPress(QString key); Q_INVOKABLE void synthesizeKeyPress(QString key);
@ -41,7 +41,7 @@ signals:
void webEventReceived(const QVariant& message); void webEventReceived(const QVariant& message);
protected: protected:
RenderableWebEntityItem* _ptr{ nullptr }; RenderableWebEntityItem* _renderableWebEntityItem{ nullptr };
}; };
class RenderableWebEntityItem : public WebEntityItem { class RenderableWebEntityItem : public WebEntityItem {

View file

@ -18,6 +18,7 @@
#include <QtCore/QDataStream> #include <QtCore/QDataStream>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QJsonDocument> #include <QtCore/QJsonDocument>
#include <QtCore/QThread>
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtNetwork/QHostInfo> #include <QtNetwork/QHostInfo>
@ -25,6 +26,7 @@
#include <LogHandler.h> #include <LogHandler.h>
#include <NumericalConstants.h> #include <NumericalConstants.h>
#include <SettingHandle.h>
#include <SharedUtil.h> #include <SharedUtil.h>
#include <UUID.h> #include <UUID.h>
@ -34,12 +36,14 @@
#include "NetworkLogging.h" #include "NetworkLogging.h"
#include "udt/Packet.h" #include "udt/Packet.h"
static Setting::Handle<quint16> LIMITED_NODELIST_LOCAL_PORT("LimitedNodeList.LocalPort", 0);
const std::set<NodeType_t> SOLO_NODE_TYPES = { const std::set<NodeType_t> SOLO_NODE_TYPES = {
NodeType::AvatarMixer, NodeType::AvatarMixer,
NodeType::AudioMixer NodeType::AudioMixer
}; };
LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short dtlsListenPort) : LimitedNodeList::LimitedNodeList(int socketListenPort, int dtlsListenPort) :
_sessionUUID(), _sessionUUID(),
_nodeHash(), _nodeHash(),
_nodeMutex(QReadWriteLock::Recursive), _nodeMutex(QReadWriteLock::Recursive),
@ -62,11 +66,11 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short
} }
qRegisterMetaType<ConnectionStep>("ConnectionStep"); qRegisterMetaType<ConnectionStep>("ConnectionStep");
auto port = (socketListenPort != INVALID_PORT) ? socketListenPort : LIMITED_NODELIST_LOCAL_PORT.get();
_nodeSocket.bind(QHostAddress::AnyIPv4, socketListenPort); _nodeSocket.bind(QHostAddress::AnyIPv4, port);
qCDebug(networking) << "NodeList socket is listening on" << _nodeSocket.localPort(); qCDebug(networking) << "NodeList socket is listening on" << _nodeSocket.localPort();
if (dtlsListenPort > 0) { if (dtlsListenPort != INVALID_PORT) {
// only create the DTLS socket during constructor if a custom port is passed // only create the DTLS socket during constructor if a custom port is passed
_dtlsSocket = new QUdpSocket(this); _dtlsSocket = new QUdpSocket(this);
@ -157,6 +161,18 @@ void LimitedNodeList::setPermissions(const NodePermissions& newPermissions) {
} }
} }
void LimitedNodeList::setSocketLocalPort(quint16 socketLocalPort) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "setSocketLocalPort", Qt::QueuedConnection,
Q_ARG(quint16, socketLocalPort));
return;
}
if (_nodeSocket.localPort() != socketLocalPort) {
_nodeSocket.rebind(socketLocalPort);
LIMITED_NODELIST_LOCAL_PORT.set(socketLocalPort);
}
}
QUdpSocket& LimitedNodeList::getDTLSSocket() { QUdpSocket& LimitedNodeList::getDTLSSocket() {
if (!_dtlsSocket) { if (!_dtlsSocket) {
// DTLS socket getter called but no DTLS socket exists, create it now // DTLS socket getter called but no DTLS socket exists, create it now
@ -606,6 +622,12 @@ SharedNodePointer LimitedNodeList::addOrUpdateNode(const QUuid& uuid, NodeType_t
}); });
} }
// Signal when a socket changes, so we can start the hole punch over.
auto weakPtr = newNodePointer.toWeakRef(); // We don't want the lambda to hold a strong ref
connect(newNodePointer.data(), &NetworkPeer::socketUpdated, this, [=] {
emit nodeSocketUpdated(weakPtr);
});
return newNodePointer; return newNodePointer;
} }
} }

View file

@ -45,6 +45,8 @@
#include "udt/Socket.h" #include "udt/Socket.h"
#include "UUIDHasher.h" #include "UUIDHasher.h"
const int INVALID_PORT = -1;
const quint64 NODE_SILENCE_THRESHOLD_MSECS = 5 * 1000; const quint64 NODE_SILENCE_THRESHOLD_MSECS = 5 * 1000;
extern const std::set<NodeType_t> SOLO_NODE_TYPES; extern const std::set<NodeType_t> SOLO_NODE_TYPES;
@ -113,6 +115,8 @@ public:
bool getThisNodeCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); } bool getThisNodeCanKick() const { return _permissions.can(NodePermissions::Permission::canKick); }
quint16 getSocketLocalPort() const { return _nodeSocket.localPort(); } quint16 getSocketLocalPort() const { return _nodeSocket.localPort(); }
Q_INVOKABLE void setSocketLocalPort(quint16 socketLocalPort);
QUdpSocket& getDTLSSocket(); QUdpSocket& getDTLSSocket();
PacketReceiver& getPacketReceiver() { return *_packetReceiver; } PacketReceiver& getPacketReceiver() { return *_packetReceiver; }
@ -250,6 +254,7 @@ signals:
void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID); void uuidChanged(const QUuid& ownerUUID, const QUuid& oldUUID);
void nodeAdded(SharedNodePointer); void nodeAdded(SharedNodePointer);
void nodeSocketUpdated(SharedNodePointer);
void nodeKilled(SharedNodePointer); void nodeKilled(SharedNodePointer);
void nodeActivated(SharedNodePointer); void nodeActivated(SharedNodePointer);
@ -267,9 +272,9 @@ protected slots:
void errorTestingLocalSocket(); void errorTestingLocalSocket();
protected: protected:
LimitedNodeList(unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0); LimitedNodeList(int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
LimitedNodeList(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton LimitedNodeList(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
void operator=(LimitedNodeList const&); // Don't implement, needed to avoid copies of singleton void operator=(LimitedNodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode, qint64 sendPacket(std::unique_ptr<NLPacket> packet, const Node& destinationNode,
const HifiSockAddr& overridenSockAddr); const HifiSockAddr& overridenSockAddr);

View file

@ -63,6 +63,7 @@ void NetworkPeer::setPublicSocket(const HifiSockAddr& publicSocket) {
if (!wasOldSocketNull) { if (!wasOldSocketNull) {
qCDebug(networking) << "Public socket change for node" << *this; qCDebug(networking) << "Public socket change for node" << *this;
emit socketUpdated();
} }
} }
} }
@ -82,6 +83,7 @@ void NetworkPeer::setLocalSocket(const HifiSockAddr& localSocket) {
if (!wasOldSocketNull) { if (!wasOldSocketNull) {
qCDebug(networking) << "Local socket change for node" << *this; qCDebug(networking) << "Local socket change for node" << *this;
emit socketUpdated();
} }
} }
} }
@ -101,6 +103,7 @@ void NetworkPeer::setSymmetricSocket(const HifiSockAddr& symmetricSocket) {
if (!wasOldSocketNull) { if (!wasOldSocketNull) {
qCDebug(networking) << "Symmetric socket change for node" << *this; qCDebug(networking) << "Symmetric socket change for node" << *this;
emit socketUpdated();
} }
} }
} }

View file

@ -81,9 +81,12 @@ public:
public slots: public slots:
void startPingTimer(); void startPingTimer();
void stopPingTimer(); void stopPingTimer();
signals: signals:
void pingTimerTimeout(); void pingTimerTimeout();
void socketActivated(const HifiSockAddr& sockAddr); void socketActivated(const HifiSockAddr& sockAddr);
void socketUpdated();
protected: protected:
void setActiveSocket(HifiSockAddr* discoveredSocket); void setActiveSocket(HifiSockAddr* discoveredSocket);

View file

@ -33,7 +33,7 @@
const int KEEPALIVE_PING_INTERVAL_MS = 1000; const int KEEPALIVE_PING_INTERVAL_MS = 1000;
NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned short dtlsListenPort) : NodeList::NodeList(char newOwnerType, int socketListenPort, int dtlsListenPort) :
LimitedNodeList(socketListenPort, dtlsListenPort), LimitedNodeList(socketListenPort, dtlsListenPort),
_ownerType(newOwnerType), _ownerType(newOwnerType),
_nodeTypesOfInterest(), _nodeTypesOfInterest(),
@ -93,6 +93,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
// anytime we get a new node we will want to attempt to punch to it // anytime we get a new node we will want to attempt to punch to it
connect(this, &LimitedNodeList::nodeAdded, this, &NodeList::startNodeHolePunch); connect(this, &LimitedNodeList::nodeAdded, this, &NodeList::startNodeHolePunch);
connect(this, &LimitedNodeList::nodeSocketUpdated, this, &NodeList::startNodeHolePunch);
// anytime we get a new node we may need to re-send our set of ignored node IDs to it // anytime we get a new node we may need to re-send our set of ignored node IDs to it
connect(this, &LimitedNodeList::nodeActivated, this, &NodeList::maybeSendIgnoreSetToNode); connect(this, &LimitedNodeList::nodeActivated, this, &NodeList::maybeSendIgnoreSetToNode);

View file

@ -116,10 +116,10 @@ private slots:
void maybeSendIgnoreSetToNode(SharedNodePointer node); void maybeSendIgnoreSetToNode(SharedNodePointer node);
private: private:
NodeList() : LimitedNodeList(0, 0) { assert(false); } // Not implemented, needed for DependencyManager templates compile NodeList() : LimitedNodeList(INVALID_PORT, INVALID_PORT) { assert(false); } // Not implemented, needed for DependencyManager templates compile
NodeList(char ownerType, unsigned short socketListenPort = 0, unsigned short dtlsListenPort = 0); NodeList(char ownerType, int socketListenPort = INVALID_PORT, int dtlsListenPort = INVALID_PORT);
NodeList(NodeList const&); // Don't implement, needed to avoid copies of singleton NodeList(NodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
void operator=(NodeList const&); // Don't implement, needed to avoid copies of singleton void operator=(NodeList const&) = delete; // Don't implement, needed to avoid copies of singleton
void processDomainServerAuthRequest(const QByteArray& packet); void processDomainServerAuthRequest(const QByteArray& packet);
void requestAuthForDomainServer(); void requestAuthForDomainServer();

View file

@ -63,10 +63,12 @@ void Socket::bind(const QHostAddress& address, quint16 port) {
} }
void Socket::rebind() { void Socket::rebind() {
quint16 oldPort = _udpSocket.localPort(); rebind(_udpSocket.localPort());
}
void Socket::rebind(quint16 localPort) {
_udpSocket.close(); _udpSocket.close();
bind(QHostAddress::AnyIPv4, oldPort); bind(QHostAddress::AnyIPv4, localPort);
} }
void Socket::setSystemBufferSizes() { void Socket::setSystemBufferSizes() {

View file

@ -61,8 +61,9 @@ public:
qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr); qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr);
void bind(const QHostAddress& address, quint16 port = 0); void bind(const QHostAddress& address, quint16 port = 0);
void rebind(quint16 port);
void rebind(); void rebind();
void setPacketFilterOperator(PacketFilterOperator filterOperator) { _packetFilterOperator = filterOperator; } void setPacketFilterOperator(PacketFilterOperator filterOperator) { _packetFilterOperator = filterOperator; }
void setPacketHandler(PacketHandler handler) { _packetHandler = handler; } void setPacketHandler(PacketHandler handler) { _packetHandler = handler; }
void setMessageHandler(MessageHandler handler) { _messageHandler = handler; } void setMessageHandler(MessageHandler handler) { _messageHandler = handler; }

View file

@ -189,6 +189,38 @@ protected:
float _step { 0.1f }; float _step { 0.1f };
}; };
class IntPreference : public TypedPreference<int> {
Q_OBJECT
Q_PROPERTY(float value READ getValue WRITE setValue NOTIFY valueChanged)
Q_PROPERTY(float min READ getMin CONSTANT)
Q_PROPERTY(float max READ getMax CONSTANT)
Q_PROPERTY(float step READ getStep CONSTANT)
public:
IntPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: TypedPreference(category, name, getter, setter) { }
float getMin() const { return _min; }
void setMin(float min) { _min = min; };
float getMax() const { return _max; }
void setMax(float max) { _max = max; };
float getStep() const { return _step; }
void setStep(float step) { _step = step; };
signals:
void valueChanged();
protected:
void emitValueChanged() override { emit valueChanged(); }
int _min { std::numeric_limits<int>::min() };
int _max { std::numeric_limits<int>::max() };
int _step { 1 };
};
class StringPreference : public TypedPreference<QString> { class StringPreference : public TypedPreference<QString> {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged) Q_PROPERTY(QString value READ getValue WRITE setValue NOTIFY valueChanged)
@ -222,6 +254,15 @@ public:
Type getType() override { return Spinner; } Type getType() override { return Spinner; }
}; };
class IntSpinnerPreference : public IntPreference {
Q_OBJECT
public:
IntSpinnerPreference(const QString& category, const QString& name, Getter getter, Setter setter)
: IntPreference(category, name, getter, setter) { }
Type getType() override { return Spinner; }
};
class EditPreference : public StringPreference { class EditPreference : public StringPreference {
Q_OBJECT Q_OBJECT
Q_PROPERTY(QString placeholderText READ getPlaceholderText CONSTANT) Q_PROPERTY(QString placeholderText READ getPlaceholderText CONSTANT)

View file

@ -10,7 +10,7 @@
// //
HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/";
Script.include("../../libraries/toolBars.js"); Script.include("/~/system/libraries/toolBars.js");
var recordingFile = "recording.rec"; var recordingFile = "recording.rec";

View file

@ -507,7 +507,7 @@ public:
DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
DependencyManager::registerInheritance<SpatialParentFinder, ParentFinder>(); DependencyManager::registerInheritance<SpatialParentFinder, ParentFinder>();
DependencyManager::set<AddressManager>(); DependencyManager::set<AddressManager>();
DependencyManager::set<NodeList>(NodeType::Agent, 0); DependencyManager::set<NodeList>(NodeType::Agent);
DependencyManager::set<DeferredLightingEffect>(); DependencyManager::set<DeferredLightingEffect>();
DependencyManager::set<ResourceCacheSharedItems>(); DependencyManager::set<ResourceCacheSharedItems>();
DependencyManager::set<TextureCache>(); DependencyManager::set<TextureCache>();

View file

@ -295,7 +295,7 @@ public:
DependencyManager::registerInheritance<LimitedNodeList, NodeList>(); DependencyManager::registerInheritance<LimitedNodeList, NodeList>();
//DependencyManager::registerInheritance<SpatialParentFinder, ParentFinder>(); //DependencyManager::registerInheritance<SpatialParentFinder, ParentFinder>();
DependencyManager::set<AddressManager>(); DependencyManager::set<AddressManager>();
DependencyManager::set<NodeList>(NodeType::Agent, 0); DependencyManager::set<NodeList>(NodeType::Agent);
DependencyManager::set<DeferredLightingEffect>(); DependencyManager::set<DeferredLightingEffect>();
DependencyManager::set<ResourceCacheSharedItems>(); DependencyManager::set<ResourceCacheSharedItems>();
DependencyManager::set<TextureCache>(); DependencyManager::set<TextureCache>();