mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
Merge branch 'master' of github.com:highfidelity/hifi into 67-to-master
This commit is contained in:
commit
f5441c05b3
55 changed files with 779 additions and 217 deletions
3
cmake/externals/quazip/CMakeLists.txt
vendored
3
cmake/externals/quazip/CMakeLists.txt
vendored
|
@ -41,6 +41,9 @@ if (APPLE)
|
|||
elseif (WIN32)
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/quazip5.lib CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/quazip5d.lib CACHE FILEPATH "Location of QuaZip release library")
|
||||
elseif (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5d.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
else ()
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG ${INSTALL_DIR}/lib/libquazip5.so CACHE FILEPATH "Location of QuaZip release library")
|
||||
|
|
|
@ -21,6 +21,7 @@ Item {
|
|||
signal newViewRequestedCallback(var request)
|
||||
signal loadingChangedCallback(var loadRequest)
|
||||
|
||||
|
||||
width: parent.width
|
||||
|
||||
property bool interactive: false
|
||||
|
@ -29,6 +30,10 @@ Item {
|
|||
id: hifi
|
||||
}
|
||||
|
||||
function stop() {
|
||||
webViewCore.stop();
|
||||
}
|
||||
|
||||
function unfocus() {
|
||||
webViewCore.runJavaScript("if (document.activeElement) document.activeElement.blur();", function(result) {
|
||||
console.log('unfocus completed: ', result);
|
||||
|
|
|
@ -21,6 +21,10 @@ Item {
|
|||
property bool passwordField: false
|
||||
property alias flickable: webroot.interactive
|
||||
|
||||
function stop() {
|
||||
webroot.stop();
|
||||
}
|
||||
|
||||
// FIXME - Keyboard HMD only: Make Interface either set keyboardRaised property directly in OffscreenQmlSurface
|
||||
// or provide HMDinfo object to QML in RenderableWebEntityItem and do the following.
|
||||
/*
|
||||
|
|
|
@ -254,7 +254,7 @@ ModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -254,7 +254,7 @@ ModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -282,7 +282,7 @@ TabletModalWindow {
|
|||
text: root.warning;
|
||||
wrapMode: Text.WordWrap;
|
||||
font.italic: true;
|
||||
maximumLineCount: 2;
|
||||
maximumLineCount: 3;
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
|
|
|
@ -124,6 +124,14 @@ Rectangle {
|
|||
root.numUpdatesAvailable = result.data.updates.length;
|
||||
}
|
||||
}
|
||||
|
||||
onAppInstalled: {
|
||||
root.installedApps = Commerce.getInstalledApps();
|
||||
}
|
||||
|
||||
onAppUninstalled: {
|
||||
root.installedApps = Commerce.getInstalledApps();
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
|
@ -249,6 +257,145 @@ Rectangle {
|
|||
Commerce.getWalletStatus();
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: installedAppsContainer;
|
||||
z: 998;
|
||||
visible: false;
|
||||
anchors.top: titleBarContainer.bottom;
|
||||
anchors.topMargin: -titleBarContainer.additionalDropdownHeight;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: parent.bottom;
|
||||
width: parent.width;
|
||||
|
||||
RalewayRegular {
|
||||
id: installedAppsHeader;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 10;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
height: 80;
|
||||
width: paintedWidth;
|
||||
text: "All Installed Marketplace Apps";
|
||||
color: hifi.colors.black;
|
||||
size: 22;
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: installedAppsList;
|
||||
clip: true;
|
||||
model: installedAppsModel;
|
||||
snapMode: ListView.SnapToItem;
|
||||
// Anchors
|
||||
anchors.top: installedAppsHeader.bottom;
|
||||
anchors.left: parent.left;
|
||||
anchors.bottom: sideloadAppButton.top;
|
||||
width: parent.width;
|
||||
delegate: Item {
|
||||
width: parent.width;
|
||||
height: 40;
|
||||
|
||||
RalewayRegular {
|
||||
text: model.appUrl;
|
||||
// Text size
|
||||
size: 16;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 12;
|
||||
height: parent.height;
|
||||
anchors.right: sideloadAppOpenButton.left;
|
||||
anchors.rightMargin: 8;
|
||||
elide: Text.ElideRight;
|
||||
// Style
|
||||
color: hifi.colors.black;
|
||||
// Alignment
|
||||
verticalAlignment: Text.AlignVCenter;
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
onClicked: {
|
||||
Window.copyToClipboard((model.appUrl).slice(0, -9));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiControlsUit.Button {
|
||||
id: sideloadAppOpenButton;
|
||||
text: "OPEN";
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.top: parent.top;
|
||||
anchors.topMargin: 2;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 2;
|
||||
anchors.right: uninstallGlyph.left;
|
||||
anchors.rightMargin: 8;
|
||||
width: 80;
|
||||
onClicked: {
|
||||
Commerce.openApp(model.appUrl);
|
||||
}
|
||||
}
|
||||
|
||||
HiFiGlyphs {
|
||||
id: uninstallGlyph;
|
||||
text: hifi.glyphs.close;
|
||||
color: hifi.colors.black;
|
||||
size: 22;
|
||||
anchors.top: parent.top;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 6;
|
||||
width: 35;
|
||||
height: parent.height;
|
||||
horizontalAlignment: Text.AlignHCenter;
|
||||
MouseArea {
|
||||
anchors.fill: parent;
|
||||
hoverEnabled: true;
|
||||
onEntered: {
|
||||
parent.text = hifi.glyphs.closeInverted;
|
||||
}
|
||||
onExited: {
|
||||
parent.text = hifi.glyphs.close;
|
||||
}
|
||||
onClicked: {
|
||||
Commerce.uninstallApp(model.appUrl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: sideloadAppButton;
|
||||
color: hifi.buttons.blue;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.left: parent.left;
|
||||
anchors.leftMargin: 8;
|
||||
anchors.right: closeAppListButton.left;
|
||||
anchors.rightMargin: 8;
|
||||
height: 40;
|
||||
text: "SIDELOAD APP FROM LOCAL DISK";
|
||||
onClicked: {
|
||||
Window.browseChanged.connect(onFileOpenChanged);
|
||||
Window.browseAsync("Locate your app's .app.json file", "", "*.app.json");
|
||||
}
|
||||
}
|
||||
HifiControlsUit.Button {
|
||||
id: closeAppListButton;
|
||||
color: hifi.buttons.white;
|
||||
colorScheme: hifi.colorSchemes.dark;
|
||||
anchors.bottom: parent.bottom;
|
||||
anchors.bottomMargin: 8;
|
||||
anchors.right: parent.right;
|
||||
anchors.rightMargin: 8;
|
||||
width: 100;
|
||||
height: 40;
|
||||
text: "BACK";
|
||||
onClicked: {
|
||||
installedAppsContainer.visible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HifiWallet.NeedsLogIn {
|
||||
id: needsLogIn;
|
||||
|
@ -317,7 +464,7 @@ Rectangle {
|
|||
//
|
||||
Item {
|
||||
id: purchasesContentsContainer;
|
||||
visible: root.activeView === "purchasesMain";
|
||||
visible: root.activeView === "purchasesMain" && !installedAppsList.visible;
|
||||
// Anchors
|
||||
anchors.left: parent.left;
|
||||
anchors.right: parent.right;
|
||||
|
@ -959,6 +1106,39 @@ Rectangle {
|
|||
}
|
||||
}
|
||||
|
||||
Keys.onPressed: {
|
||||
if ((event.key == Qt.Key_F) && (event.modifiers & Qt.ControlModifier)) {
|
||||
installedAppsContainer.visible = !installedAppsContainer.visible;
|
||||
console.log("User changed visibility of installedAppsContainer to " + installedAppsContainer.visible);
|
||||
}
|
||||
}
|
||||
function onFileOpenChanged(filename) {
|
||||
// disconnect the event, otherwise the requests will stack up
|
||||
try { // Not all calls to onFileOpenChanged() connect an event.
|
||||
Window.browseChanged.disconnect(onFileOpenChanged);
|
||||
} catch (e) {
|
||||
console.log('Purchases.qml ignoring', e);
|
||||
}
|
||||
if (filename) {
|
||||
Commerce.installApp(filename);
|
||||
}
|
||||
}
|
||||
ListModel {
|
||||
id: installedAppsModel;
|
||||
}
|
||||
onInstalledAppsChanged: {
|
||||
installedAppsModel.clear();
|
||||
var installedAppsArray = root.installedApps.split(",");
|
||||
var installedAppsObject = [];
|
||||
// "- 1" because the last app string ends with ","
|
||||
for (var i = 0; i < installedAppsArray.length - 1; i++) {
|
||||
installedAppsObject[i] = {
|
||||
"appUrl": installedAppsArray[i]
|
||||
}
|
||||
}
|
||||
installedAppsModel.append(installedAppsObject);
|
||||
}
|
||||
|
||||
//
|
||||
// Function Name: fromScript()
|
||||
//
|
||||
|
|
|
@ -145,6 +145,16 @@
|
|||
#include <avatars-renderer/ScriptAvatar.h>
|
||||
#include <RenderableEntityItem.h>
|
||||
|
||||
#include <AnimationLogging.h>
|
||||
#include <AvatarLogging.h>
|
||||
#include <ScriptEngineLogging.h>
|
||||
#include <ModelFormatLogging.h>
|
||||
#include <controllers/Logging.h>
|
||||
#include <NetworkLogging.h>
|
||||
#include <shared/StorageLogging.h>
|
||||
#include <ScriptEngineLogging.h>
|
||||
#include <ui/Logging.h>
|
||||
|
||||
#include "AudioClient.h"
|
||||
#include "audio/AudioScope.h"
|
||||
#include "avatar/AvatarManager.h"
|
||||
|
@ -1060,6 +1070,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
if (steamClient) {
|
||||
qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID();
|
||||
}
|
||||
setCrashAnnotation("steam", property(hifi::properties::STEAM).toBool() ? "1" : "0");
|
||||
|
||||
qCDebug(interfaceapp) << "[VERSION] Build sequence:" << qPrintable(applicationVersion());
|
||||
qCDebug(interfaceapp) << "[VERSION] MODIFIED_ORGANIZATION:" << BuildInfo::MODIFIED_ORGANIZATION;
|
||||
qCDebug(interfaceapp) << "[VERSION] VERSION:" << BuildInfo::VERSION;
|
||||
|
@ -1145,6 +1157,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
const DomainHandler& domainHandler = nodeList->getDomainHandler();
|
||||
|
||||
connect(&domainHandler, SIGNAL(domainURLChanged(QUrl)), SLOT(domainURLChanged(QUrl)));
|
||||
connect(&domainHandler, &DomainHandler::domainURLChanged, [](QUrl domainURL){
|
||||
setCrashAnnotation("domain", domainURL.toString().toStdString());
|
||||
});
|
||||
connect(&domainHandler, SIGNAL(resetting()), SLOT(resettingDomain()));
|
||||
connect(&domainHandler, SIGNAL(connectedToDomain(QUrl)), SLOT(updateWindowTitle()));
|
||||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(updateWindowTitle()));
|
||||
|
@ -1190,6 +1205,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog);
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle);
|
||||
connect(accountManager.data(), &AccountManager::usernameChanged, [](QString username){
|
||||
setCrashAnnotation("username", username.toStdString());
|
||||
});
|
||||
|
||||
// set the account manager's root URL and trigger a login request if we don't have the access token
|
||||
accountManager->setIsAgent(true);
|
||||
|
@ -1207,6 +1225,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateThreadPoolCount);
|
||||
connect(this, &Application::activeDisplayPluginChanged, this, [](){
|
||||
qApp->setProperty(hifi::properties::HMD, qApp->isHMDMode());
|
||||
auto displayPlugin = qApp->getActiveDisplayPlugin();
|
||||
setCrashAnnotation("display_plugin", displayPlugin->getName().toStdString());
|
||||
setCrashAnnotation("hmd", displayPlugin->isHmd() ? "1" : "0");
|
||||
});
|
||||
connect(this, &Application::activeDisplayPluginChanged, this, &Application::updateSystemTabletMode);
|
||||
|
||||
|
@ -1214,6 +1235,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
connect(myAvatar.get(), &MyAvatar::positionGoneTo,
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
connect(myAvatar.get(), &MyAvatar::skeletonModelURLChanged, [](){
|
||||
QUrl avatarURL = qApp->getMyAvatar()->getSkeletonModelURL();
|
||||
setCrashAnnotation("avatar", avatarURL.toString().toStdString());
|
||||
});
|
||||
|
||||
|
||||
// Inititalize sample before registering
|
||||
_sampleSound = DependencyManager::get<SoundCache>()->getSound(PathUtils::resourcesUrl("sounds/sample.wav"));
|
||||
|
||||
|
@ -1306,6 +1333,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
// Needs to happen AFTER the render engine initialization to access its configuration
|
||||
initializeUi();
|
||||
|
||||
updateVerboseLogging();
|
||||
|
||||
init();
|
||||
qCDebug(interfaceapp, "init() complete.");
|
||||
|
||||
|
@ -1376,6 +1405,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
userActivityLogger.disable(false);
|
||||
}
|
||||
|
||||
QString machineFingerPrint = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
|
||||
|
||||
if (userActivityLogger.isEnabled()) {
|
||||
// sessionRunTime will be reset soon by loadSettings. Grab it now to get previous session value.
|
||||
// The value will be 0 if the user blew away settings this session, which is both a feature and a bug.
|
||||
|
@ -1425,11 +1456,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
properties["first_run"] = firstRun.get();
|
||||
|
||||
// add the user's machine ID to the launch event
|
||||
properties["machine_fingerprint"] = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint());
|
||||
properties["machine_fingerprint"] = machineFingerPrint;
|
||||
|
||||
userActivityLogger.logAction("launch", properties);
|
||||
}
|
||||
|
||||
setCrashAnnotation("machine_fingerprint", machineFingerPrint.toStdString());
|
||||
|
||||
_entityEditSender.setMyAvatar(myAvatar.get());
|
||||
|
||||
// The entity octree will have to know about MyAvatar for the parentJointName import
|
||||
|
@ -2174,6 +2207,46 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo
|
|||
qCDebug(interfaceapp) << "Metaverse session ID is" << uuidStringWithoutCurlyBraces(accountManager->getSessionID());
|
||||
}
|
||||
|
||||
void Application::updateVerboseLogging() {
|
||||
bool enable = Menu::getInstance()->isOptionChecked(MenuOption::VerboseLogging);
|
||||
|
||||
const_cast<QLoggingCategory*>(&animation())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&animation())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&avatars())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&avatars())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&scriptengine())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&scriptengine())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&modelformat())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&modelformat())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&controllers())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&controllers())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&resourceLog())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&resourceLog())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&networking())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&networking())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&asset_client())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&asset_client())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&messages_client())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&messages_client())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&storagelogging())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&storagelogging())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&uiLogging())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&uiLogging())->setEnabled(QtInfoMsg, enable);
|
||||
|
||||
const_cast<QLoggingCategory*>(&glLogging())->setEnabled(QtDebugMsg, enable);
|
||||
const_cast<QLoggingCategory*>(&glLogging())->setEnabled(QtInfoMsg, enable);
|
||||
}
|
||||
|
||||
void Application::domainConnectionRefused(const QString& reasonMessage, int reasonCodeInt, const QString& extraInfo) {
|
||||
DomainHandler::ConnectionRefusedReason reasonCode = static_cast<DomainHandler::ConnectionRefusedReason>(reasonCodeInt);
|
||||
|
||||
|
@ -3042,7 +3115,6 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
|
|||
PROFILE_RANGE(render, __FUNCTION__);
|
||||
|
||||
bool sandboxIsRunning = SandboxUtils::readStatus(reply->readAll());
|
||||
qDebug() << "HandleSandboxStatus" << sandboxIsRunning;
|
||||
|
||||
enum HandControllerType {
|
||||
Vive,
|
||||
|
|
|
@ -399,6 +399,8 @@ public slots:
|
|||
|
||||
Q_INVOKABLE bool askBeforeSetAvatarUrl(const QString& avatarUrl) { return askToSetAvatarUrl(avatarUrl); }
|
||||
|
||||
void updateVerboseLogging();
|
||||
|
||||
private slots:
|
||||
void onDesktopRootItemCreated(QQuickItem* qmlContext);
|
||||
void onDesktopRootContextCreated(QQmlContext* qmlContext);
|
||||
|
|
|
@ -43,12 +43,10 @@ void ConnectionMonitor::init() {
|
|||
}
|
||||
|
||||
void ConnectionMonitor::startTimer() {
|
||||
qDebug() << "ConnectionMonitor: Starting timer";
|
||||
_timer.start(DISPLAY_AFTER_DISCONNECTED_FOR_X_MS);
|
||||
}
|
||||
|
||||
void ConnectionMonitor::stopTimer() {
|
||||
qDebug() << "ConnectionMonitor: Stopping timer";
|
||||
_timer.stop();
|
||||
DependencyManager::get<DialogsManager>()->setDomainConnectionFailureVisibility(false);
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#if HAS_CRASHPAD
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <QStandardPaths>
|
||||
#include <QDir>
|
||||
|
||||
|
@ -23,8 +25,8 @@
|
|||
#include <client/crashpad_client.h>
|
||||
#include <client/crash_report_database.h>
|
||||
#include <client/settings.h>
|
||||
// #include <client/annotation_list.h>
|
||||
// #include <client/crashpad_info.h>
|
||||
#include <client/annotation_list.h>
|
||||
#include <client/crashpad_info.h>
|
||||
|
||||
using namespace crashpad;
|
||||
|
||||
|
@ -35,7 +37,8 @@ static std::wstring gIPCPipe;
|
|||
|
||||
extern QString qAppFileName();
|
||||
|
||||
// crashpad::AnnotationList* crashpadAnnotations { nullptr };
|
||||
std::mutex annotationMutex;
|
||||
crashpad::SimpleStringDictionary* crashpadAnnotations { nullptr };
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
|
@ -102,12 +105,14 @@ bool startCrashHandler() {
|
|||
}
|
||||
|
||||
void setCrashAnnotation(std::string name, std::string value) {
|
||||
// if (!crashpadAnnotations) {
|
||||
// crashpadAnnotations = new crashpad::AnnotationList(); // don't free this, let it leak
|
||||
// crashpad::CrashpadInfo* crashpad_info = crashpad::GetCrashpadInfo();
|
||||
// crashpad_info->set_simple_annotations(crashpadAnnotations);
|
||||
// }
|
||||
// crashpadAnnotations->SetKeyValue(name, value);
|
||||
std::lock_guard<std::mutex> guard(annotationMutex);
|
||||
if (!crashpadAnnotations) {
|
||||
crashpadAnnotations = new crashpad::SimpleStringDictionary(); // don't free this, let it leak
|
||||
crashpad::CrashpadInfo* crashpad_info = crashpad::CrashpadInfo::GetCrashpadInfo();
|
||||
crashpad_info->set_simple_annotations(crashpadAnnotations);
|
||||
}
|
||||
std::replace(value.begin(), value.end(), ',', ';');
|
||||
crashpadAnnotations->SetKeyValue(name, value);
|
||||
}
|
||||
|
||||
#else
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <UserActivityLogger.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Crashpad.h"
|
||||
#include "DiscoverabilityManager.h"
|
||||
#include "Menu.h"
|
||||
|
||||
|
@ -127,10 +128,12 @@ void DiscoverabilityManager::updateLocation() {
|
|||
QNetworkAccessManager::PutOperation, callbackParameters);
|
||||
}
|
||||
|
||||
// Update Steam
|
||||
// Update Steam and crash logger
|
||||
QUrl currentAddress = addressManager->currentFacingPublicAddress();
|
||||
if (auto steamClient = PluginManager::getInstance()->getSteamClientPlugin()) {
|
||||
steamClient->updateLocation(domainHandler.getHostname(), addressManager->currentFacingPublicAddress());
|
||||
steamClient->updateLocation(domainHandler.getHostname(), currentAddress);
|
||||
}
|
||||
setCrashAnnotation("address", currentAddress.toString().toStdString());
|
||||
}
|
||||
|
||||
void DiscoverabilityManager::handleHeartbeatResponse(QNetworkReply& requestReply) {
|
||||
|
|
|
@ -9,11 +9,6 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
/**jsdoc
|
||||
* The LOD class manages your Level of Detail functions within interface
|
||||
* @namespace LODManager
|
||||
*/
|
||||
|
||||
#ifndef hifi_LODManager_h
|
||||
#define hifi_LODManager_h
|
||||
|
||||
|
@ -39,10 +34,32 @@ const float ADJUST_LOD_MIN_SIZE_SCALE = DEFAULT_OCTREE_SIZE_SCALE * 0.04f;
|
|||
|
||||
class AABox;
|
||||
|
||||
/**jsdoc
|
||||
* The LOD class manages your Level of Detail functions within Interface.
|
||||
* @namespace LODManager
|
||||
* @property {number} presentTime <em>Read-only.</em>
|
||||
* @property {number} engineRunTime <em>Read-only.</em>
|
||||
* @property {number} gpuTime <em>Read-only.</em>
|
||||
* @property {number} avgRenderTime <em>Read-only.</em>
|
||||
* @property {number} fps <em>Read-only.</em>
|
||||
* @property {number} lodLevel <em>Read-only.</em>
|
||||
* @property {number} lodDecreaseFPS <em>Read-only.</em>
|
||||
* @property {number} lodIncreaseFPS <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
class LODManager : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
|
||||
Q_PROPERTY(float presentTime READ getPresentTime)
|
||||
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
|
||||
Q_PROPERTY(float gpuTime READ getGPUTime)
|
||||
Q_PROPERTY(float avgRenderTime READ getAverageRenderTime)
|
||||
Q_PROPERTY(float fps READ getMaxTheoreticalFPS)
|
||||
Q_PROPERTY(float lodLevel READ getLODLevel)
|
||||
Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS)
|
||||
Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS)
|
||||
|
||||
public:
|
||||
|
||||
/**jsdoc
|
||||
|
@ -138,28 +155,6 @@ public:
|
|||
*/
|
||||
Q_INVOKABLE float getLODIncreaseFPS() const;
|
||||
|
||||
/**jsdoc
|
||||
* @namespace LODManager
|
||||
* @property {number} presentTime <em>Read-only.</em>
|
||||
* @property {number} engineRunTime <em>Read-only.</em>
|
||||
* @property {number} gpuTime <em>Read-only.</em>
|
||||
* @property {number} avgRenderTime <em>Read-only.</em>
|
||||
* @property {number} fps <em>Read-only.</em>
|
||||
* @property {number} lodLevel <em>Read-only.</em>
|
||||
* @property {number} lodDecreaseFPS <em>Read-only.</em>
|
||||
* @property {number} lodIncreaseFPS <em>Read-only.</em>
|
||||
*/
|
||||
|
||||
Q_PROPERTY(float presentTime READ getPresentTime)
|
||||
Q_PROPERTY(float engineRunTime READ getEngineRunTime)
|
||||
Q_PROPERTY(float gpuTime READ getGPUTime)
|
||||
Q_PROPERTY(float avgRenderTime READ getAverageRenderTime)
|
||||
Q_PROPERTY(float fps READ getMaxTheoreticalFPS)
|
||||
Q_PROPERTY(float lodLevel READ getLODLevel)
|
||||
|
||||
Q_PROPERTY(float lodDecreaseFPS READ getLODDecreaseFPS)
|
||||
Q_PROPERTY(float lodIncreaseFPS READ getLODIncreaseFPS)
|
||||
|
||||
float getPresentTime() const { return _presentTime; }
|
||||
float getEngineRunTime() const { return _engineRunTime; }
|
||||
float getGPUTime() const { return _gpuTime; }
|
||||
|
|
|
@ -810,6 +810,9 @@ Menu::Menu() {
|
|||
scriptEngines->loadScript(defaultScriptsLoc.toString());
|
||||
});
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(developerMenu, MenuOption::VerboseLogging, 0, false,
|
||||
qApp, SLOT(updateVerboseLogging()));
|
||||
|
||||
#if 0 /// -------------- REMOVED FOR NOW --------------
|
||||
addDisabledActionAndSeparator(navigateMenu, "History");
|
||||
QAction* backAction = addActionToQMenuAndActionHash(navigateMenu, MenuOption::Back, 0, addressManager.data(), SLOT(goBack()));
|
||||
|
|
|
@ -142,6 +142,7 @@ namespace MenuOption {
|
|||
const QString Pair = "Pair";
|
||||
const QString PhysicsShowHulls = "Draw Collision Shapes";
|
||||
const QString PhysicsShowOwned = "Highlight Simulation Ownership";
|
||||
const QString VerboseLogging = "Verbose Logging";
|
||||
const QString PipelineWarnings = "Log Render Pipeline Warnings";
|
||||
const QString Preferences = "General...";
|
||||
const QString Quit = "Quit";
|
||||
|
|
|
@ -615,9 +615,15 @@ void Wallet::updateImageProvider() {
|
|||
securityImageProvider->setSecurityImage(_securityImage);
|
||||
|
||||
// inform tablet security image provider
|
||||
QQmlEngine* tabletEngine = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system")->getTabletSurface()->getSurfaceContext()->engine();
|
||||
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
|
||||
securityImageProvider->setSecurityImage(_securityImage);
|
||||
TabletProxy* tablet = DependencyManager::get<TabletScriptingInterface>()->getTablet("com.highfidelity.interface.tablet.system");
|
||||
if (tablet) {
|
||||
OffscreenQmlSurface* tabletSurface = tablet->getTabletSurface();
|
||||
if (tabletSurface) {
|
||||
QQmlEngine* tabletEngine = tabletSurface->getSurfaceContext()->engine();
|
||||
securityImageProvider = reinterpret_cast<SecurityImageProvider*>(tabletEngine->imageProvider(SecurityImageProvider::PROVIDER_NAME));
|
||||
securityImageProvider->setSecurityImage(_securityImage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Wallet::chooseSecurityImage(const QString& filename) {
|
||||
|
|
|
@ -108,11 +108,9 @@ AudioDeviceList::~AudioDeviceList() {
|
|||
// store the selected device
|
||||
foreach(std::shared_ptr<AudioDevice> adevice, _devices) {
|
||||
if (adevice->selectedDesktop) {
|
||||
qDebug() << "Saving Desktop for" << _mode << "name" << adevice->info.deviceName();
|
||||
settingDesktop.set(adevice->info.deviceName());
|
||||
}
|
||||
if (adevice->selectedHMD) {
|
||||
qDebug() << "Saving HMD for" << _mode << "name" << adevice->info.deviceName();
|
||||
settingHMD.set(adevice->info.deviceName());
|
||||
}
|
||||
}
|
||||
|
@ -311,7 +309,6 @@ void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
|
|||
}
|
||||
}
|
||||
|
||||
qDebug() << "adding audio device:" << device.display << device.selectedDesktop << device.selectedHMD << _mode;
|
||||
newDevices.push_back(newDevice(device));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ class ScriptEngine;
|
|||
/**jsdoc
|
||||
* The Controller API provides facilities to interact with computer and controller hardware.
|
||||
*
|
||||
* <h5>Functions:</h5>
|
||||
* <h5>Functions</h5>
|
||||
*
|
||||
* <p>Properties</p>
|
||||
* <ul>
|
||||
|
@ -143,6 +143,61 @@ class ScriptEngine;
|
|||
* <li>{@link Controller.stopInputPlayback|stopInputPlayback}</li>
|
||||
* </ul>
|
||||
*
|
||||
* <h5>Entity Methods:</h5>
|
||||
*
|
||||
* <p>The default scripts implement hand controller actions that use {@link Entities.callEntityMethod} to call entity script
|
||||
* methods, if present in the entity being interacted with.</p>
|
||||
*
|
||||
* <table>
|
||||
* <thead>
|
||||
* <tr><th>Method Name</th><th>Description</th><th>Example</th></tr>
|
||||
* </thead>
|
||||
* <tbody>
|
||||
* <tr>
|
||||
* <td><code>startFarTrigger</code><br /><code>continueFarTrigger</code><br /><code>stopFarTrigger</code></td>
|
||||
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is triggerable, and the
|
||||
* user starts, continues, or stops squeezing the trigger.</td>
|
||||
* </td>
|
||||
* <td>A light switch that can be toggled on and off from a distance.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startNearTrigger</code><br /><code>continueNearTrigger</code><br /><code>stopNearTrigger</code></td>
|
||||
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is triggerable, and the
|
||||
* user starts, continues, or stops squeezing the trigger.</td>
|
||||
* <td>A doorbell that can be rung when a user is near.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startDistanceGrab</code><br /><code>continueDistanceGrab</code><br /></td>
|
||||
* <td>These methods are called when a user is more than 0.3m away from the entity, the entity is either cloneable, or
|
||||
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
|
||||
* <td>A comet that emits icy particle trails when a user is dragging it through the sky.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startNearGrab</code><br /><code>continueNearGrab</code><br /></td>
|
||||
* <td>These methods are called when a user is less than 0.3m away from the entity, the entity is either cloneable, or
|
||||
* grabbable and not locked, and the user starts or continues to squeeze the trigger.</td>
|
||||
* <td>A ball that glows when it's being held close.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>releaseGrab</code></td>
|
||||
* <td>This method is called when a user releases the trigger when having been either distance or near grabbing an
|
||||
* entity.</td>
|
||||
* <td>Turn off the ball glow or comet trail with the user finishes grabbing it.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td><code>startEquip</code><br /><code>continueEquip</code><br /><code>releaseEquip</code></td>
|
||||
* <td>These methods are called when a user starts, continues, or stops equipping an entity.</td>
|
||||
* <td>A glass that stays in the user's hand after the trigger is clicked.</td>
|
||||
* </tr>
|
||||
* </tbody>
|
||||
* </table>
|
||||
* <p>All the entity methods are called with the following two arguments:</p>
|
||||
* <ul>
|
||||
* <li>The entity ID.</li>
|
||||
* <li>A string, <code>"hand,userID"</code> — where "hand" is <code>"left"</code> or <code>"right"</code>, and "userID"
|
||||
* is the user's {@link MyAvatar|MyAvatar.sessionUUID}.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @namespace Controller
|
||||
*
|
||||
* @property {Controller.Actions} Actions - Predefined actions on Interface and the user's avatar. These can be used as end
|
||||
|
|
|
@ -80,7 +80,6 @@ void DialogsManager::showFeed() {
|
|||
}
|
||||
|
||||
void DialogsManager::setDomainConnectionFailureVisibility(bool visible) {
|
||||
qDebug() << "DialogsManager::setDomainConnectionFailureVisibility: visible" << visible;
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
auto tablet = dynamic_cast<TabletProxy*>(tabletScriptingInterface->getTablet("com.highfidelity.interface.tablet.system"));
|
||||
|
||||
|
|
|
@ -588,6 +588,7 @@ void AnimExpression::evalUnaryMinus(const AnimVariantMap& map, std::stack<OpCode
|
|||
PUSH(false);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OpCode::Int:
|
||||
PUSH(-rhs.intVal);
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
// Inline functions to implement audio dynamics processing
|
||||
//
|
||||
|
||||
#include <stddef.h>
|
||||
#include <math.h>
|
||||
#include <stdint.h>
|
||||
|
||||
|
|
|
@ -39,7 +39,9 @@ class UserInputMapper;
|
|||
* methods.</li>
|
||||
* <li>Use {@link Controller.parseMapping} or {@link Controller.loadMapping} to load a {@link Controller.MappingJSON}.</li>
|
||||
* </ul>
|
||||
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take effect.
|
||||
*
|
||||
* <p>Enable the mapping using {@link MappingObject#enable|enable} or {@link Controller.enableMapping} for it to take
|
||||
* effect.</p>
|
||||
*
|
||||
* <p>Mappings and their routes are applied according to the following rules:</p>
|
||||
* <ul>
|
||||
|
@ -49,7 +51,7 @@ class UserInputMapper;
|
|||
* output that already has a route the new route is ignored.</li>
|
||||
* <li>New mappings override previous mappings: each output is processed using the route in the most recently enabled
|
||||
* mapping that contains that output.</li>
|
||||
* </p>
|
||||
* </ul>
|
||||
*
|
||||
* @class MappingObject
|
||||
*/
|
||||
|
|
|
@ -29,7 +29,8 @@ class ScriptingInterface;
|
|||
* <p>A route in a {@link MappingObject} used by the {@link Controller} API.</p>
|
||||
*
|
||||
* <p>Create a route using {@link MappingObject} methods and apply this object's methods to process it, terminating with
|
||||
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function.</p>
|
||||
* {@link RouteObject#to} to apply it to a <code>Standard</code> control, action, or script function. Note: Loops are not
|
||||
* permitted.</p>
|
||||
*
|
||||
* <p>Some methods apply to routes with number data, some apply routes with {@link Pose} data, and some apply to both route
|
||||
* types.<p>
|
||||
|
|
|
@ -308,12 +308,7 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
|||
item->setProperty(URL_PROPERTY, _lastSourceUrl);
|
||||
});
|
||||
} else if (_contentType == ContentType::QmlContent) {
|
||||
_webSurface->load(_lastSourceUrl, [this](QQmlContext* context, QObject* item) {
|
||||
if (item && item->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", _webSurface.data());
|
||||
}
|
||||
});
|
||||
_webSurface->load(_lastSourceUrl);
|
||||
}
|
||||
_fadeStartTime = usecTimestampNow();
|
||||
_webSurface->resume();
|
||||
|
@ -323,32 +318,21 @@ bool WebEntityRenderer::buildWebSurface(const TypedEntityPointer& entity) {
|
|||
|
||||
void WebEntityRenderer::destroyWebSurface() {
|
||||
QSharedPointer<OffscreenQmlSurface> webSurface;
|
||||
ContentType contentType{ ContentType::NoContent };
|
||||
withWriteLock([&] {
|
||||
webSurface.swap(_webSurface);
|
||||
std::swap(contentType, _contentType);
|
||||
});
|
||||
|
||||
if (webSurface) {
|
||||
--_currentWebCount;
|
||||
QQuickItem* rootItem = webSurface->getRootItem();
|
||||
// Explicitly set the web URL to an empty string, in an effort to get a
|
||||
// faster shutdown of any chromium processes interacting with audio
|
||||
if (rootItem && _contentType == ContentType::HtmlContent) {
|
||||
rootItem->setProperty(URL_PROPERTY, "");
|
||||
}
|
||||
|
||||
if (rootItem && rootItem->objectName() == "tabletRoot") {
|
||||
auto tabletScriptingInterface = DependencyManager::get<TabletScriptingInterface>();
|
||||
tabletScriptingInterface->setQmlTabletRoot("com.highfidelity.interface.tablet.system", nullptr);
|
||||
}
|
||||
|
||||
// Fix for crash in QtWebEngineCore when rapidly switching domains
|
||||
// Call stop on the QWebEngineView before destroying OffscreenQMLSurface.
|
||||
if (rootItem) {
|
||||
QObject* obj = rootItem->findChild<QObject*>("webEngineView");
|
||||
if (obj) {
|
||||
// stop loading
|
||||
QMetaObject::invokeMethod(obj, "stop");
|
||||
}
|
||||
if (rootItem && contentType == ContentType::HtmlContent) {
|
||||
// stop loading
|
||||
QMetaObject::invokeMethod(rootItem, "stop");
|
||||
}
|
||||
|
||||
webSurface->pause();
|
||||
|
|
|
@ -390,17 +390,18 @@ public slots:
|
|||
/**jsdoc
|
||||
* Find all entities of a particular name that intersect a sphere defined by a center point and radius.
|
||||
* @function Entities.findEntitiesByName
|
||||
* @param {Entities.EntityType} entityName - The name of the entity to search for.
|
||||
* @param {string} entityName - The name of the entity to search for.
|
||||
* @param {Vec3} center - The point about which to search.
|
||||
* @param {number} radius - The radius within which to search.
|
||||
* @param {boolean} caseSensitiveSearch - Choose whether to to return case sensitive results back.
|
||||
* @returns {Uuid[]} An array of entity IDs of the specified type that intersect the search sphere. The array is empty if
|
||||
* no entities could be found.
|
||||
* @example <caption>Get back a list of entities</caption>
|
||||
* @param {boolean} [caseSensitive=false] - If <code>true</code> then the search is case-sensitive.
|
||||
* @returns {Uuid[]} An array of entity IDs that have the specified name and intersect the search sphere. The array is empty
|
||||
* if no entities could be found.
|
||||
* @example <caption>Report the number of entities with the name, "Light-Target".</caption>
|
||||
* var entityIDs = Entities.findEntitiesByName("Light-Target", MyAvatar.position, 10, false);
|
||||
* print("Number of Entities with the name Light-Target " + entityIDs.length);
|
||||
* print("Number of entities with the name "Light-Target": " + entityIDs.length);
|
||||
*/
|
||||
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius, bool caseSensitiveSearch = false ) const;
|
||||
Q_INVOKABLE QVector<QUuid> findEntitiesByName(const QString entityName, const glm::vec3& center, float radius,
|
||||
bool caseSensitiveSearch = false ) const;
|
||||
|
||||
/**jsdoc
|
||||
* Find the first entity intersected by a {@link PickRay}. <code>Light</code> and <code>Zone</code> entities are not
|
||||
|
|
|
@ -996,14 +996,12 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
|
|||
QByteArray filename = subobject.properties.at(0).toByteArray();
|
||||
QByteArray filepath = filename.replace('\\', '/');
|
||||
filename = fileOnUrl(filepath, url);
|
||||
qDebug() << "Filename" << filepath << filename;
|
||||
_textureFilepaths.insert(getID(object.properties), filepath);
|
||||
_textureFilenames.insert(getID(object.properties), filename);
|
||||
} else if (subobject.name == "TextureName" && subobject.properties.length() >= TEXTURE_NAME_MIN_SIZE) {
|
||||
// trim the name from the timestamp
|
||||
QString name = QString(subobject.properties.at(0).toByteArray());
|
||||
name = name.left(name.indexOf('['));
|
||||
qDebug() << "Filename" << name;
|
||||
_textureNames.insert(getID(object.properties), name);
|
||||
} else if (subobject.name == "Texture_Alpha_Source" && subobject.properties.length() >= TEXTURE_ALPHA_SOURCE_MIN_SIZE) {
|
||||
tex.assign<uint8_t>(tex.alphaSource, subobject.properties.at(0).value<int>());
|
||||
|
|
|
@ -192,8 +192,6 @@ void EntityScriptClient::handleNodeClientConnectionReset(SharedNodePointer node)
|
|||
return;
|
||||
}
|
||||
|
||||
//qCDebug(entity_script_client) << "EntityScriptClient detected client connection reset handshake with Asset Server - failing any pending requests";
|
||||
|
||||
forceFailureOfPendingRequests(node);
|
||||
}
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
Q_DECLARE_LOGGING_CATEGORY(resourceLog)
|
||||
Q_DECLARE_LOGGING_CATEGORY(networking)
|
||||
Q_DECLARE_LOGGING_CATEGORY(asset_client)
|
||||
Q_DECLARE_LOGGING_CATEGORY(entity_script_client)
|
||||
Q_DECLARE_LOGGING_CATEGORY(messages_client)
|
||||
|
||||
#endif // hifi_NetworkLogging_h
|
||||
|
|
|
@ -795,9 +795,10 @@ QString getMarketplaceID(const QString& urlString) {
|
|||
}
|
||||
|
||||
bool Octree::readFromURL(const QString& urlString) {
|
||||
QString marketplaceID = getMarketplaceID(urlString);
|
||||
QString trimmedUrl = urlString.trimmed();
|
||||
QString marketplaceID = getMarketplaceID(trimmedUrl);
|
||||
auto request =
|
||||
std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, urlString));
|
||||
std::unique_ptr<ResourceRequest>(DependencyManager::get<ResourceManager>()->createResourceRequest(this, trimmedUrl));
|
||||
|
||||
if (!request) {
|
||||
return false;
|
||||
|
|
|
@ -153,6 +153,8 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
// remove the objects (aka MotionStates) from physics
|
||||
_physicsEngine->removeSetOfObjects(_physicalObjects);
|
||||
|
||||
clearOwnershipData();
|
||||
|
||||
// delete the MotionStates
|
||||
for (auto stateItr : _physicalObjects) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr));
|
||||
|
@ -165,7 +167,6 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
_physicalObjects.clear();
|
||||
|
||||
// clear all other lists specific to this derived class
|
||||
clearOwnershipData();
|
||||
_entitiesToRemoveFromPhysics.clear();
|
||||
_entitiesToAddToPhysics.clear();
|
||||
_incomingChanges.clear();
|
||||
|
|
|
@ -90,19 +90,23 @@ SharedObject::~SharedObject() {
|
|||
_renderControl = nullptr;
|
||||
}
|
||||
|
||||
if (_rootItem) {
|
||||
delete _rootItem;
|
||||
_rootItem = nullptr;
|
||||
}
|
||||
|
||||
if (_quickWindow) {
|
||||
_quickWindow->destroy();
|
||||
delete _quickWindow;
|
||||
_quickWindow = nullptr;
|
||||
}
|
||||
|
||||
// _rootItem is parented to the quickWindow, so needs no explicit destruction
|
||||
//if (_rootItem) {
|
||||
// delete _rootItem;
|
||||
// _rootItem = nullptr;
|
||||
//}
|
||||
|
||||
releaseEngine(_qmlContext->engine());
|
||||
if (_qmlContext) {
|
||||
auto engine = _qmlContext->engine();
|
||||
delete _qmlContext;
|
||||
_qmlContext = nullptr;
|
||||
releaseEngine(engine);
|
||||
}
|
||||
}
|
||||
|
||||
void SharedObject::create(OffscreenSurface* surface) {
|
||||
|
@ -210,9 +214,9 @@ QQmlEngine* SharedObject::acquireEngine(OffscreenSurface* surface) {
|
|||
if (!globalEngine) {
|
||||
Q_ASSERT(0 == globalEngineRefCount);
|
||||
globalEngine = new QQmlEngine();
|
||||
surface->initializeQmlEngine(result);
|
||||
++globalEngineRefCount;
|
||||
surface->initializeEngine(result);
|
||||
}
|
||||
++globalEngineRefCount;
|
||||
result = globalEngine;
|
||||
#else
|
||||
result = new QQmlEngine();
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "AbstractViewStateInterface.h"
|
||||
#include "RenderUtilsLogging.h"
|
||||
#include "DebugDraw.h"
|
||||
#include "StencilMaskPass.h"
|
||||
|
||||
#include "animdebugdraw_vert.h"
|
||||
#include "animdebugdraw_frag.h"
|
||||
|
@ -70,7 +71,7 @@ public:
|
|||
typedef render::Payload<AnimDebugDrawData> AnimDebugDrawPayload;
|
||||
|
||||
namespace render {
|
||||
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::opaqueShape() : ItemKey::Builder::opaqueShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); }
|
||||
template <> const ItemKey payloadGetKey(const AnimDebugDrawData::Pointer& data) { return (data->_isVisible ? ItemKey::Builder::transparentShape() : ItemKey::Builder::transparentShape().withInvisible()).withTagBits(ItemKey::TAG_BITS_ALL); }
|
||||
template <> const Item::Bound payloadGetBound(const AnimDebugDrawData::Pointer& data) { return data->_bound; }
|
||||
template <> void payloadRender(const AnimDebugDrawData::Pointer& data, RenderArgs* args) {
|
||||
data->render(args);
|
||||
|
@ -104,6 +105,7 @@ AnimDebugDraw::AnimDebugDraw() :
|
|||
state->setBlendFunction(false, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD,
|
||||
gpu::State::INV_SRC_ALPHA, gpu::State::FACTOR_ALPHA,
|
||||
gpu::State::BLEND_OP_ADD, gpu::State::ONE);
|
||||
PrepareStencil::testMaskDrawShape(*state.get());
|
||||
auto vertShader = animdebugdraw_vert::getShader();
|
||||
auto fragShader = animdebugdraw_frag::getShader();
|
||||
auto program = gpu::Shader::createProgram(vertShader, fragShader);
|
||||
|
|
|
@ -198,7 +198,7 @@ Antialiasing::~Antialiasing() {
|
|||
_antialiasingTextures[1].reset();
|
||||
}
|
||||
|
||||
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
||||
const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline(const render::RenderContextPointer& renderContext) {
|
||||
|
||||
if (!_antialiasingPipeline) {
|
||||
|
||||
|
@ -207,17 +207,6 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
|||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("taaParamsBuffer"), AntialiasingPass_ParamsSlot));
|
||||
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), AntialiasingPass_FrameTransformSlot));
|
||||
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("historyMap"), AntialiasingPass_HistoryMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), AntialiasingPass_SourceMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("velocityMap"), AntialiasingPass_VelocityMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AntialiasingPass_DepthMapSlot));
|
||||
|
||||
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
|
@ -225,6 +214,21 @@ const gpu::PipelinePointer& Antialiasing::getAntialiasingPipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_antialiasingPipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
gpu::doInBatch("SurfaceGeometryPass::CurvaturePipeline", renderContext->args->_context, [program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("taaParamsBuffer"), AntialiasingPass_ParamsSlot));
|
||||
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), AntialiasingPass_FrameTransformSlot));
|
||||
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("historyMap"), AntialiasingPass_HistoryMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("sourceMap"), AntialiasingPass_SourceMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("velocityMap"), AntialiasingPass_VelocityMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), AntialiasingPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return _antialiasingPipeline;
|
||||
|
@ -347,7 +351,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
|
|||
batch.setViewportTransform(args->_viewport);
|
||||
|
||||
// TAA step
|
||||
getAntialiasingPipeline();
|
||||
getAntialiasingPipeline(renderContext);
|
||||
batch.setResourceFramebufferSwapChainTexture(AntialiasingPass_HistoryMapSlot, _antialiasingBuffers, 0);
|
||||
batch.setResourceTexture(AntialiasingPass_SourceMapSlot, sourceBuffer->getRenderBuffer(0));
|
||||
batch.setResourceTexture(AntialiasingPass_VelocityMapSlot, velocityBuffer->getVelocityTexture());
|
||||
|
@ -358,7 +362,7 @@ void Antialiasing::run(const render::RenderContextPointer& renderContext, const
|
|||
batch.setUniformBuffer(AntialiasingPass_FrameTransformSlot, deferredFrameTransform->getFrameTransformBuffer());
|
||||
|
||||
batch.setFramebufferSwapChain(_antialiasingBuffers, 1);
|
||||
batch.setPipeline(getAntialiasingPipeline());
|
||||
batch.setPipeline(getAntialiasingPipeline(renderContext));
|
||||
batch.draw(gpu::TRIANGLE_STRIP, 4);
|
||||
|
||||
// Blend step
|
||||
|
|
|
@ -174,7 +174,7 @@ public:
|
|||
void configure(const Config& config);
|
||||
void run(const render::RenderContextPointer& renderContext, const Inputs& inputs);
|
||||
|
||||
const gpu::PipelinePointer& getAntialiasingPipeline();
|
||||
const gpu::PipelinePointer& getAntialiasingPipeline(const render::RenderContextPointer& renderContext);
|
||||
const gpu::PipelinePointer& getBlendPipeline();
|
||||
const gpu::PipelinePointer& getDebugBlendPipeline();
|
||||
|
||||
|
|
|
@ -168,7 +168,7 @@ void LinearDepthPass::run(const render::RenderContextPointer& renderContext, con
|
|||
outputs.edit4() = halfNormalTexture;
|
||||
|
||||
auto linearDepthPipeline = getLinearDepthPipeline(renderContext);
|
||||
auto downsamplePipeline = getDownsamplePipeline();
|
||||
auto downsamplePipeline = getDownsamplePipeline(renderContext);
|
||||
|
||||
auto depthViewport = args->_viewport;
|
||||
auto halfViewport = depthViewport >> 1;
|
||||
|
@ -241,19 +241,12 @@ const gpu::PipelinePointer& LinearDepthPass::getLinearDepthPipeline(const render
|
|||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
|
||||
const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline(const render::RenderContextPointer& renderContext) {
|
||||
if (!_downsamplePipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = surfaceGeometry_downsampleDepthNormal_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), DepthLinearPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("linearDepthMap"), DepthLinearPass_DepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("normalMap"), DepthLinearPass_NormalMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
PrepareStencil::testShape(*state);
|
||||
|
||||
|
@ -261,6 +254,16 @@ const gpu::PipelinePointer& LinearDepthPass::getDownsamplePipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_downsamplePipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
gpu::doInBatch("LinearDepthPass::run", renderContext->args->_context, [program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding("deferredFrameTransformBuffer", DepthLinearPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding("linearDepthMap", DepthLinearPass_DepthMapSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding("normalMap", DepthLinearPass_NormalMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return _downsamplePipeline;
|
||||
|
|
|
@ -84,7 +84,7 @@ private:
|
|||
const gpu::PipelinePointer& getLinearDepthPipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _linearDepthPipeline;
|
||||
|
||||
const gpu::PipelinePointer& getDownsamplePipeline();
|
||||
const gpu::PipelinePointer& getDownsamplePipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _downsamplePipeline;
|
||||
|
||||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
|
|
@ -113,7 +113,7 @@ void VelocityBufferPass::run(const render::RenderContextPointer& renderContext,
|
|||
outputs.edit1() = velocityFBO;
|
||||
outputs.edit2() = velocityTexture;
|
||||
|
||||
auto cameraMotionPipeline = getCameraMotionPipeline();
|
||||
auto cameraMotionPipeline = getCameraMotionPipeline(renderContext);
|
||||
|
||||
auto fullViewport = args->_viewport;
|
||||
|
||||
|
@ -143,18 +143,12 @@ void VelocityBufferPass::run(const render::RenderContextPointer& renderContext,
|
|||
}
|
||||
|
||||
|
||||
const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline() {
|
||||
const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline(const render::RenderContextPointer& renderContext) {
|
||||
if (!_cameraMotionPipeline) {
|
||||
auto vs = gpu::StandardShaderLib::getDrawViewportQuadTransformTexcoordVS();
|
||||
auto ps = velocityBuffer_cameraMotion_frag::getShader();
|
||||
gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps);
|
||||
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), VelocityBufferPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), VelocityBufferPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
|
||||
|
||||
gpu::StatePointer state = gpu::StatePointer(new gpu::State());
|
||||
|
||||
// Stencil test the curvature pass for objects pixels only, not the background
|
||||
|
@ -164,6 +158,16 @@ const gpu::PipelinePointer& VelocityBufferPass::getCameraMotionPipeline() {
|
|||
|
||||
// Good to go add the brand new pipeline
|
||||
_cameraMotionPipeline = gpu::Pipeline::create(program, state);
|
||||
|
||||
gpu::doInBatch("VelocityBufferPass::CameraMotionPipeline", renderContext->args->_context,
|
||||
[program](gpu::Batch& batch) {
|
||||
batch.runLambda([program]() {
|
||||
gpu::Shader::BindingSet slotBindings;
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("deferredFrameTransformBuffer"), VelocityBufferPass_FrameTransformSlot));
|
||||
slotBindings.insert(gpu::Shader::Binding(std::string("depthMap"), VelocityBufferPass_DepthMapSlot));
|
||||
gpu::Shader::makeProgram(*program, slotBindings);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return _cameraMotionPipeline;
|
||||
|
|
|
@ -79,7 +79,7 @@ private:
|
|||
|
||||
VelocityFramebufferPointer _velocityFramebuffer;
|
||||
|
||||
const gpu::PipelinePointer& getCameraMotionPipeline();
|
||||
const gpu::PipelinePointer& getCameraMotionPipeline(const render::RenderContextPointer& renderContext);
|
||||
gpu::PipelinePointer _cameraMotionPipeline;
|
||||
|
||||
gpu::RangeTimerPointer _gpuTimer;
|
||||
|
|
|
@ -2161,6 +2161,32 @@ void ScriptEngine::loadEntityScript(const EntityItemID& entityID, const QString&
|
|||
}, forceRedownload);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script starts for a user.
|
||||
* <p>Note: Can only be connected to via <code>this.preload = function (...) { ... }</code> in the entity script.</p>
|
||||
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
|
||||
* @function Entities.preload
|
||||
* @param {Uuid} entityID - The ID of the entity that the script is running in.
|
||||
* @returns {Signal}
|
||||
* @example <caption>Get the ID of the entity that a client entity script is running in.</caption>
|
||||
* var entityScript = (function () {
|
||||
* this.entityID = Uuid.NULL;
|
||||
*
|
||||
* this.preload = function (entityID) {
|
||||
* this.entityID = entityID;
|
||||
* print("Entity ID: " + this.entityID);
|
||||
* };
|
||||
* );
|
||||
*
|
||||
* var entityID = Entities.addEntity({
|
||||
* type: "Box",
|
||||
* position: Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, { x: 0, y: 0, z: -5 })),
|
||||
* dimensions: { x: 0.5, y: 0.5, z: 0.5 },
|
||||
* color: { red: 255, green: 0, blue: 0 },
|
||||
* script: "(" + entityScript + ")", // Could host the script on a Web server instead.
|
||||
* lifetime: 300 // Delete after 5 minutes.
|
||||
* });
|
||||
*/
|
||||
// since all of these operations can be asynch we will always do the actual work in the response handler
|
||||
// for the download
|
||||
void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, const QString& scriptOrURL, const QString& contents, bool isURL, bool success , const QString& status) {
|
||||
|
@ -2345,6 +2371,13 @@ void ScriptEngine::entityScriptContentAvailable(const EntityItemID& entityID, co
|
|||
processDeferredEntityLoads(entityScript, entityID);
|
||||
}
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the script terminates for a user.
|
||||
* <p>Note: Can only be connected to via <code>this.unoad = function () { ... }</code> in the entity script.</p>
|
||||
* <table><tr><th>Available in:</th><td>Client Entity Scripts</td><td>Server Entity Scripts</td></tr></table>
|
||||
* @function Entities.unload
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void ScriptEngine::unloadEntityScript(const EntityItemID& entityID, bool shouldRemoveFromMap) {
|
||||
if (QThread::currentThread() != thread()) {
|
||||
#ifdef THREAD_DEBUGGING
|
||||
|
|
|
@ -273,9 +273,9 @@ QVariantList ScriptEngines::getRunning() {
|
|||
} else {
|
||||
displayURLString = displayURL.toDisplayString(QUrl::FormattingOptions(QUrl::FullyEncoded));
|
||||
}
|
||||
resultNode.insert("url", displayURLString);
|
||||
// The path contains the exact path/URL of the script, which also is used in the stopScript function.
|
||||
resultNode.insert("path", normalizeScriptURL(runningScript).toString());
|
||||
resultNode.insert("path", displayURLString);
|
||||
resultNode.insert("url", normalizeScriptURL(runningScript).toString());
|
||||
resultNode.insert("local", runningScriptURL.isLocalFile());
|
||||
result.append(resultNode);
|
||||
}
|
||||
|
@ -538,7 +538,6 @@ int ScriptEngines::runScriptInitializers(ScriptEnginePointer scriptEngine) {
|
|||
int ii=0;
|
||||
for (auto initializer : _scriptInitializers) {
|
||||
ii++;
|
||||
qDebug() << "initializer" << ii;
|
||||
initializer(scriptEngine);
|
||||
}
|
||||
return ii;
|
||||
|
|
|
@ -213,7 +213,7 @@ void setOctalCodeSectionValue(unsigned char* octalCode, int section, char sectio
|
|||
int byteForSection = (BITS_IN_OCTAL * section / BITS_IN_BYTE);
|
||||
unsigned char* byteAt = octalCode + 1 + byteForSection;
|
||||
char bitInByte = (BITS_IN_OCTAL * section) % BITS_IN_BYTE;
|
||||
char shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL;
|
||||
int8_t shiftBy = BITS_IN_BYTE - bitInByte - BITS_IN_OCTAL;
|
||||
const unsigned char UNSHIFTED_MASK = 0x07;
|
||||
unsigned char shiftedMask;
|
||||
unsigned char shiftedValue;
|
||||
|
|
|
@ -102,6 +102,9 @@ private:
|
|||
};
|
||||
|
||||
inline void traceEvent(const QLoggingCategory& category, const QString& name, EventType type, const QString& id = "", const QVariantMap& args = {}, const QVariantMap& extra = {}) {
|
||||
if (!DependencyManager::isSet<Tracer>()) {
|
||||
return;
|
||||
}
|
||||
const auto& tracer = DependencyManager::get<Tracer>();
|
||||
if (tracer) {
|
||||
tracer->traceEvent(category, name, type, id, args, extra);
|
||||
|
|
|
@ -22,6 +22,5 @@ namespace {
|
|||
}
|
||||
void MiniPromise::registerMetaTypes(QObject* engine) {
|
||||
auto scriptEngine = qobject_cast<QScriptEngine*>(engine);
|
||||
qDebug() << "----------------------- MiniPromise::registerMetaTypes ------------" << scriptEngine;
|
||||
qScriptRegisterMetaType(scriptEngine, promiseToScriptValue, promiseFromScriptValue);
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QLoggingCategory>
|
||||
#include "StorageLogging.h"
|
||||
|
||||
Q_LOGGING_CATEGORY(storagelogging, "hifi.core.storage")
|
||||
|
||||
|
@ -102,4 +102,4 @@ FileStorage::~FileStorage() {
|
|||
if (_file.isOpen()) {
|
||||
_file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
18
libraries/shared/src/shared/StorageLogging.h
Normal file
18
libraries/shared/src/shared/StorageLogging.h
Normal file
|
@ -0,0 +1,18 @@
|
|||
//
|
||||
// StorageLogging.h
|
||||
//
|
||||
// Created by Seth Alves on 2018-4-20
|
||||
// Copyright 2018 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_StorageLogging_h
|
||||
#define hifi_StorageLogging_h
|
||||
|
||||
#include <QtCore/QLoggingCategory>
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(storagelogging)
|
||||
|
||||
#endif // hifi_StorageLogging_h
|
|
@ -6,8 +6,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_Controllers_Logging_h
|
||||
#define hifi_Controllers_Logging_h
|
||||
#ifndef hifi_UI_Logging_h
|
||||
#define hifi_UI_Logging_h
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ class AudioHandler : public QObject, QRunnable {
|
|||
public:
|
||||
AudioHandler(OffscreenQmlSurface* surface, const QString& deviceName, QObject* parent = nullptr);
|
||||
|
||||
virtual ~AudioHandler() { qDebug() << "Audio Handler Destroyed"; }
|
||||
virtual ~AudioHandler() { }
|
||||
|
||||
void run() override;
|
||||
|
||||
|
@ -115,6 +115,7 @@ private:
|
|||
class UrlHandler : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UrlHandler(QObject* parent = nullptr) : QObject(parent) {}
|
||||
Q_INVOKABLE bool canHandleUrl(const QString& url) {
|
||||
static auto handler = dynamic_cast<AbstractUriHandler*>(qApp);
|
||||
return handler && handler->canAcceptURL(url);
|
||||
|
@ -223,6 +224,17 @@ void AudioHandler::run() {
|
|||
qDebug() << "QML Audio changed to " << _newTargetDevice;
|
||||
}
|
||||
|
||||
OffscreenQmlSurface::~OffscreenQmlSurface() {
|
||||
clearFocusItem();
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::clearFocusItem() {
|
||||
if (_currentFocusItem) {
|
||||
disconnect(_currentFocusItem, &QObject::destroyed, this, &OffscreenQmlSurface::focusDestroyed);
|
||||
}
|
||||
_currentFocusItem = nullptr;
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::initializeEngine(QQmlEngine* engine) {
|
||||
Parent::initializeEngine(engine);
|
||||
new QQmlFileSelector(engine);
|
||||
|
@ -246,7 +258,7 @@ void OffscreenQmlSurface::initializeEngine(QQmlEngine* engine) {
|
|||
|
||||
auto rootContext = engine->rootContext();
|
||||
rootContext->setContextProperty("GL", ::getGLContextData());
|
||||
rootContext->setContextProperty("urlHandler", new UrlHandler());
|
||||
rootContext->setContextProperty("urlHandler", new UrlHandler(rootContext));
|
||||
rootContext->setContextProperty("resourceDirectoryUrl", QUrl::fromLocalFile(PathUtils::resourcesPath()));
|
||||
rootContext->setContextProperty("ApplicationInterface", qApp);
|
||||
auto javaScriptToInject = getEventBridgeJavascript();
|
||||
|
@ -545,17 +557,15 @@ bool OffscreenQmlSurface::handlePointerEvent(const PointerEvent& event, class QT
|
|||
}
|
||||
|
||||
void OffscreenQmlSurface::focusDestroyed(QObject* obj) {
|
||||
if (_currentFocusItem) {
|
||||
disconnect(_currentFocusItem, &QObject::destroyed, this, &OffscreenQmlSurface::focusDestroyed);
|
||||
}
|
||||
_currentFocusItem = nullptr;
|
||||
clearFocusItem();
|
||||
}
|
||||
|
||||
void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
|
||||
clearFocusItem();
|
||||
|
||||
QQuickItem* item = static_cast<QQuickItem*>(object);
|
||||
if (!item) {
|
||||
setFocusText(false);
|
||||
_currentFocusItem = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -563,10 +573,6 @@ void OffscreenQmlSurface::onFocusObjectChanged(QObject* object) {
|
|||
qApp->sendEvent(object, &query);
|
||||
setFocusText(query.value(Qt::ImEnabled).toBool());
|
||||
|
||||
if (_currentFocusItem) {
|
||||
disconnect(_currentFocusItem, &QObject::destroyed, this, 0);
|
||||
}
|
||||
|
||||
// Raise and lower keyboard for QML text fields.
|
||||
// HTML text fields are handled in emitWebEvent() methods - testing READ_ONLY_PROPERTY prevents action for HTML files.
|
||||
const char* READ_ONLY_PROPERTY = "readOnly";
|
||||
|
|
|
@ -22,7 +22,8 @@ class OffscreenQmlSurface : public hifi::qml::OffscreenSurface {
|
|||
Q_OBJECT
|
||||
Q_PROPERTY(bool focusText READ isFocusText NOTIFY focusTextChanged)
|
||||
public:
|
||||
|
||||
~OffscreenQmlSurface();
|
||||
|
||||
static void addWhitelistContextHandler(const std::initializer_list<QUrl>& urls, const QmlContextCallback& callback);
|
||||
static void addWhitelistContextHandler(const QUrl& url, const QmlContextCallback& callback) { addWhitelistContextHandler({ { url } }, callback); };
|
||||
|
||||
|
@ -58,6 +59,7 @@ public slots:
|
|||
void sendToQml(const QVariant& message);
|
||||
|
||||
protected:
|
||||
void clearFocusItem();
|
||||
void setFocusText(bool newFocusText);
|
||||
void initializeEngine(QQmlEngine* engine) override;
|
||||
void onRootContextCreated(QQmlContext* qmlContext) override;
|
||||
|
|
|
@ -1291,6 +1291,7 @@ function cleanupModelMenus() {
|
|||
Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE);
|
||||
Menu.removeMenuItem("Edit", MENU_CREATE_ENTITIES_GRABBABLE);
|
||||
}
|
||||
|
||||
Script.scriptEnding.connect(function () {
|
||||
|
|
|
@ -321,7 +321,8 @@
|
|||
{
|
||||
id: "alpha",
|
||||
name: "Alpha",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -329,7 +330,8 @@
|
|||
{
|
||||
id: "alphaSpread",
|
||||
name: "Alpha Spread",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -337,7 +339,8 @@
|
|||
{
|
||||
id: "alphaStart",
|
||||
name: "Alpha Start",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
@ -345,7 +348,8 @@
|
|||
{
|
||||
id: "alphaFinish",
|
||||
name: "Alpha Finish",
|
||||
type: "SliderFloat"
|
||||
type: "SliderFloat",
|
||||
max: 1.0
|
||||
},
|
||||
{
|
||||
type: "Row"
|
||||
|
|
|
@ -23,5 +23,9 @@ if (WIN32)
|
|||
add_dependency_external_projects(wasapi)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_link_libraries(${TARGET_NAME} atomic)
|
||||
endif()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
endif()
|
||||
|
|
47
tests/qml/qml/controls/WebEntityView.qml
Normal file
47
tests/qml/qml/controls/WebEntityView.qml
Normal file
|
@ -0,0 +1,47 @@
|
|||
//
|
||||
// WebEntityView.qml
|
||||
//
|
||||
// Created by Kunal Gosar on 16 March 2017
|
||||
// Copyright 2017 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
|
||||
//
|
||||
|
||||
import QtQuick 2.5
|
||||
import QtWebEngine 1.5
|
||||
import Hifi 1.0
|
||||
|
||||
/*
|
||||
TestItem {
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
color: "blue"
|
||||
property string url: ""
|
||||
ColorAnimation on color {
|
||||
loops: Animation.Infinite; from: "blue"; to: "yellow"; duration: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
WebEngineView {
|
||||
id: webViewCore
|
||||
objectName: "webEngineView"
|
||||
width: parent !== null ? parent.width : undefined
|
||||
height: parent !== null ? parent.height : undefined
|
||||
|
||||
onFeaturePermissionRequested: {
|
||||
grantFeaturePermission(securityOrigin, feature, true);
|
||||
}
|
||||
|
||||
//disable popup
|
||||
onContextMenuRequested: {
|
||||
request.accepted = true;
|
||||
}
|
||||
|
||||
onNewViewRequested: {
|
||||
newViewRequestedCallback(request)
|
||||
}
|
||||
}
|
|
@ -28,52 +28,87 @@
|
|||
#include <QtGui/QImage>
|
||||
#include <QtGui/QOpenGLFunctions_4_5_Core>
|
||||
#include <QtGui/QOpenGLContext>
|
||||
|
||||
#include <QtQuick/QQuickItem>
|
||||
#include <QtQml/QQmlContext>
|
||||
#include <QtQml/QQmlComponent>
|
||||
|
||||
#include <SettingInterface.h>
|
||||
|
||||
#include <gl/OffscreenGLCanvas.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <PathUtils.h>
|
||||
#include <NumericalConstants.h>
|
||||
#include <PerfStat.h>
|
||||
#include <PathUtils.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include <qml/OffscreenSurface.h>
|
||||
#include <unordered_set>
|
||||
#include <array>
|
||||
|
||||
namespace gl {
|
||||
extern void initModuleGl();
|
||||
}
|
||||
|
||||
class OffscreenQmlSurface : public hifi::qml::OffscreenSurface {
|
||||
class QTestItem : public QQuickItem {
|
||||
Q_OBJECT
|
||||
public:
|
||||
QTestItem(QQuickItem* parent = nullptr) : QQuickItem(parent) { qDebug() << __FUNCTION__; }
|
||||
|
||||
~QTestItem() { qDebug() << __FUNCTION__; }
|
||||
};
|
||||
|
||||
QUrl getTestResource(const QString& relativePath) {
|
||||
static QString dir;
|
||||
if (dir.isEmpty()) {
|
||||
QDir path(__FILE__);
|
||||
path.cdUp();
|
||||
dir = path.cleanPath(path.absoluteFilePath("../")) + "/";
|
||||
qDebug() << "Resources Path: " << dir;
|
||||
}
|
||||
return QUrl::fromLocalFile(dir + relativePath);
|
||||
}
|
||||
|
||||
#define DIVISIONS_X 5
|
||||
#define DIVISIONS_Y 5
|
||||
|
||||
using QmlPtr = QSharedPointer<hifi::qml::OffscreenSurface>;
|
||||
using TextureAndFence = hifi::qml::OffscreenSurface::TextureAndFence;
|
||||
|
||||
struct QmlInfo {
|
||||
QmlPtr surface;
|
||||
GLuint texture{ 0 };
|
||||
uint64_t lifetime{ 0 };
|
||||
};
|
||||
|
||||
class TestWindow : public QWindow {
|
||||
|
||||
public:
|
||||
TestWindow();
|
||||
|
||||
|
||||
private:
|
||||
using TextureAndFence = hifi::qml::OffscreenSurface::TextureAndFence;
|
||||
QOpenGLContext _glContext;
|
||||
OffscreenGLCanvas _sharedContext;
|
||||
OffscreenQmlSurface _offscreenQml;
|
||||
std::array<std::array<QmlInfo, DIVISIONS_Y>, DIVISIONS_X> _surfaces;
|
||||
|
||||
QOpenGLFunctions_4_5_Core _glf;
|
||||
uint32_t _currentTexture{ 0 };
|
||||
GLsync _readFence{ 0 };
|
||||
std::function<void(uint32_t, void*)> _discardLamdba;
|
||||
QSize _size;
|
||||
size_t _surfaceCount{ 0 };
|
||||
GLuint _fbo{ 0 };
|
||||
const QSize _qmlSize{ 640, 480 };
|
||||
bool _aboutToQuit{ false };
|
||||
uint64_t _createStopTime;
|
||||
void initGl();
|
||||
void updateSurfaces();
|
||||
void buildSurface(QmlInfo& qmlInfo, bool allowVideo);
|
||||
void destroySurface(QmlInfo& qmlInfo);
|
||||
void resizeWindow(const QSize& size);
|
||||
void draw();
|
||||
void resizeEvent(QResizeEvent* ev) override;
|
||||
};
|
||||
|
||||
TestWindow::TestWindow() {
|
||||
setSurfaceType(QSurface::OpenGLSurface);
|
||||
Setting::init();
|
||||
|
||||
setSurfaceType(QSurface::OpenGLSurface);
|
||||
QSurfaceFormat format;
|
||||
format.setDepthBufferSize(24);
|
||||
format.setStencilBufferSize(8);
|
||||
|
@ -83,13 +118,16 @@ TestWindow::TestWindow() {
|
|||
QSurfaceFormat::setDefaultFormat(format);
|
||||
setFormat(format);
|
||||
|
||||
qmlRegisterType<QTestItem>("Hifi", 1, 0, "TestItem");
|
||||
|
||||
show();
|
||||
_createStopTime = usecTimestampNow() + (3000u * USECS_PER_SECOND);
|
||||
|
||||
resize(QSize(800, 600));
|
||||
|
||||
auto timer = new QTimer(this);
|
||||
timer->setTimerType(Qt::PreciseTimer);
|
||||
timer->setInterval(5);
|
||||
timer->setInterval(30);
|
||||
connect(timer, &QTimer::timeout, [&] { draw(); });
|
||||
timer->start();
|
||||
|
||||
|
@ -97,7 +135,6 @@ TestWindow::TestWindow() {
|
|||
timer->stop();
|
||||
_aboutToQuit = true;
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
void TestWindow::initGl() {
|
||||
|
@ -105,6 +142,7 @@ void TestWindow::initGl() {
|
|||
if (!_glContext.create() || !_glContext.makeCurrent(this)) {
|
||||
qFatal("Unable to intialize Window GL context");
|
||||
}
|
||||
gl::initModuleGl();
|
||||
|
||||
_glf.initializeOpenGLFunctions();
|
||||
_glf.glCreateFramebuffers(1, &_fbo);
|
||||
|
@ -113,15 +151,97 @@ void TestWindow::initGl() {
|
|||
qFatal("Unable to intialize Shared GL context");
|
||||
}
|
||||
hifi::qml::OffscreenSurface::setSharedContext(_sharedContext.getContext());
|
||||
_discardLamdba = _offscreenQml.getDiscardLambda();
|
||||
_offscreenQml.resize({ 640, 480 });
|
||||
_offscreenQml.load(QUrl::fromLocalFile("C:/Users/bdavi/Git/hifi/tests/qml/qml/main.qml"));
|
||||
_discardLamdba = hifi::qml::OffscreenSurface::getDiscardLambda();
|
||||
}
|
||||
|
||||
void TestWindow::resizeWindow(const QSize& size) {
|
||||
_size = size;
|
||||
}
|
||||
|
||||
static const int DEFAULT_MAX_FPS = 10;
|
||||
static const QString CONTROL_URL{ "/qml/controls/WebEntityView.qml" };
|
||||
static const char* URL_PROPERTY{ "url" };
|
||||
|
||||
QString getSourceUrl(bool video) {
|
||||
static const std::vector<QString> SOURCE_URLS{
|
||||
"https://www.reddit.com/wiki/random",
|
||||
"https://en.wikipedia.org/wiki/Wikipedia:Random",
|
||||
"https://slashdot.org/",
|
||||
};
|
||||
|
||||
static const std::vector<QString> VIDEO_SOURCE_URLS{
|
||||
"https://www.youtube.com/watch?v=gDXwhHm4GhM",
|
||||
"https://www.youtube.com/watch?v=Ch_hoYPPeGc",
|
||||
};
|
||||
|
||||
const auto& sourceUrls = video ? VIDEO_SOURCE_URLS : SOURCE_URLS;
|
||||
auto index = rand() % sourceUrls.size();
|
||||
return sourceUrls[index];
|
||||
}
|
||||
|
||||
void TestWindow::buildSurface(QmlInfo& qmlInfo, bool video) {
|
||||
++_surfaceCount;
|
||||
auto lifetimeSecs = (uint32_t)(5.0f + (randFloat() * 10.0f));
|
||||
auto lifetimeUsecs = (USECS_PER_SECOND * lifetimeSecs);
|
||||
qmlInfo.lifetime = lifetimeUsecs + usecTimestampNow();
|
||||
qmlInfo.texture = 0;
|
||||
qmlInfo.surface.reset(new hifi::qml::OffscreenSurface());
|
||||
qmlInfo.surface->load(getTestResource(CONTROL_URL), [video](QQmlContext* context, QQuickItem* item) {
|
||||
item->setProperty(URL_PROPERTY, getSourceUrl(video));
|
||||
});
|
||||
qmlInfo.surface->setMaxFps(DEFAULT_MAX_FPS);
|
||||
qmlInfo.surface->resize(_qmlSize);
|
||||
qmlInfo.surface->resume();
|
||||
}
|
||||
|
||||
void TestWindow::destroySurface(QmlInfo& qmlInfo) {
|
||||
auto& surface = qmlInfo.surface;
|
||||
auto webView = surface->getRootItem();
|
||||
if (webView) {
|
||||
// stop loading
|
||||
QMetaObject::invokeMethod(webView, "stop");
|
||||
webView->setProperty(URL_PROPERTY, "about:blank");
|
||||
}
|
||||
surface->pause();
|
||||
surface.reset();
|
||||
}
|
||||
|
||||
void TestWindow::updateSurfaces() {
|
||||
auto now = usecTimestampNow();
|
||||
// Fetch any new textures
|
||||
for (size_t x = 0; x < DIVISIONS_X; ++x) {
|
||||
for (size_t y = 0; y < DIVISIONS_Y; ++y) {
|
||||
auto& qmlInfo = _surfaces[x][y];
|
||||
if (!qmlInfo.surface) {
|
||||
if (now < _createStopTime && randFloat() > 0.99f) {
|
||||
buildSurface(qmlInfo, x == 0 && y == 0);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (now > qmlInfo.lifetime) {
|
||||
destroySurface(qmlInfo);
|
||||
continue;
|
||||
}
|
||||
|
||||
auto& surface = qmlInfo.surface;
|
||||
auto& currentTexture = qmlInfo.texture;
|
||||
|
||||
TextureAndFence newTextureAndFence;
|
||||
if (surface->fetchTexture(newTextureAndFence)) {
|
||||
if (currentTexture != 0) {
|
||||
auto readFence = _glf.glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
glFlush();
|
||||
_discardLamdba(currentTexture, readFence);
|
||||
}
|
||||
currentTexture = newTextureAndFence.first;
|
||||
_glf.glWaitSync((GLsync)newTextureAndFence.second, 0, GL_TIMEOUT_IGNORED);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestWindow::draw() {
|
||||
if (_aboutToQuit) {
|
||||
return;
|
||||
|
@ -140,38 +260,30 @@ void TestWindow::draw() {
|
|||
return;
|
||||
}
|
||||
|
||||
updateSurfaces();
|
||||
|
||||
auto size = this->geometry().size();
|
||||
auto incrementX = size.width() / DIVISIONS_X;
|
||||
auto incrementY = size.height() / DIVISIONS_Y;
|
||||
_glf.glViewport(0, 0, size.width(), size.height());
|
||||
_glf.glClearColor(1, 0, 0, 1);
|
||||
_glf.glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
TextureAndFence newTextureAndFence;
|
||||
if (_offscreenQml.fetchTexture(newTextureAndFence)) {
|
||||
if (_currentTexture) {
|
||||
_discardLamdba(_currentTexture, _readFence);
|
||||
_readFence = 0;
|
||||
for (uint32_t x = 0; x < DIVISIONS_X; ++x) {
|
||||
for (uint32_t y = 0; y < DIVISIONS_Y; ++y) {
|
||||
auto& qmlInfo = _surfaces[x][y];
|
||||
if (!qmlInfo.surface || !qmlInfo.texture) {
|
||||
continue;
|
||||
}
|
||||
_glf.glNamedFramebufferTexture(_fbo, GL_COLOR_ATTACHMENT0, qmlInfo.texture, 0);
|
||||
_glf.glBlitNamedFramebuffer(_fbo, 0,
|
||||
// src coordinates
|
||||
0, 0, _qmlSize.width() - 1, _qmlSize.height() - 1,
|
||||
// dst coordinates
|
||||
incrementX * x, incrementY * y, incrementX * (x + 1), incrementY * (y + 1),
|
||||
// blit mask and filter
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
_currentTexture = newTextureAndFence.first;
|
||||
_glf.glWaitSync((GLsync)newTextureAndFence.second, 0, GL_TIMEOUT_IGNORED);
|
||||
_glf.glNamedFramebufferTexture(_fbo, GL_COLOR_ATTACHMENT0, _currentTexture, 0);
|
||||
}
|
||||
|
||||
auto diff = _size - _qmlSize;
|
||||
diff /= 2;
|
||||
auto qmlExtent = diff + _qmlSize;
|
||||
|
||||
if (_currentTexture) {
|
||||
_glf.glBlitNamedFramebuffer(_fbo, 0,
|
||||
0, 0, _qmlSize.width() - 1, _qmlSize.height() - 1,
|
||||
diff.width(), diff.height(), qmlExtent.width() - 1, qmlExtent.height() - 2,
|
||||
GL_COLOR_BUFFER_BIT, GL_NEAREST);
|
||||
}
|
||||
|
||||
if (_readFence) {
|
||||
_glf.glDeleteSync(_readFence);
|
||||
}
|
||||
_readFence = _glf.glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
_glf.glFlush();
|
||||
|
||||
_glContext.swapBuffers(this);
|
||||
}
|
||||
|
||||
|
@ -180,11 +292,9 @@ void TestWindow::resizeEvent(QResizeEvent* ev) {
|
|||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
setupHifiApplication("QML Test");
|
||||
|
||||
QGuiApplication app(argc, argv);
|
||||
TestWindow window;
|
||||
app.exec();
|
||||
return 0;
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
#include "main.moc"
|
||||
|
|
|
@ -27,6 +27,10 @@ if (WIN32)
|
|||
add_dependency_external_projects(wasapi)
|
||||
endif()
|
||||
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
target_link_libraries(${TARGET_NAME} atomic)
|
||||
endif()
|
||||
|
||||
package_libraries_for_deployment()
|
||||
|
||||
|
||||
|
|
|
@ -94,20 +94,20 @@ exports.handlers = {
|
|||
if (e.doclet.hifiInterface) {
|
||||
rows.push("Interface Scripts");
|
||||
}
|
||||
if (e.doclet.hifiAssignmentClient) {
|
||||
rows.push("Assignment Client Scripts");
|
||||
}
|
||||
if (e.doclet.hifiClientEntity) {
|
||||
rows.push("Client Entity Scripts");
|
||||
}
|
||||
if (e.doclet.hifiServerEntity) {
|
||||
rows.push("Server Entity Scripts");
|
||||
}
|
||||
if (e.doclet.hifiAssignmentClient) {
|
||||
rows.push("Assignment Client Scripts");
|
||||
}
|
||||
|
||||
// Append an Available In: table at the end of the namespace description.
|
||||
if (rows.length > 0) {
|
||||
var table = "<br><br><table><td>Available In:<td>" + rows.join("<td>") + "</table>";
|
||||
e.doclet.description = e.doclet.description + table;
|
||||
var table = "<br><br><table><tr><th>Available in:</th><td>" + rows.join("</td><td>") + "</td></tr></table>";
|
||||
e.doclet.description = (e.doclet.description ? e.doclet.description : "") + table;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +124,7 @@ exports.defineTags = function (dictionary) {
|
|||
});
|
||||
|
||||
// @hifi-assignment-client
|
||||
dictionary.defineTag("hifi-assigment-client", {
|
||||
dictionary.defineTag("hifi-assignment-client", {
|
||||
onTagged: function (doclet, tag) {
|
||||
doclet.hifiAssignmentClient = true;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue