Merge branch 'master' of github.com:highfidelity/hifi into linux-qol

This commit is contained in:
Seth Alves 2016-05-07 11:04:50 -07:00
commit 4b1274cb0f
19 changed files with 276 additions and 212 deletions

View file

@ -161,7 +161,6 @@ extern "C" {
using namespace std;
static QTimer locationUpdateTimer;
static QTimer balanceUpdateTimer;
static QTimer identityPacketTimer;
static QTimer pingTimer;
@ -677,6 +676,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
// send a location update immediately
discoverabilityManager->updateLocation();
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated);
@ -688,13 +690,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
// connect to appropriate slots on AccountManager
AccountManager& accountManager = AccountManager::getInstance();
const qint64 BALANCE_UPDATE_INTERVAL_MSECS = 5 * MSECS_PER_SEC;
connect(&balanceUpdateTimer, &QTimer::timeout, &accountManager, &AccountManager::updateBalance);
balanceUpdateTimer.start(BALANCE_UPDATE_INTERVAL_MSECS);
connect(&accountManager, &AccountManager::balanceChanged, this, &Application::updateWindowTitle);
auto dialogsManager = DependencyManager::get<DialogsManager>();
connect(&accountManager, &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
connect(&accountManager, &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
@ -1197,7 +1192,6 @@ void Application::cleanupBeforeQuit() {
// first stop all timers directly or by invokeMethod
// depending on what thread they run in
locationUpdateTimer.stop();
balanceUpdateTimer.stop();
identityPacketTimer.stop();
pingTimer.stop();
QMetaObject::invokeMethod(&_settingsTimer, "stop", Qt::BlockingQueuedConnection);

View file

@ -15,12 +15,13 @@
#include <AddressManager.h>
#include <DomainHandler.h>
#include <NodeList.h>
#include <UserActivityLogger.h>
#include <UUID.h>
#include "DiscoverabilityManager.h"
#include "Menu.h"
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::All;
const Discoverability::Mode DEFAULT_DISCOVERABILITY_MODE = Discoverability::Friends;
DiscoverabilityManager::DiscoverabilityManager() :
_mode("discoverabilityMode", DEFAULT_DISCOVERABILITY_MODE)
@ -29,53 +30,103 @@ DiscoverabilityManager::DiscoverabilityManager() :
}
const QString API_USER_LOCATION_PATH = "/api/v1/user/location";
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
const QString SESSION_ID_KEY = "session_id";
void DiscoverabilityManager::updateLocation() {
AccountManager& accountManager = AccountManager::getInstance();
if (_mode.get() != Discoverability::None) {
if (_mode.get() != Discoverability::None && accountManager.isLoggedIn()) {
auto addressManager = DependencyManager::get<AddressManager>();
DomainHandler& domainHandler = DependencyManager::get<NodeList>()->getDomainHandler();
if (accountManager.isLoggedIn() && domainHandler.isConnected()
&& (!addressManager->getRootPlaceID().isNull() || !domainHandler.getUUID().isNull())) {
// construct a QJsonObject given the user's current address information
QJsonObject rootObject;
QJsonObject locationObject;
QString pathString = addressManager->currentPath();
const QString LOCATION_KEY_IN_ROOT = "location";
const QString PATH_KEY_IN_LOCATION = "path";
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
if (!addressManager->getRootPlaceID().isNull()) {
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
} else {
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
}
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
accountManager.sendRequest(API_USER_LOCATION_PATH, AccountManagerAuth::Required,
QNetworkAccessManager::PutOperation,
JSONCallbackParameters(), QJsonDocument(rootObject).toJson());
// construct a QJsonObject given the user's current address information
QJsonObject rootObject;
QJsonObject locationObject;
QString pathString = addressManager->currentPath();
const QString LOCATION_KEY_IN_ROOT = "location";
const QString PATH_KEY_IN_LOCATION = "path";
locationObject.insert(PATH_KEY_IN_LOCATION, pathString);
const QString CONNECTED_KEY_IN_LOCATION = "connected";
locationObject.insert(CONNECTED_KEY_IN_LOCATION, domainHandler.isConnected());
if (!addressManager->getRootPlaceID().isNull()) {
const QString PLACE_ID_KEY_IN_LOCATION = "place_id";
locationObject.insert(PLACE_ID_KEY_IN_LOCATION,
uuidStringWithoutCurlyBraces(addressManager->getRootPlaceID()));
}
} else {
if (!domainHandler.getUUID().isNull()) {
const QString DOMAIN_ID_KEY_IN_LOCATION = "domain_id";
locationObject.insert(DOMAIN_ID_KEY_IN_LOCATION,
uuidStringWithoutCurlyBraces(domainHandler.getUUID()));
}
// in case the place/domain isn't in the database, we send the network address and port
auto& domainSockAddr = domainHandler.getSockAddr();
const QString NETWORK_ADRESS_KEY_IN_LOCATION = "network_address";
locationObject.insert(NETWORK_ADRESS_KEY_IN_LOCATION, domainSockAddr.getAddress().toString());
const QString NETWORK_ADDRESS_PORT_IN_LOCATION = "network_port";
locationObject.insert(NETWORK_ADDRESS_PORT_IN_LOCATION, domainSockAddr.getPort());
const QString FRIENDS_ONLY_KEY_IN_LOCATION = "friends_only";
locationObject.insert(FRIENDS_ONLY_KEY_IN_LOCATION, (_mode.get() == Discoverability::Friends));
// if we have a session ID add it now, otherwise add a null value
rootObject[SESSION_ID_KEY] = _sessionID.isEmpty() ? QJsonValue() : _sessionID;
JSONCallbackParameters callbackParameters;
callbackParameters.jsonCallbackReceiver = this;
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
// figure out if we'll send a fresh location or just a simple heartbeat
auto apiPath = API_USER_HEARTBEAT_PATH;
if (locationObject != _lastLocationObject) {
// we have a changed location, send it now
_lastLocationObject = locationObject;
rootObject.insert(LOCATION_KEY_IN_ROOT, locationObject);
apiPath = API_USER_LOCATION_PATH;
}
accountManager.sendRequest(apiPath, AccountManagerAuth::Required,
QNetworkAccessManager::PutOperation,
callbackParameters, QJsonDocument(rootObject).toJson());
} else if (UserActivityLogger::getInstance().isEnabled()) {
// we still send a heartbeat to the metaverse server for stats collection
const QString API_USER_HEARTBEAT_PATH = "/api/v1/user/heartbeat";
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Required, QNetworkAccessManager::PutOperation);
JSONCallbackParameters callbackParameters;
callbackParameters.jsonCallbackReceiver = this;
callbackParameters.jsonCallbackMethod = "handleHeartbeatResponse";
QJsonObject heartbeatObject;
if (!_sessionID.isEmpty()) {
heartbeatObject[SESSION_ID_KEY] = _sessionID;
} else {
heartbeatObject[SESSION_ID_KEY] = QJsonValue();
}
accountManager.sendRequest(API_USER_HEARTBEAT_PATH, AccountManagerAuth::Optional,
QNetworkAccessManager::PutOperation, callbackParameters,
QJsonDocument(heartbeatObject).toJson());
}
}
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
auto dataObject = AccountManager::dataObjectFromResponse(requestReply);
if (!dataObject.isEmpty()) {
_sessionID = dataObject[SESSION_ID_KEY].toString();
}
}
@ -93,6 +144,9 @@ void DiscoverabilityManager::setDiscoverabilityMode(Discoverability::Mode discov
if (static_cast<int>(_mode.get()) == Discoverability::None) {
// if we just got set to no discoverability, make sure that we delete our location in DB
removeLocation();
} else {
// we have a discoverability mode that says we should send a location, do that right away
updateLocation();
}
emit discoverabilityModeChanged(discoverabilityMode);

View file

@ -42,10 +42,15 @@ public slots:
signals:
void discoverabilityModeChanged(Discoverability::Mode discoverabilityMode);
private slots:
void handleHeartbeatResponse(QNetworkReply& requestReply);
private:
DiscoverabilityManager();
Setting::Handle<int> _mode;
QString _sessionID;
QJsonObject _lastLocationObject;
};
#endif // hifi_DiscoverabilityManager_h
#endif // hifi_DiscoverabilityManager_h

View file

@ -131,71 +131,102 @@ const glm::vec3 randVector() {
// Do some basic timing tests and report the results
void runTimingTests() {
// How long does it take to make a call to get the time?
const int numTimingTests = 3;
QElapsedTimer startTime;
float elapsedNSecs;
float elapsedUSecs;
qCDebug(interfaceapp, "numTimingTests: %d", numTimingTests);
startTime.start();
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() ns: %f", (double)elapsedNSecs / numTimingTests);
// Test sleep functions for accuracy
startTime.start();
for (int i = 0; i < numTimingTests; i++) {
QThread::msleep(1);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / numTimingTests));
startTime.start();
for (int i = 0; i < numTimingTests; i++) {
QThread::sleep(1);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "QThread::sleep(1) s: %f", (double)(elapsedNSecs / NSECS_PER_MSEC / MSECS_PER_SECOND / numTimingTests));
const int numUsecTests = 1000;
startTime.start();
for (int i = 0; i < numUsecTests; i++) {
usleep(1);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(1) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
startTime.start();
for (int i = 0; i < numUsecTests; i++) {
usleep(10);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(10) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
startTime.start();
for (int i = 0; i < numUsecTests; i++) {
usleep(100);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(100) (1000x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numUsecTests));
startTime.start();
for (int i = 0; i < numTimingTests; i++) {
usleep(1000);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(1000) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
startTime.start();
for (int i = 0; i < numTimingTests; i++) {
usleep(1001);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(1001) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
startTime.start();
for (int i = 0; i < numTimingTests; i++) {
usleep(1500);
}
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(1500) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC / numTimingTests));
startTime.start();
usleep(15000);
elapsedNSecs = (float)startTime.nsecsElapsed();
qCDebug(interfaceapp, "usleep(15000) (1x) us: %f", (double)(elapsedNSecs / NSECS_PER_USEC));
const int numTests = 1000000;
int* iResults = (int*)malloc(sizeof(int) * numTests);
float fTest = 1.0;
float* fResults = (float*)malloc(sizeof(float) * numTests);
QElapsedTimer startTime;
startTime.start();
float elapsedUsecs;
float NSEC_TO_USEC = 1.0f / 1000.0f;
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "QElapsedTimer::nsecElapsed() usecs: %f", (double)elapsedUsecs);
// Test sleep functions for accuracy
startTime.start();
QThread::msleep(1);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "QThread::msleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
QThread::sleep(1);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "QThread::sleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
usleep(1);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "usleep(1) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
usleep(10);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "usleep(10) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
usleep(100);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "usleep(100) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
usleep(1000);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "usleep(1000) ms: %f", (double)(elapsedUsecs / 1000.0f));
startTime.start();
usleep(15000);
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "usleep(15000) ms: %f", (double)(elapsedUsecs / 1000.0f));
// Random number generation
startTime.start();
for (int i = 0; i < numTests; i++) {
iResults[i] = rand();
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp, "rand() stored in array usecs: %f, first result:%d",
(double)(elapsedUsecs / numTests), iResults[0]);
(double)(elapsedUSecs / numTests), iResults[0]);
// Random number generation using randFloat()
startTime.start();
for (int i = 0; i < numTests; i++) {
fResults[i] = randFloat();
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp, "randFloat() stored in array usecs: %f, first result: %f",
(double)(elapsedUsecs / numTests), (double)(fResults[0]));
(double)(elapsedUSecs / numTests), (double)(fResults[0]));
free(iResults);
free(fResults);
@ -206,8 +237,8 @@ void runTimingTests() {
for (int i = 0; i < numTests; i++) {
fTest = powf(fTest, 0.5f);
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUsecs / (float) numTests));
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp, "powf(f, 0.5) usecs: %f", (double)(elapsedUSecs / (float) numTests));
// Vector Math
float distance;
@ -218,9 +249,9 @@ void runTimingTests() {
//float distanceSquared = glm::dot(temp, temp);
distance = glm::distance(pointA, pointB);
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp, "vector math usecs: %f [%f usecs total for %d tests], last result:%f",
(double)(elapsedUsecs / (float) numTests), (double)elapsedUsecs, numTests, (double)distance);
(double)(elapsedUSecs / (float) numTests), (double)elapsedUSecs, numTests, (double)distance);
// Vec3 test
glm::vec3 vecA(randVector()), vecB(randVector());
@ -231,9 +262,9 @@ void runTimingTests() {
glm::vec3 temp = vecA-vecB;
result = glm::dot(temp,temp);
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp, "vec3 assign and dot() usecs: %f, last result:%f",
(double)(elapsedUsecs / numTests), (double)result);
(double)(elapsedUSecs / numTests), (double)result);
quint64 BYTE_CODE_MAX_TEST_VALUE = 99999999;
@ -265,9 +296,9 @@ void runTimingTests() {
}
}
elapsedUsecs = (float)startTime.nsecsElapsed() * NSEC_TO_USEC;
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUsecs
<< "per test:" << (double) (elapsedUsecs / tests)
elapsedUSecs = (float)startTime.nsecsElapsed() / NSECS_PER_USEC;
qCDebug(interfaceapp) << "ByteCountCoded<quint64> usecs: " << elapsedUSecs
<< "per test:" << (double) (elapsedUSecs / tests)
<< "tests:" << tests
<< "failed:" << failed;
}

