Merge branch 'master' of github.com:highfidelity/hifi into raypick-avatars

This commit is contained in:
Seth Alves 2016-06-28 16:56:27 -07:00
commit 224008afd6
8 changed files with 143 additions and 63 deletions

View file

@ -60,6 +60,50 @@ const QString DomainMetadata::Descriptors::Hours::CLOSE = "close";
//
// it is meant to be sent to and consumed by an external API
// merge delta into target
// target should be of the form [ OpenTime, CloseTime ],
// delta should be of the form [ { open: Time, close: Time } ]
void parseHours(QVariant delta, QVariant& target) {
using Hours = DomainMetadata::Descriptors::Hours;
assert(target.canConvert<QVariantList>());
auto& targetList = *static_cast<QVariantList*>(target.data());
// if/when multiple ranges are allowed, this list will need to be iterated
assert(targetList[0].canConvert<QVariantList>());
auto& hours = *static_cast<QVariantList*>(targetList[0].data());
if (!delta.canConvert<QVariantList>()) {
return;
}
auto& deltaList = *static_cast<QVariantList*>(delta.data());
if (deltaList.isEmpty()) {
return;
}
auto& deltaHours = *static_cast<QVariantMap*>(deltaList.first().data());
if (deltaHours.isEmpty()) {
return;
}
// merge delta into base
static const int OPEN_INDEX = 0;
static const int CLOSE_INDEX = 1;
auto open = deltaHours.find(Hours::OPEN);
if (open != deltaHours.end()) {
hours[OPEN_INDEX] = open.value();
}
assert(hours[OPEN_INDEX].canConvert<QString>());
auto close = deltaHours.find(Hours::CLOSE);
if (close != deltaHours.end()) {
hours[CLOSE_INDEX] = close.value();
}
assert(hours[CLOSE_INDEX].canConvert<QString>());
}
DomainMetadata::DomainMetadata(QObject* domainServer) : QObject(domainServer) {
// set up the structure necessary for casting during parsing (see parseHours, esp.)
_metadata[USERS] = QVariantMap {};
@ -100,45 +144,12 @@ QJsonObject DomainMetadata::get(const QString& group) {
return QJsonObject::fromVariantMap(_metadata[group].toMap());
}
// merge delta into target
// target should be of the form [ OpenTime, CloseTime ],
// delta should be of the form [ { open: Time, close: Time } ]
void parseHours(QVariant delta, QVariant& target) {
using Hours = DomainMetadata::Descriptors::Hours;
assert(target.canConvert<QVariantList>());
auto& targetList = *static_cast<QVariantList*>(target.data());
// if/when multiple ranges are allowed, this list will need to be iterated
assert(targetList[0].canConvert<QVariantList>());
auto& hours = *static_cast<QVariantList*>(targetList[0].data());
auto deltaHours = delta.toList()[0].toMap();
if (deltaHours.isEmpty()) {
return;
}
// merge delta into base
static const int OPEN_INDEX = 0;
static const int CLOSE_INDEX = 1;
auto open = deltaHours.find(Hours::OPEN);
if (open != deltaHours.end()) {
hours[OPEN_INDEX] = open.value();
}
assert(hours[OPEN_INDEX].canConvert<QString>());
auto close = deltaHours.find(Hours::CLOSE);
if (close != deltaHours.end()) {
hours[CLOSE_INDEX] = close.value();
}
assert(hours[CLOSE_INDEX].canConvert<QString>());
}
void DomainMetadata::descriptorsChanged() {
// get descriptors
assert(_metadata[DESCRIPTORS].canConvert<QVariantMap>());
auto& state = *static_cast<QVariantMap*>(_metadata[DESCRIPTORS].data());
auto settings = static_cast<DomainServer*>(parent())->_settingsManager.getSettingsMap();
auto descriptors = settings[DESCRIPTORS].toMap();
auto& settings = static_cast<DomainServer*>(parent())->_settingsManager.getSettingsMap();
auto& descriptors = static_cast<DomainServer*>(parent())->_settingsManager.getDescriptorsMap();
// copy simple descriptors (description/maturity)
state[Descriptors::DESCRIPTION] = descriptors[Descriptors::DESCRIPTION];
@ -149,20 +160,20 @@ void DomainMetadata::descriptorsChanged() {
state[Descriptors::TAGS] = descriptors[Descriptors::TAGS].toList();
// parse capacity
const QString CAPACITY = "security.maximum_user_capacity";
static const QString CAPACITY = "security.maximum_user_capacity";
const QVariant* capacityVariant = valueForKeyPath(settings, CAPACITY);
unsigned int capacity = capacityVariant ? capacityVariant->toUInt() : 0;
state[Descriptors::CAPACITY] = capacity;
// parse operating hours
const QString WEEKDAY_HOURS = "weekday_hours";
const QString WEEKEND_HOURS = "weekend_hours";
const QString UTC_OFFSET = "utc_offset";
static const QString WEEKDAY_HOURS = "weekday_hours";
static const QString WEEKEND_HOURS = "weekend_hours";
static const QString UTC_OFFSET = "utc_offset";
assert(state[Descriptors::HOURS].canConvert<QVariantMap>());
auto& hours = *static_cast<QVariantMap*>(state[Descriptors::HOURS].data());
parseHours(descriptors.take(WEEKDAY_HOURS), hours[Descriptors::Hours::WEEKDAY]);
parseHours(descriptors.take(WEEKEND_HOURS), hours[Descriptors::Hours::WEEKEND]);
hours[Descriptors::Hours::UTC_OFFSET] = descriptors.take(UTC_OFFSET);
parseHours(descriptors[WEEKDAY_HOURS], hours[Descriptors::Hours::WEEKDAY]);
parseHours(descriptors[WEEKEND_HOURS], hours[Descriptors::Hours::WEEKEND]);
#if DEV_BUILD || PR_BUILD
qDebug() << "Domain metadata descriptors set:" << QJsonObject::fromVariantMap(_metadata[DESCRIPTORS].toMap());

View file

@ -27,6 +27,7 @@
#include <HifiConfigVariantMap.h>
#include <HTTPConnection.h>
#include <NLPacketList.h>
#include <NumericalConstants.h>
#include "DomainServerSettingsManager.h"
@ -263,23 +264,7 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList
if (oldVersion < 1.5) {
// This was prior to operating hours, so add default hours
static const QString WEEKDAY_HOURS{ "descriptors.weekday_hours" };
static const QString WEEKEND_HOURS{ "descriptors.weekend_hours" };
static const QString UTC_OFFSET{ "descriptors.utc_offset" };
QVariant* weekdayHours = valueForKeyPath(_configMap.getUserConfig(), WEEKDAY_HOURS, true);
QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true);
QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true);
*weekdayHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } };
*weekendHours = QVariantList { QVariantMap{ { "open", QVariant("00:00") }, { "close", QVariant("23:59") } } };
*utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)3600);
// write the new settings to file
persistToFile();
// reload the master and user config so the merged config is correct
_configMap.loadMasterAndUserConfig(_argumentList);
validateDescriptorsMap();
}
}
@ -289,6 +274,49 @@ void DomainServerSettingsManager::setupConfigMap(const QStringList& argumentList
appSettings.setValue(JSON_SETTINGS_VERSION_KEY, _descriptionVersion);
}
QVariantMap& DomainServerSettingsManager::getDescriptorsMap() {
validateDescriptorsMap();
static const QString DESCRIPTORS{ "descriptors" };
return *static_cast<QVariantMap*>(getSettingsMap()[DESCRIPTORS].data());
}
void DomainServerSettingsManager::validateDescriptorsMap() {
static const QString WEEKDAY_HOURS{ "descriptors.weekday_hours" };
static const QString WEEKEND_HOURS{ "descriptors.weekend_hours" };
static const QString UTC_OFFSET{ "descriptors.utc_offset" };
QVariant* weekdayHours = valueForKeyPath(_configMap.getUserConfig(), WEEKDAY_HOURS, true);
QVariant* weekendHours = valueForKeyPath(_configMap.getUserConfig(), WEEKEND_HOURS, true);
QVariant* utcOffset = valueForKeyPath(_configMap.getUserConfig(), UTC_OFFSET, true);
static const QString OPEN{ "open" };
static const QString CLOSE{ "close" };
static const QString DEFAULT_OPEN{ "00:00" };
static const QString DEFAULT_CLOSE{ "23:59" };
bool wasMalformed = false;
if (weekdayHours->isNull()) {
*weekdayHours = QVariantList{ QVariantMap{ { OPEN, QVariant(DEFAULT_OPEN) }, { CLOSE, QVariant(DEFAULT_CLOSE) } } };
wasMalformed = true;
}
if (weekendHours->isNull()) {
*weekendHours = QVariantList{ QVariantMap{ { OPEN, QVariant(DEFAULT_OPEN) }, { CLOSE, QVariant(DEFAULT_CLOSE) } } };
wasMalformed = true;
}
if (utcOffset->isNull()) {
*utcOffset = QVariant(QTimeZone::systemTimeZone().offsetFromUtc(QDateTime::currentDateTime()) / (float)SECS_PER_HOUR);
wasMalformed = true;
}
if (wasMalformed) {
// write the new settings to file
persistToFile();
// reload the master and user config so the merged config is correct
_configMap.loadMasterAndUserConfig(_argumentList);
}
}
void DomainServerSettingsManager::packPermissionsForMap(QString mapName,
NodePermissionsMap& agentPermissions,
QString keyPath) {

View file

@ -41,6 +41,8 @@ public:
QVariantMap& getUserSettingsMap() { return _configMap.getUserConfig(); }
QVariantMap& getSettingsMap() { return _configMap.getMergedConfig(); }
QVariantMap& getDescriptorsMap();
bool haveStandardPermissionsForName(const QString& name) const { return _standardAgentPermissions.contains(name); }
bool havePermissionsForName(const QString& name) const { return _agentPermissions.contains(name); }
NodePermissions getStandardPermissionsForName(const QString& name) const;
@ -72,6 +74,8 @@ private:
friend class DomainServer;
void validateDescriptorsMap();
void packPermissionsForMap(QString mapName, NodePermissionsMap& agentPermissions, QString keyPath);
void packPermissions();
void unpackPermissions();

View file

@ -24,6 +24,13 @@ FocusScope {
readonly property int invalid_position: -9999;
property rect recommendedRect: Qt.rect(0,0,0,0);
property var expectedChildren;
property bool repositionLocked: true
onRepositionLockedChanged: {
if (!repositionLocked) {
d.handleSizeChanged();
}
}
onHeightChanged: d.handleSizeChanged();
@ -52,11 +59,14 @@ FocusScope {
readonly property real menu: 8000
}
QtObject {
id: d
function handleSizeChanged() {
if (desktop.repositionLocked) {
return;
}
var oldRecommendedRect = recommendedRect;
var newRecommendedRectJS = (typeof Controller === "undefined") ? Qt.rect(0,0,0,0) : Controller.getRecommendedOverlayRect();
var newRecommendedRect = Qt.rect(newRecommendedRectJS.x, newRecommendedRectJS.y,
@ -235,6 +245,10 @@ FocusScope {
}
function repositionAll() {
if (desktop.repositionLocked) {
return;
}
var oldRecommendedRect = recommendedRect;
var oldRecommendedDimmensions = { x: oldRecommendedRect.width, y: oldRecommendedRect.height };
var newRecommendedRect = Controller.getRecommendedOverlayRect();

View file

@ -39,6 +39,19 @@ Item {
onSelected: d.handleSelection(subMenu, currentItem, item)
}
}
property var delay: Timer { // No setTimeout in QML.
property var menuItem: null;
interval: 0
repeat: false
running: false
function trigger(item) { // Capture item and schedule asynchronous Timer.
menuItem = item;
start();
}
onTriggered: {
menuItem.trigger(); // Now trigger the item.
}
}
function toModel(items) {
var result = modelMaker.createObject(desktop);
@ -128,7 +141,8 @@ Item {
case MenuItemType.Item:
console.log("Triggering " + item.text)
item.trigger();
// Don't block waiting for modal dialogs and such that the menu might open.
delay.trigger(item);
clearMenus();
break;
}

View file

@ -963,6 +963,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
updateHeartbeat();
loadSettings();
// Now that we've loaded the menu and thus switched to the previous display plugin
// we can unlock the desktop repositioning code, since all the positions will be
// relative to the desktop size for this plugin
auto offscreenUi = DependencyManager::get<OffscreenUi>();
offscreenUi->getDesktop()->setProperty("repositionLocked", false);
// Make sure we don't time out during slow operations at startup
updateHeartbeat();
@ -5343,7 +5350,6 @@ void Application::updateDisplayMode() {
_displayPlugin = newDisplayPlugin;
}
emit activeDisplayPluginChanged();
// reset the avatar, to set head and hand palms back to a reasonable default pose.

View file

@ -39,6 +39,9 @@ const quint64 NSECS_PER_MSEC = 1000000;
const quint64 USECS_PER_MSEC = 1000;
const quint64 MSECS_PER_SECOND = 1000;
const quint64 USECS_PER_SECOND = USECS_PER_MSEC * MSECS_PER_SECOND;
const quint64 SECS_PER_MINUTE = 60;
const quint64 MINS_PER_HOUR = 60;
const quint64 SECS_PER_HOUR = SECS_PER_MINUTE * MINS_PER_HOUR;
const int BITS_IN_BYTE = 8;
const int BYTES_PER_KILOBYTE = 1000;

View file

@ -599,8 +599,6 @@ var usersWindow = (function () {
usersRequest.ontimeout = pollUsersTimedOut;
usersRequest.onreadystatechange = processUsers;
usersRequest.send();
checkLoggedIn();
}
processUsers = function () {
@ -646,6 +644,8 @@ var usersWindow = (function () {
updateUsersDisplay();
updateOverlayPositions();
checkLoggedIn();
} else {
print("Error: Request for users status returned " + usersRequest.status + " " + usersRequest.statusText);
usersTimer = Script.setTimeout(pollUsers, HTTP_GET_TIMEOUT); // Try again after a longer delay.