diff --git a/assignment-client/src/AssignmentClient.cpp b/assignment-client/src/AssignmentClient.cpp index f7594e97f2..3e3c7c0609 100644 --- a/assignment-client/src/AssignmentClient.cpp +++ b/assignment-client/src/AssignmentClient.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -36,13 +37,19 @@ int hifiSockAddrMeta = qRegisterMetaType("HifiSockAddr"); AssignmentClient::AssignmentClient(int &argc, char **argv) : QCoreApplication(argc, argv), - _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME) + _assignmentServerHostname(DEFAULT_ASSIGNMENT_SERVER_HOSTNAME), + _shutdownEventListener(this) { + LogUtils::init(); + setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("assignment-client"); QSettings::setDefaultFormat(QSettings::IniFormat); + installNativeEventFilter(&_shutdownEventListener); + connect(&_shutdownEventListener, SIGNAL(receivedCloseEvent()), SLOT(quit())); + // set the logging target to the the CHILD_TARGET_NAME Logging::setTargetName(ASSIGNMENT_CLIENT_TARGET_NAME); diff --git a/assignment-client/src/AssignmentClient.h b/assignment-client/src/AssignmentClient.h index 9834402dbf..7628aa0a3b 100644 --- a/assignment-client/src/AssignmentClient.h +++ b/assignment-client/src/AssignmentClient.h @@ -14,6 +14,7 @@ #include +#include "ShutdownEventListener.h" #include "ThreadedAssignment.h" class AssignmentClient : public QCoreApplication { @@ -21,6 +22,7 @@ class AssignmentClient : public QCoreApplication { public: AssignmentClient(int &argc, char **argv); static const SharedAssignmentPointer& getCurrentAssignment() { return _currentAssignment; } + private slots: void sendAssignmentRequest(); void readPendingDatagrams(); @@ -30,6 +32,7 @@ private slots: private: Assignment _requestAssignment; static SharedAssignmentPointer _currentAssignment; + ShutdownEventListener _shutdownEventListener; QString _assignmentServerHostname; }; diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 2cd8150e63..56570a4b82 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -31,6 +32,7 @@ DomainServer::DomainServer(int argc, char* argv[]) : QCoreApplication(argc, argv), + _shutdownEventListener(this), _httpManager(DOMAIN_SERVER_HTTP_PORT, QString("%1/resources/web/").arg(QCoreApplication::applicationDirPath()), this), _httpsManager(NULL), _allAssignments(), @@ -46,10 +48,16 @@ DomainServer::DomainServer(int argc, char* argv[]) : _cookieSessionHash(), _settingsManager() { + + LogUtils::init(); + setOrganizationName("High Fidelity"); setOrganizationDomain("highfidelity.io"); setApplicationName("domain-server"); QSettings::setDefaultFormat(QSettings::IniFormat); + + installNativeEventFilter(&_shutdownEventListener); + connect(&_shutdownEventListener, SIGNAL(receivedCloseEvent()), SLOT(quit())); qRegisterMetaType("DomainServerWebSessionData"); qRegisterMetaTypeStreamOperators("DomainServerWebSessionData"); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 666994c818..10633cc71a 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -26,6 +27,7 @@ #include "DomainServerSettingsManager.h" #include "DomainServerWebSessionData.h" +#include "ShutdownEventListener.h" #include "WalletTransaction.h" #include "PendingAssignedNodeData.h" @@ -97,6 +99,8 @@ private: QJsonObject jsonForSocket(const HifiSockAddr& socket); QJsonObject jsonObjectForNode(const SharedNodePointer& node); + + ShutdownEventListener _shutdownEventListener; HTTPManager _httpManager; HTTPSManager* _httpsManager; diff --git a/examples/animatedModelExample.js b/examples/animatedModelExample.js index 9a4bdb3ea7..3fffdc88d2 100644 --- a/examples/animatedModelExample.js +++ b/examples/animatedModelExample.js @@ -21,6 +21,7 @@ var roll = 0.0; var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll) var originalProperties = { + type: "Model", position: { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z }, @@ -37,8 +38,8 @@ var originalProperties = { animationIsPlaying: true, }; -var modelID = Models.addModel(originalProperties); -print("Models.addModel()... modelID.creatorTokenID = " + modelID.creatorTokenID); +var modelID = Entities.addEntity(originalProperties); +print("Entities.addEntity()... modelID.creatorTokenID = " + modelID.creatorTokenID); var isPlaying = true; var playPauseEveryWhile = 360; @@ -48,6 +49,7 @@ var resetFrameEveryWhile = 600; function moveModel(deltaTime) { var somethingChanged = false; + print("count= " + count); if (count % playPauseEveryWhile == 0) { isPlaying = !isPlaying; print("isPlaying=" + isPlaying); @@ -56,11 +58,11 @@ function moveModel(deltaTime) { if (count % adjustFPSEveryWhile == 0) { if (animationFPS == 30) { - animationFPS = 30; - } else if (animationFPS == 10) { animationFPS = 10; - } else if (animationFPS == 60) { + } else if (animationFPS == 10) { animationFPS = 60; + } else if (animationFPS == 60) { + animationFPS = 30; } print("animationFPS=" + animationFPS); isPlaying = true; @@ -78,7 +80,7 @@ function moveModel(deltaTime) { // delete it... if (count == moveUntil) { print("calling Models.deleteModel()"); - Models.deleteModel(modelID); + Entities.deleteEntity(modelID); } // stop it... @@ -107,7 +109,7 @@ function moveModel(deltaTime) { resetFrame = false; } - Models.editModel(modelID, newProperties); + Entities.editEntity(modelID, newProperties); } } diff --git a/examples/editModels.js b/examples/editModels.js index 8d0cf7e71c..fc9c8617ef 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -2828,7 +2828,7 @@ function handeMenuEvent(menuItem) { array.push({ label: "Lifetime:", value: properties.lifetime.toFixed(decimals) }); - if (properties.type == "Box") { + if (properties.type == "Box" || properties.type == "Sphere") { array.push({ label: "Red:", value: properties.color.red }); array.push({ label: "Green:", value: properties.color.green }); array.push({ label: "Blue:", value: properties.color.blue }); diff --git a/examples/entitiesButterflyFlock.js b/examples/entitiesButterflyFlock.js new file mode 100644 index 0000000000..a715c33c59 --- /dev/null +++ b/examples/entitiesButterflyFlock.js @@ -0,0 +1,230 @@ +// +// butterflyFlockTest1.js +// +// +// Created by Adrian McCarlie on August 2, 2014 +// Modified by Brad Hefta-Gaub to use Entities on Sept. 3, 2014 +// Copyright 2014 High Fidelity, Inc. +// +// This sample script creates a swarm of butterfly entities that fly around the avatar. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +function getRandomFloat(min, max) { + return Math.random() * (max - min) + min; +} + +// Multiply vector by scalar +function vScalarMult(v, s) { + var rval = { x: v.x * s, y: v.y * s, z: v.z * s }; + return rval; +} + +function printVector(v) { + print(v.x + ", " + v.y + ", " + v.z + "\n"); +} +// Create a random vector with individual lengths between a,b +function randVector(a, b) { + var rval = { x: a + Math.random() * (b - a), y: a + Math.random() * (b - a), z: a + Math.random() * (b - a) }; + return rval; +} + +// Returns a vector which is fraction of the way between a and b +function vInterpolate(a, b, fraction) { + var rval = { x: a.x + (b.x - a.x) * fraction, y: a.y + (b.y - a.y) * fraction, z: a.z + (b.z - a.z) * fraction }; + return rval; +} + +var startTimeInSeconds = new Date().getTime() / 1000; + +var lifeTime = 60; // lifetime of the butterflies in seconds! +var range = 1.0; // Over what distance in meters do you want the flock to fly around +var frame = 0; + +var CHANCE_OF_MOVING = 0.9; +var BUTTERFLY_GRAVITY = 0;//-0.06; +var BUTTERFLY_FLAP_SPEED = 1.0; +var BUTTERFLY_VELOCITY = 0.55; +var myPosition = MyAvatar.position; + +var pitch = 0.0;//experimental +var yaw = 0.0;//experimental +var roll = 0.0; //experimental +var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll);//experimental + +// This is our butterfly object +function defineButterfly(entityID, targetPosition) { + this.entityID = entityID; + this.previousFlapOffset = 0; + this.targetPosition = targetPosition; + this.moving = false; +} + +// Array of butterflies +var butterflies = []; +var numButterflies = 20; +function addButterfly() { + // Decide the size of butterfly + var color = { red: 100, green: 100, blue: 100 }; + var size = 0; + + var which = Math.random(); + if (which < 0.2) { + size = 0.08; + } else if (which < 0.4) { + size = 0.09; + } else if (which < 0.6) { + size = 0.8; + } else if (which < 0.8) { + size = 0.8; + } else { + size = 0.8; + } + + myPosition = MyAvatar.position; + // if ( frame < numButterflies){ + // myPosition = {x: myPosition.x, y: myPosition.y, z: myPosition.z }; + // } + + var properties = { + type: "Model", + lifetime: lifeTime, + position: Vec3.sum(randVector(-range, range), myPosition), + velocity: { x: 0, y: 0.0, z: 0 }, + gravity: { x: 0, y: 1.0, z: 0 }, + damping: 0.1, + radius : size, + color: color, + rotation: rotation, + //animationURL: "http://business.ozblog.me/objects/butterfly/newButterfly6.fbx", + //animationIsPlaying: true, + modelURL: "http://business.ozblog.me/objects/butterfly/newButterfly6.fbx" + }; + properties.position.z = properties.position.z+1; + butterflies.push(new defineButterfly(Entities.addEntity(properties), properties.position)); +} + +// Generate the butterflies +for (var i = 0; i < numButterflies; i++) { + addButterfly(); +} + +// Main update function +function updateButterflies(deltaTime) { + // Check to see if we've been running long enough that our butterflies are dead + var nowTimeInSeconds = new Date().getTime() / 1000; + if ((nowTimeInSeconds - startTimeInSeconds) >= lifeTime) { + // print("our butterflies are dying, stop our script"); + Script.stop(); + return; + } + + frame++; + // Only update every third frame + if ((frame % 3) == 0) { + myPosition = MyAvatar.position; + + // Update all the butterflies + for (var i = 0; i < numButterflies; i++) { + entityID = butterflies[i].entityID; + var properties = Entities.getEntityProperties(entityID); + + if (properties.position.y > myPosition.y + getRandomFloat(0.0,0.3)){ //0.3 //ceiling + properties.gravity.y = - 3.0; + properties.damping.y = 1.0; + properties.velocity.y = 0; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + if (properties.velocity.x < 0.5){ + butterflies[i].moving = false; + } + if (properties.velocity.z < 0.5){ + butterflies[i].moving = false; + } + } + + if (properties.velocity.y <= -0.2) { + properties.velocity.y = 0.22; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + } + + if (properties.position.y < myPosition.y - getRandomFloat(0.0,0.3)) { //-0.3 // floor + properties.velocity.y = 0.9; + properties.gravity.y = - 4.0; + properties.velocity.x = properties.velocity.x; + properties.velocity.z = properties.velocity.z; + if (properties.velocity.x < 0.5){ + butterflies[i].moving = false; + } + if (properties.velocity.z < 0.5){ + butterflies[i].moving = false; + } + } + + + // Begin movement by getting a target + if (butterflies[i].moving == false) { + if (Math.random() < CHANCE_OF_MOVING) { + var targetPosition = Vec3.sum(randVector(-range, range), myPosition); + if (targetPosition.x < 0) { + targetPosition.x = 0; + } + if (targetPosition.y < 0) { + targetPosition.y = 0; + } + if (targetPosition.z < 0) { + targetPosition.z = 0; + } + if (targetPosition.x > TREE_SCALE) { + targetPosition.x = TREE_SCALE; + } + if (targetPosition.y > TREE_SCALE) { + targetPosition.y = TREE_SCALE; + } + if (targetPosition.z > TREE_SCALE) { + targetPosition.z = TREE_SCALE; + } + butterflies[i].targetPosition = targetPosition; + butterflies[i].moving = true; + } + } + + // If we are moving, move towards the target + if (butterflies[i].moving) { + + var holding = properties.velocity.y; + + var desiredVelocity = Vec3.subtract(butterflies[i].targetPosition, properties.position); + desiredVelocity = vScalarMult(Vec3.normalize(desiredVelocity), BUTTERFLY_VELOCITY); + + properties.velocity = vInterpolate(properties.velocity, desiredVelocity, 0.2); + properties.velocity.y = holding ; + + + // If we are near the target, we should get a new target + if (Vec3.length(Vec3.subtract(properties.position, butterflies[i].targetPosition)) < (properties.radius / 1.0)) { + butterflies[i].moving = false; + } + + var yawRads = Math.atan2(properties.velocity.z, properties.velocity.x); + yawRads = yawRads + Math.PI / 2.0; + var newOrientation = Quat.fromPitchYawRollRadians(0.0, yawRads, 0.0); + properties.rotation = newOrientation; + } + + // Use a cosine wave offset to make it look like its flapping. + var offset = Math.cos(nowTimeInSeconds * BUTTERFLY_FLAP_SPEED) * (properties.radius); + properties.position.y = properties.position.y + (offset - butterflies[i].previousFlapOffset); + // Change position relative to previous offset. + butterflies[i].previousFlapOffset = offset; + Entities.editEntity(entityID, properties); + } + } +} + +// register the call back so it fires before each data send +Script.update.connect(updateButterflies); \ No newline at end of file diff --git a/examples/inspect.js b/examples/inspect.js index a4ff405c3f..b9ed5a3f00 100644 --- a/examples/inspect.js +++ b/examples/inspect.js @@ -205,7 +205,7 @@ function mousePressEvent(event) { // Compute trajectories related values var pickRay = Camera.computePickRay(mouseLastX, mouseLastY); var voxelIntersection = Voxels.findRayIntersection(pickRay); - var modelIntersection = Models.findRayIntersection(pickRay); + var modelIntersection = Entities.findRayIntersection(pickRay); position = Camera.getPosition(); @@ -218,7 +218,7 @@ function mousePressEvent(event) { if (modelIntersection.intersects && modelIntersection.accurate) { distance = modelIntersection.distance; - center = modelIntersection.modelProperties.position; + center = modelIntersection.properties.position; string = "Inspecting model"; } diff --git a/examples/rayPickExample.js b/examples/rayPickExample.js index 336fbe2162..c3b6581007 100644 --- a/examples/rayPickExample.js +++ b/examples/rayPickExample.js @@ -42,16 +42,16 @@ function mouseMoveEvent(event) { print("voxelAt.red/green/blue=" + voxelAt.red + ", " + voxelAt.green + ", " + voxelAt.blue); } - intersection = Models.findRayIntersection(pickRay); + intersection = Entities.findRayIntersection(pickRay); if (!intersection.accurate) { - print(">>> NOTE: intersection not accurate. will try calling Models.findRayIntersectionBlocking()"); - intersection = Models.findRayIntersectionBlocking(pickRay); + print(">>> NOTE: intersection not accurate. will try calling Entities.findRayIntersectionBlocking()"); + intersection = Entities.findRayIntersectionBlocking(pickRay); print(">>> AFTER BLOCKING CALL intersection.accurate=" + intersection.accurate); } if (intersection.intersects) { - print("intersection modelID.id=" + intersection.modelID.id); - print("intersection modelProperties.modelURL=" + intersection.modelProperties.modelURL); + print("intersection entityID.id=" + intersection.entityID.id); + print("intersection properties.modelURL=" + intersection.properties.modelURL); print("intersection face=" + intersection.face); print("intersection distance=" + intersection.distance); print("intersection intersection.x/y/z=" + intersection.intersection.x + ", " diff --git a/examples/twoFallingEntities.js b/examples/twoFallingEntities.js new file mode 100644 index 0000000000..0d157b70c3 --- /dev/null +++ b/examples/twoFallingEntities.js @@ -0,0 +1,25 @@ +// +// twoFallingEntities.js +// +// Creates a red 0.2 meter diameter ball right in front of your avatar that lives for 60 seconds +// + +var radius = 0.1; +var position = Vec3.sum(MyAvatar.position, Quat.getFront(MyAvatar.orientation)); +var properties = { + type: "Sphere", + position: position, + velocity: { x: 0, y: 0, z: 0}, + gravity: { x: 0, y: -0.05, z: 0}, + radius: radius, + damping: 0.999, + color: { red: 200, green: 0, blue: 0 }, + lifetime: 60 + }; + +var newEntity = Entities.addEntity(properties); +position.x -= radius * 1.0; +properties.position = position; +var newEntityTwo = Entities.addEntity(properties); + +Script.stop(); // no need to run anymore \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index d0a59863a1..711b3cb3a4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3856,14 +3856,17 @@ void Application::manageRunningScriptsWidgetVisibility(bool shown) { } void Application::toggleRunningScriptsWidget() { - if (_runningScriptsWidgetWasVisible) { - _runningScriptsWidget->hide(); - _runningScriptsWidgetWasVisible = false; + if (_runningScriptsWidget->isVisible()) { + if (_runningScriptsWidget->hasFocus()) { + _runningScriptsWidget->hide(); + } else { + _runningScriptsWidget->raise(); + setActiveWindow(_runningScriptsWidget); + _runningScriptsWidget->setFocus(); + } } else { - _runningScriptsWidget->setBoundary(QRect(_window->geometry().topLeft(), - _window->size())); _runningScriptsWidget->show(); - _runningScriptsWidgetWasVisible = true; + _runningScriptsWidget->setFocus(); } } diff --git a/interface/src/ui/RunningScriptsWidget.cpp b/interface/src/ui/RunningScriptsWidget.cpp index 5bcb1a85de..7a46873129 100644 --- a/interface/src/ui/RunningScriptsWidget.cpp +++ b/interface/src/ui/RunningScriptsWidget.cpp @@ -22,9 +22,11 @@ #include "Application.h" #include "Menu.h" #include "ScriptsModel.h" +#include "UIUtil.h" RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : - FramelessDialog(parent, 0, POSITION_LEFT), + QWidget(parent, Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint | + Qt::WindowCloseButtonHint), ui(new Ui::RunningScriptsWidget), _signalMapper(this), _proxyModel(this), @@ -33,15 +35,6 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : setAttribute(Qt::WA_DeleteOnClose, false); - setAllowResize(false); - - ui->hideWidgetButton->setIcon(QIcon(Application::resourcesPath() + "images/close.svg")); - ui->reloadAllButton->setIcon(QIcon(Application::resourcesPath() + "images/reload.svg")); - ui->stopAllButton->setIcon(QIcon(Application::resourcesPath() + "images/stop.svg")); - ui->loadScriptButton->setIcon(QIcon(Application::resourcesPath() + "images/plus-white.svg")); - - ui->recentlyLoadedScriptsArea->hide(); - ui->filterLineEdit->installEventFilter(this); connect(&_proxyModel, &QSortFilterProxyModel::modelReset, @@ -55,12 +48,6 @@ RunningScriptsWidget::RunningScriptsWidget(QWidget* parent) : connect(ui->filterLineEdit, &QLineEdit::textChanged, this, &RunningScriptsWidget::updateFileFilter); connect(ui->scriptListView, &QListView::doubleClicked, this, &RunningScriptsWidget::loadScriptFromList); - _recentlyLoadedScriptsTable = new ScriptsTableWidget(ui->recentlyLoadedScriptsTableWidget); - _recentlyLoadedScriptsTable->setColumnCount(1); - _recentlyLoadedScriptsTable->setColumnWidth(0, 265); - - connect(ui->hideWidgetButton, &QPushButton::clicked, - Application::getInstance(), &Application::toggleRunningScriptsWidget); connect(ui->reloadAllButton, &QPushButton::clicked, Application::getInstance(), &Application::reloadAllScripts); connect(ui->stopAllButton, &QPushButton::clicked, @@ -163,7 +150,15 @@ void RunningScriptsWidget::showEvent(QShowEvent* event) { ui->filterLineEdit->setFocus(); } - FramelessDialog::showEvent(event); + const QRect parentGeometry = parentWidget()->geometry(); + int titleBarHeight = UIUtil::getWindowTitleBarHeight(this); + int menuBarHeight = Menu::getInstance()->geometry().height(); + int topMargin = titleBarHeight + menuBarHeight; + + setGeometry(parentGeometry.topLeft().x(), parentGeometry.topLeft().y() + topMargin, + size().width(), parentWidget()->height() - topMargin); + + QWidget::showEvent(event); } void RunningScriptsWidget::selectFirstInList() { @@ -189,19 +184,18 @@ bool RunningScriptsWidget::eventFilter(QObject* sender, QEvent* event) { return false; } - return FramelessDialog::eventFilter(sender, event); + return QWidget::eventFilter(sender, event); } void RunningScriptsWidget::keyPressEvent(QKeyEvent *keyEvent) { if (keyEvent->key() == Qt::Key_Escape) { return; } else { - FramelessDialog::keyPressEvent(keyEvent); + QWidget::keyPressEvent(keyEvent); } } void RunningScriptsWidget::scriptStopped(const QString& scriptName) { - // _recentlyLoadedScripts.prepend(scriptName); } void RunningScriptsWidget::allScriptsStopped() { diff --git a/interface/src/ui/RunningScriptsWidget.h b/interface/src/ui/RunningScriptsWidget.h index 6810aca487..7493a1a5ce 100644 --- a/interface/src/ui/RunningScriptsWidget.h +++ b/interface/src/ui/RunningScriptsWidget.h @@ -25,8 +25,7 @@ namespace Ui { class RunningScriptsWidget; } -class RunningScriptsWidget : public FramelessDialog -{ +class RunningScriptsWidget : public QWidget { Q_OBJECT public: explicit RunningScriptsWidget(QWidget* parent = NULL); diff --git a/interface/ui/runningScriptsWidget.ui b/interface/ui/runningScriptsWidget.ui index b58c8436d0..ddc6ad6c27 100644 --- a/interface/ui/runningScriptsWidget.ui +++ b/interface/ui/runningScriptsWidget.ui @@ -7,29 +7,24 @@ 0 0 324 - 971 + 643 - Form + Running Scripts - * { - font-family: Helvetica, Arial, sans-serif; -} -QWidget { - background: #f7f7f7; -} + * { font-family: Helvetica, Arial, sans-serif; } - 20 + 14 20 - 20 + 14 20 @@ -38,23 +33,22 @@ QWidget { - 0 + 6 0 - 0 + 6 color: #0e7077; -font-size: 20px; -background: transparent; +font-size: 20px; - <html><head/><body><p><span style=" font-size:18px;">Running Scripts</span></p></body></html> + Running Scripts 0 @@ -77,28 +71,6 @@ background: transparent; - - - - PointingHandCursor - - - border: 0 - - - - - - - 16 - 16 - - - - true - - - @@ -133,24 +105,45 @@ background: transparent; 0 - - - - Helvetica,Arial,sans-serif - -1 - 75 - false - true - - - - color: #0e7077; + + + + 0 + + + 6 + + + 0 + + + 6 + + + 0 + + + + + + Helvetica,Arial,sans-serif + -1 + 75 + false + true + + + + color: #0e7077; font: bold 16px; -background: transparent; - - - <html><head/><body><p><span style=" font-weight:600;">Currently running</span></p></body></html> - + + + + Currently Running + + + + @@ -177,49 +170,24 @@ background: transparent; 0 + + reloadStopButtonArea { padding: 0 } + - - 24 - - 0 + 6 0 - 0 + 6 0 - - - 0 - 0 - - - - - 111 - 35 - - - - PointingHandCursor - - - false - - - background: #0e7077; -color: #fff; -border-radius: 4px; -font: bold 14px; -padding-top: 3px; - Reload all @@ -227,28 +195,6 @@ padding-top: 3px; - - - 0 - 0 - - - - - 111 - 35 - - - - PointingHandCursor - - - background: #0e7077; -color: #fff; -border-radius: 4px; -font: bold 14px; -padding-top: 3px; - Stop all @@ -261,8 +207,8 @@ padding-top: 3px; - 40 - 20 + 0 + 0 @@ -271,192 +217,104 @@ padding-top: 3px; - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 8 - - - - - - - - font: 14px; - - - There are no scripts currently running. - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 10 - - - - - - - - - Helvetica,Arial,sans-serif - 14 - - - - Qt::LeftToRight - - - QFrame::NoFrame - - - 0 - - - Qt::ScrollBarAsNeeded - - - Qt::ScrollBarAlwaysOff - - - true - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - 0 - 0 - 284 - 16 - + + + + 0 - - - 0 - 0 - + + 6 - - font-size: 14px; + + 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - true - - - - 0 - 100 - - - - - 16777215 - 16777215 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - 0 - - - - - color: #0e7077; -font: bold 16px; - - - <html><head/><body><p><span style=" font-weight:600;">Recently loaded</span></p></body></html> - - - - - - - font: 14px; - - - There are no recently loaded scripts. - - - - - - - - 0 - 1 - - - - - 284 - 0 - - - - background: transparent; -font-size: 14px; - + + 6 + + + 0 + + + + + + Helvetica,Arial,sans-serif + 14 + + + + Qt::LeftToRight + + + QFrame::NoFrame + + + 0 + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + true + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + + + 0 + 0 + 284 + 16 + + + + + 0 + 0 + + + + font-size: 14px; + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + font: 14px; + + + There are no scripts currently running. + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + @@ -476,9 +334,6 @@ font-size: 14px; 300 - - - 0 @@ -502,16 +357,16 @@ font-size: 14px; 0 - 0 + 6 - 0 + 6 - 0 + 6 - 15 + 6 @@ -539,28 +394,6 @@ font: bold 16px; - - - 0 - 0 - - - - - 111 - 35 - - - - PointingHandCursor - - - background: #0e7077; -color: #fff; -border-radius: 4px; -font: bold 14px; -padding-top: 3px; - Load script @@ -570,64 +403,44 @@ padding-top: 3px; - - - border: 1px solid rgb(128, 128, 128); -border-radius: 2px; -padding: 4px; -background-color: white; - - - - - - filter - - - true - - - - - - - Qt::Vertical - - - QSizePolicy::Fixed - - - - 20 - 6 - - - - - - - - QListView { - border: 1px solid rgb(128, 128, 128); - border-radius: 2px; -} -QListView::item { - padding-top: 2px; - padding-bottom: 2px; -} - - - QFrame::Box - - - QFrame::Plain - - - Qt::ScrollBarAlwaysOn - - - Qt::ScrollBarAlwaysOff - + + + + 6 + + + 0 + + + 6 + + + 0 + + + + + + + + filter + + + true + + + + + + + Qt::ScrollBarAlwaysOn + + + Qt::ScrollBarAlwaysOff + + + + diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index a7ed908a63..971d7066eb 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -1,6 +1,6 @@ // // EntityScriptingInterface.cpp -// libraries/models/src +// libraries/entities/src // // Created by Brad Hefta-Gaub on 12/6/13. // Copyright 2013 High Fidelity, Inc. @@ -19,7 +19,6 @@ EntityScriptingInterface::EntityScriptingInterface() : { } - void EntityScriptingInterface::queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties) { getEntityPacketSender()->queueEditEntityMessage(packetType, entityID, properties); @@ -35,7 +34,7 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro // queue the packet queueEntityMessage(PacketTypeEntityAddOrEdit, id, properties); - // If we have a local model tree set, then also update it. + // If we have a local entity tree set, then also update it. if (_entityTree) { _entityTree->lockForWrite(); _entityTree->addEntity(id, properties); @@ -93,20 +92,20 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(EntityItemID EntityItemID EntityScriptingInterface::editEntity(EntityItemID entityID, const EntityItemProperties& properties) { EntityItemID actualID = entityID; - // if the model is unknown, attempt to look it up + // if the entity is unknown, attempt to look it up if (!entityID.isKnownID) { actualID = EntityItemID::getIDfromCreatorTokenID(entityID.creatorTokenID); } - // if at this point, we know the id, send the update to the model server + // if at this point, we know the id, send the update to the entity server if (actualID.id != UNKNOWN_ENTITY_ID) { entityID.id = actualID.id; entityID.isKnownID = true; queueEntityMessage(PacketTypeEntityAddOrEdit, entityID, properties); } - // If we have a local model tree set, then also update it. We can do this even if we don't know - // the actual id, because we can edit out local models just with creatorTokenID + // If we have a local entity tree set, then also update it. We can do this even if we don't know + // the actual id, because we can edit out local entities just with creatorTokenID if (_entityTree) { _entityTree->lockForWrite(); _entityTree->updateEntity(entityID, properties); @@ -119,19 +118,19 @@ void EntityScriptingInterface::deleteEntity(EntityItemID entityID) { EntityItemID actualID = entityID; - // if the model is unknown, attempt to look it up + // if the entity is unknown, attempt to look it up if (!entityID.isKnownID) { actualID = EntityItemID::getIDfromCreatorTokenID(entityID.creatorTokenID); } - // if at this point, we know the id, send the update to the model server + // if at this point, we know the id, send the update to the entity server if (actualID.id != UNKNOWN_ENTITY_ID) { entityID.id = actualID.id; entityID.isKnownID = true; getEntityPacketSender()->queueEraseEntityMessage(entityID); } - // If we have a local model tree set, then also update it. + // If we have a local entity tree set, then also update it. if (_entityTree) { _entityTree->lockForWrite(); _entityTree->deleteEntity(entityID); @@ -167,12 +166,12 @@ QVector EntityScriptingInterface::findEntities(const glm::vec3& ce QVector result; if (_entityTree) { _entityTree->lockForRead(); - QVector models; - _entityTree->findEntities(center/(float)TREE_SCALE, radius/(float)TREE_SCALE, models); + QVector entities; + _entityTree->findEntities(center/(float)TREE_SCALE, radius/(float)TREE_SCALE, entities); _entityTree->unlock(); - foreach (const EntityItem* model, models) { - EntityItemID thisEntityItemID(model->getID(), UNKNOWN_ENTITY_TOKEN, true); + foreach (const EntityItem* entity, entities) { + EntityItemID thisEntityItemID(entity->getID(), UNKNOWN_ENTITY_TOKEN, true); result << thisEntityItemID; } } @@ -219,11 +218,11 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c QScriptValue obj = engine->newObject(); obj.setProperty("intersects", value.intersects); obj.setProperty("accurate", value.accurate); - QScriptValue modelItemValue = EntityItemIDtoScriptValue(engine, value.entityID); - obj.setProperty("entityID", modelItemValue); + QScriptValue entityItemValue = EntityItemIDtoScriptValue(engine, value.entityID); + obj.setProperty("entityID", entityItemValue); - QScriptValue modelPropertiesValue = EntityItemPropertiesToScriptValue(engine, value.properties); - obj.setProperty("properties", modelPropertiesValue); + QScriptValue propertiesValue = EntityItemPropertiesToScriptValue(engine, value.properties); + obj.setProperty("properties", propertiesValue); obj.setProperty("distance", value.distance); @@ -262,13 +261,13 @@ QScriptValue RayToEntityIntersectionResultToScriptValue(QScriptEngine* engine, c void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, RayToEntityIntersectionResult& value) { value.intersects = object.property("intersects").toVariant().toBool(); value.accurate = object.property("accurate").toVariant().toBool(); - QScriptValue modelIDValue = object.property("entityID"); - if (modelIDValue.isValid()) { - EntityItemIDfromScriptValue(modelIDValue, value.entityID); + QScriptValue entityIDValue = object.property("entityID"); + if (entityIDValue.isValid()) { + EntityItemIDfromScriptValue(entityIDValue, value.entityID); } - QScriptValue modelPropertiesValue = object.property("properties"); - if (modelPropertiesValue.isValid()) { - EntityItemPropertiesFromScriptValue(modelPropertiesValue, value.properties); + QScriptValue entityPropertiesValue = object.property("properties"); + if (entityPropertiesValue.isValid()) { + EntityItemPropertiesFromScriptValue(entityPropertiesValue, value.properties); } value.distance = object.property("distance").toVariant().toFloat(); diff --git a/libraries/entities/src/UpdateEntityOperator.cpp b/libraries/entities/src/UpdateEntityOperator.cpp index 157e68aa70..65a86a80ca 100644 --- a/libraries/entities/src/UpdateEntityOperator.cpp +++ b/libraries/entities/src/UpdateEntityOperator.cpp @@ -175,7 +175,16 @@ bool UpdateEntityOperator::preRecursion(OctreeElement* element) { // if we are the existing containing element, then we can just do the update of the entity properties if (entityTreeElement == _containingElement) { - assert(!_removeOld); // We shouldn't be in a remove old case and also be the new best fit + + // TODO: We shouldn't be in a remove old case and also be the new best fit. This indicates that + // we have some kind of a logic error in this operator. But, it can handle it properly by setting + // the new properties for the entity and moving on. Still going to output a warning that if we + // see consistently we will want to address this. + if (_removeOld) { + qDebug() << "UNEXPECTED - UpdateEntityOperator - " + "we thought we needed to removeOld, but the old entity is our best fit."; + _removeOld = false; + } // set the entity properties and mark our element as changed. _existingEntity->setProperties(_properties); diff --git a/libraries/shared/src/LogUtils.cpp b/libraries/shared/src/LogUtils.cpp new file mode 100644 index 0000000000..c38f5c8574 --- /dev/null +++ b/libraries/shared/src/LogUtils.cpp @@ -0,0 +1,24 @@ +// +// LogUtils.cpp +// libraries/shared/src +// +// Created by Ryan Huffman on 09/03/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "LogUtils.h" + +void LogUtils::init() { +#ifdef Q_OS_WIN + // Windows applications buffer stdout/err hard when not run from a terminal, + // making assignment clients run from the Stack Manager application not flush + // log messages. + // This will disable the buffering. If this becomes a performance issue, + // an alternative is to call fflush(...) periodically. + setbuf(stdout, NULL); + setbuf(stderr, NULL); +#endif +} diff --git a/libraries/shared/src/LogUtils.h b/libraries/shared/src/LogUtils.h new file mode 100644 index 0000000000..955c33d338 --- /dev/null +++ b/libraries/shared/src/LogUtils.h @@ -0,0 +1,20 @@ +// +// LogUtils.h +// libraries/shared/src +// +// Created by Ryan Huffman on 09/03/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_LogUtils_h +#define hifi_LogUtils_h + +class LogUtils { +public: + static void init(); +}; + +#endif // hifi_LogUtils_h diff --git a/libraries/shared/src/ShutdownEventListener.cpp b/libraries/shared/src/ShutdownEventListener.cpp new file mode 100644 index 0000000000..961d18e793 --- /dev/null +++ b/libraries/shared/src/ShutdownEventListener.cpp @@ -0,0 +1,31 @@ +// +// ShutdownEventListener.cpp +// libraries/shared/src +// +// Created by Ryan Huffman on 09/03/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "ShutdownEventListener.h" + +#ifdef Q_OS_WIN +#include +#endif + +ShutdownEventListener::ShutdownEventListener(QObject* parent) : QObject(parent) { +} + +bool ShutdownEventListener::nativeEventFilter(const QByteArray &eventType, void* msg, long* result) { +#ifdef Q_OS_WIN + if (eventType == "windows_generic_MSG") { + MSG* message = (MSG*)msg; + if (message->message == WM_CLOSE) { + emit receivedCloseEvent(); + } + } +#endif + return true; +} diff --git a/libraries/shared/src/ShutdownEventListener.h b/libraries/shared/src/ShutdownEventListener.h new file mode 100644 index 0000000000..e39770c13d --- /dev/null +++ b/libraries/shared/src/ShutdownEventListener.h @@ -0,0 +1,29 @@ +// +// ShutdownEventListener.h +// libraries/shared/src +// +// Created by Ryan Huffman on 09/03/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_ShutdownEventListener_h +#define hifi_ShutdownEventListener_h + +#include +#include + +class ShutdownEventListener : public QObject, public QAbstractNativeEventFilter { + Q_OBJECT +public: + ShutdownEventListener(QObject* parent = NULL); + + virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result); + +signals: + void receivedCloseEvent(); +}; + +#endif // hifi_ShutdownEventListener_h diff --git a/libraries/shared/src/UIUtil.cpp b/libraries/shared/src/UIUtil.cpp new file mode 100644 index 0000000000..db9dde2f00 --- /dev/null +++ b/libraries/shared/src/UIUtil.cpp @@ -0,0 +1,29 @@ +// +// UIUtil.cpp +// library/shared/src +// +// Created by Ryan Huffman on 09/02/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include + +#include "UIUtil.h" + +int UIUtil::getWindowTitleBarHeight(const QWidget* window) { + QStyleOptionTitleBar options; + options.titleBarState = 1; + options.titleBarFlags = Qt::Window; + int titleBarHeight = window->style()->pixelMetric(QStyle::PM_TitleBarHeight, &options, window); + +#if defined(Q_OS_MAC) + // The height on OSX is 4 pixels too tall + titleBarHeight -= 4; +#endif + + return titleBarHeight; +} diff --git a/libraries/shared/src/UIUtil.h b/libraries/shared/src/UIUtil.h new file mode 100644 index 0000000000..304e8bfce9 --- /dev/null +++ b/libraries/shared/src/UIUtil.h @@ -0,0 +1,24 @@ +// +// UIUtil.h +// library/shared/src +// +// Created by Ryan Huffman on 09/02/2014. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +#ifndef hifi_UIUtil_h +#define hifi_UIUtil_h + +#include + +class UIUtil { +public: + static int getWindowTitleBarHeight(const QWidget* window); + +}; + +#endif // hifi_UIUtil_h