View file

@ -13,32 +13,16 @@
#include "AccountScriptingInterface.h"
AccountScriptingInterface::AccountScriptingInterface() {
AccountManager& accountManager = AccountManager::getInstance();
connect(&accountManager, &AccountManager::balanceChanged, this,
&AccountScriptingInterface::updateBalance);
}
AccountScriptingInterface* AccountScriptingInterface::getInstance() {
static AccountScriptingInterface sharedInstance;
return &sharedInstance;
}
float AccountScriptingInterface::getBalance() {
AccountManager& accountManager = AccountManager::getInstance();
return accountManager.getAccountInfo().getBalanceInSatoshis();
}
bool AccountScriptingInterface::isLoggedIn() {
AccountManager& accountManager = AccountManager::getInstance();
return accountManager.isLoggedIn();
}
void AccountScriptingInterface::updateBalance() {
AccountManager& accountManager = AccountManager::getInstance();
emit balanceChanged(accountManager.getAccountInfo().getBalanceInSatoshis());
}
QString AccountScriptingInterface::getUsername() {
AccountManager& accountManager = AccountManager::getInstance();
if (accountManager.isLoggedIn()) {

View file

@ -16,17 +16,11 @@
class AccountScriptingInterface : public QObject {
Q_OBJECT
AccountScriptingInterface();
signals:
void balanceChanged(float newBalance);
public slots:
static AccountScriptingInterface* getInstance();
float getBalance();
QString getUsername();
bool isLoggedIn();
void updateBalance();
};
#endif // hifi_AccountScriptingInterface_h

View file

@ -1193,10 +1193,15 @@ void AvatarData::sendIdentityPacket() {
QByteArray identityData = identityByteArray();
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, identityData.size());
identityPacket->write(identityData);
nodeList->broadcastToNodes(std::move(identityPacket), NodeSet() << NodeType::AvatarMixer);
auto packetList = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
packetList->write(identityData);
nodeList->eachMatchingNode(
[&](const SharedNodePointer& node)->bool {
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
},
[&](const SharedNodePointer& node) {
nodeList->sendPacketList(std::move(packetList), *node);
});
}
void AvatarData::sendBillboardPacket() {

View file

@ -394,10 +394,20 @@ const QString& NetworkMaterial::getTextureName(MapChannel channel) {
return NO_TEXTURE;
}
QUrl NetworkMaterial::getTextureUrl(const QUrl& url, const FBXTexture& texture) {
// If content is inline, cache it under the fbx file, not its url
const auto baseUrl = texture.content.isEmpty() ? url : QUrl(url.url() + "/");
return baseUrl.resolved(QUrl(texture.filename));
QUrl NetworkMaterial::getTextureUrl(const QUrl& baseUrl, const FBXTexture& texture) {
if (texture.content.isEmpty()) {
// External file: search relative to the baseUrl, in case filename is relative
return baseUrl.resolved(QUrl(texture.filename));
} else {
// Inlined file: cache under the fbx file to avoid namespace clashes
// NOTE: We cannot resolve the path because filename may be an absolute path
assert(texture.filename.size() > 0);
if (texture.filename.at(0) == '/') {
return baseUrl.toString() + texture.filename;
} else {
return baseUrl.toString() + '/' + texture.filename;
}
}
}
model::TextureMapPointer NetworkMaterial::fetchTextureMap(const QUrl& baseUrl, const FBXTexture& fbxTexture,

View file

@ -66,6 +66,19 @@ JSONCallbackParameters::JSONCallbackParameters(QObject* jsonCallbackReceiver, co
}
QJsonObject AccountManager::dataObjectFromResponse(QNetworkReply &requestReply) {
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
static const QString STATUS_KEY = "status";
static const QString DATA_KEY = "data";
if (jsonObject.contains(STATUS_KEY) && jsonObject[STATUS_KEY] == "success" && jsonObject.contains(DATA_KEY)) {
return jsonObject[DATA_KEY].toObject();
} else {
return QJsonObject();
}
}
AccountManager::AccountManager() :
_authURL(),
_pendingCallbackMap()
@ -82,8 +95,6 @@ AccountManager::AccountManager() :
qRegisterMetaType<QHttpMultiPart*>("QHttpMultiPart*");
qRegisterMetaType<AccountManagerAuth::Type>();
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
}
const QString DOUBLE_SLASH_SUBSTITUTE = "slashslash";
@ -92,9 +103,6 @@ void AccountManager::logout() {
// a logout means we want to delete the DataServerAccountInfo we currently have for this URL, in-memory and in file
_accountInfo = DataServerAccountInfo();
emit balanceChanged(0);
connect(&_accountInfo, &DataServerAccountInfo::balanceChanged, this, &AccountManager::accountInfoBalanceChanged);
// remove this account from the account settings file
removeAccountFromFile();
@ -103,21 +111,6 @@ void AccountManager::logout() {
emit usernameChanged(QString());
}
void AccountManager::updateBalance() {
if (hasValidAccessToken()) {
// ask our auth endpoint for our balance
JSONCallbackParameters callbackParameters;
callbackParameters.jsonCallbackReceiver = &_accountInfo;
callbackParameters.jsonCallbackMethod = "setBalanceFromJSON";
sendRequest("/api/v1/wallets/mine", AccountManagerAuth::Required, QNetworkAccessManager::GetOperation, callbackParameters);
}
}
void AccountManager::accountInfoBalanceChanged(qint64 newBalance) {
emit balanceChanged(newBalance);
}
QString accountFileDir() {
return QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
}

View file

@ -77,6 +77,8 @@ public:
DataServerAccountInfo& getAccountInfo() { return _accountInfo; }
static QJsonObject dataObjectFromResponse(QNetworkReply& requestReply);
public slots:
void requestAccessToken(const QString& login, const QString& password);
@ -85,8 +87,6 @@ public slots:
void requestAccessTokenError(QNetworkReply::NetworkError error);
void requestProfileError(QNetworkReply::NetworkError error);
void logout();
void updateBalance();
void accountInfoBalanceChanged(qint64 newBalance);
void generateNewUserKeypair() { generateNewKeypair(); }
void generateNewDomainKeypair(const QUuid& domainID) { generateNewKeypair(false, domainID); }
@ -98,7 +98,6 @@ signals:
void loginComplete(const QUrl& authURL);
void loginFailed();
void logoutComplete();
void balanceChanged(qint64 newBalance);
void newKeypair();
private slots:

View file

@ -31,8 +31,6 @@ DataServerAccountInfo::DataServerAccountInfo(const DataServerAccountInfo& otherI
_xmppPassword = otherInfo._xmppPassword;
_discourseApiKey = otherInfo._discourseApiKey;
_walletID = otherInfo._walletID;
_balance = otherInfo._balance;
_hasBalance = otherInfo._hasBalance;
_privateKey = otherInfo._privateKey;
_domainID = otherInfo._domainID;
}
@ -51,8 +49,6 @@ void DataServerAccountInfo::swap(DataServerAccountInfo& otherInfo) {
swap(_xmppPassword, otherInfo._xmppPassword);
swap(_discourseApiKey, otherInfo._discourseApiKey);
swap(_walletID, otherInfo._walletID);
swap(_balance, otherInfo._balance);
swap(_hasBalance, otherInfo._hasBalance);
swap(_privateKey, otherInfo._privateKey);
swap(_domainID, otherInfo._domainID);
}
@ -87,23 +83,6 @@ void DataServerAccountInfo::setWalletID(const QUuid& walletID) {
}
}
void DataServerAccountInfo::setBalance(qint64 balance) {
if (!_hasBalance || _balance != balance) {
_balance = balance;
_hasBalance = true;
emit balanceChanged(_balance);
}
}
void DataServerAccountInfo::setBalanceFromJSON(QNetworkReply& requestReply) {
QJsonObject jsonObject = QJsonDocument::fromJson(requestReply.readAll()).object();
if (jsonObject["status"].toString() == "success") {
qint64 balanceInSatoshis = jsonObject["data"].toObject()["wallet"].toObject()["balance"].toDouble();
setBalance(balanceInSatoshis);
}
}
bool DataServerAccountInfo::hasProfile() const {
return _username.length() > 0;
}

View file

@ -43,13 +43,6 @@ public:
const QUuid& getWalletID() const { return _walletID; }
void setWalletID(const QUuid& walletID);
qint64 getBalance() const { return _balance; }
float getBalanceInSatoshis() const { return _balance / SATOSHIS_PER_CREDIT; }
void setBalance(qint64 balance);
bool hasBalance() const { return _hasBalance; }
void setHasBalance(bool hasBalance) { _hasBalance = hasBalance; }
Q_INVOKABLE void setBalanceFromJSON(QNetworkReply& requestReply);
QByteArray getUsernameSignature(const QUuid& connectionToken);
bool hasPrivateKey() const { return !_privateKey.isEmpty(); }
void setPrivateKey(const QByteArray& privateKey) { _privateKey = privateKey; }
@ -65,8 +58,7 @@ public:
friend QDataStream& operator<<(QDataStream &out, const DataServerAccountInfo& info);
friend QDataStream& operator>>(QDataStream &in, DataServerAccountInfo& info);
signals:
qint64 balanceChanged(qint64 newBalance);
private:
void swap(DataServerAccountInfo& otherInfo);
@ -75,8 +67,6 @@ private:
QString _xmppPassword;
QString _discourseApiKey;
QUuid _walletID;
qint64 _balance { 0 };
bool _hasBalance { false };
QUuid _domainID; // if this holds account info for a domain, this holds the ID of that domain
QByteArray _privateKey;

View file

@ -18,4 +18,4 @@ namespace NetworkingConstants {
const QUrl METAVERSE_SERVER_URL = QUrl("https://metaverse.highfidelity.com");
}
#endif // hifi_NetworkingConstants_h
#endif // hifi_NetworkingConstants_h

View file

@ -28,6 +28,8 @@ public:
static UserActivityLogger& getInstance();
public slots:
bool isEnabled() { return !_disabled.get(); }
void disable(bool disable);
void logAction(QString action, QJsonObject details = QJsonObject(), JSONCallbackParameters params = JSONCallbackParameters());

View file

@ -225,9 +225,7 @@ void PhysicsEngine::removeContacts(ObjectMotionState* motionState) {
ContactMap::iterator contactItr = _contactMap.begin();
while (contactItr != _contactMap.end()) {
if (contactItr->first._a == motionState || contactItr->first._b == motionState) {
ContactMap::iterator iterToDelete = contactItr;
++contactItr;
_contactMap.erase(iterToDelete);
contactItr = _contactMap.erase(contactItr);
} else {
++contactItr;
}
@ -386,9 +384,7 @@ const CollisionEvents& PhysicsEngine::getCollisionEvents() {
}
if (type == CONTACT_EVENT_TYPE_END) {
ContactMap::iterator iterToDelete = contactItr;
++contactItr;
_contactMap.erase(iterToDelete);
contactItr = _contactMap.erase(contactItr);
} else {
++contactItr;
}

View file

@ -35,6 +35,7 @@ const float METERS_PER_CENTIMETER = 0.01f;
const float METERS_PER_MILLIMETER = 0.001f;
const float MILLIMETERS_PER_METER = 1000.0f;
const quint64 NSECS_PER_USEC = 1000;
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;

View file

@ -455,19 +455,44 @@ void printVoxelCode(unsigned char* voxelCode) {
}
#ifdef _WIN32
void usleep(int waitTime) {
const quint64 BUSY_LOOP_USECS = 2000;
quint64 compTime = waitTime + usecTimestampNow();
quint64 compTimeSleep = compTime - BUSY_LOOP_USECS;
while (true) {
if (usecTimestampNow() < compTimeSleep) {
QThread::msleep(1);
}
if (usecTimestampNow() >= compTime) {
break;
}
void usleep(int waitTime) {
// Use QueryPerformanceCounter for least overhead
LARGE_INTEGER now; // ticks
QueryPerformanceCounter(&now);
static int64_t ticksPerSec = 0;
if (ticksPerSec == 0) {
LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency);
ticksPerSec = frequency.QuadPart;
}
// order ops to avoid loss in precision
int64_t waitTicks = (ticksPerSec * waitTime) / USECS_PER_SECOND;
int64_t sleepTicks = now.QuadPart + waitTicks;
// Busy wait with sleep/yield where possible
while (true) {
QueryPerformanceCounter(&now);
if (now.QuadPart >= sleepTicks) {
break;
}
// Sleep if we have at least 1ms to spare
const int64_t MIN_SLEEP_USECS = 1000;
// msleep is allowed to overshoot, so give it a 100us berth
const int64_t MIN_SLEEP_USECS_BERTH = 100;
// order ops to avoid loss in precision
int64_t sleepFor = ((sleepTicks - now.QuadPart) * USECS_PER_SECOND) / ticksPerSec - MIN_SLEEP_USECS_BERTH;
if (sleepFor > MIN_SLEEP_USECS) {
Sleep((DWORD)(sleepFor / USECS_PER_MSEC));
// Yield otherwise
} else {
// Use Qt to delegate, as SwitchToThread is only supported starting with XP
QThread::yieldCurrentThread();
}
}
}
#endif
// Inserts the value and key into three arrays sorted by the key array, the first array is the value,

View file

@ -8,10 +8,12 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
Script.load("system/away.js");
Script.load("system/progress.js");
Script.load("system/edit.js");
Script.load("system/away.js");
Script.load("system/users.js");
Script.load("system/examples.js");
Script.load("system/edit.js");
Script.load("system/selectAudioDevice.js");
Script.load("system/notifications.js");
Script.load("system/controllers/handControllerGrab.js");

View file

@ -222,7 +222,7 @@ var usersWindow = (function() {
var baseURL = Script.resolvePath("assets/images/tools/");
var WINDOW_WIDTH = 160,
var WINDOW_WIDTH = 260,
WINDOW_MARGIN = 12,
WINDOW_BASE_MARGIN = 6, // A little less is needed in order look correct
WINDOW_FONT = {