Merge pull request #5 from kasenvr/master

Upgrading to last master branch
This commit is contained in:
Alezia Kurdis 2020-09-17 19:38:24 -04:00 committed by GitHub
commit f8cbf74b37
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 256 additions and 72 deletions

View file

@ -80,6 +80,13 @@ Where /path/to/directory is the path to a directory where you wish the build fil
// The type of release.
RELEASE_TYPE=PRODUCTION|PR|DEV
// The Interface will have a custom default home and startup location.
INITIAL_STARTUP_LOCATION=Location/IP/URL
// Code-signing environment variables must be set during runtime of CMake AND globally when the signing takes place.
HF_PFX_FILE=Path to certificate
HF_PFX_PASSPHRASE=Passphrase for certificate
// Determine the build type
PRODUCTION_BUILD=0|1
PR_BUILD=0|1

View file

@ -1,5 +1,7 @@
# Creating an Installer
*Last Updated on August 24, 2020*
Follow the [build guide](BUILD.md) to figure out how to build Vircadia for your platform.
During generation, CMake should produce an `install` target and a `package` target.
@ -13,6 +15,8 @@ To produce an installer, run the `package` target. However you will want to foll
#### Windows
##### Prerequisites
To produce an executable installer on Windows, the following are required:
1. [7-zip](<https://www.7-zip.org/download.html>)
@ -59,6 +63,12 @@ To produce an executable installer on Windows, the following are required:
1. [Node.JS and NPM](<https://www.npmjs.com/get-npm>)
1. Install version 10.15.0 LTS
##### Code Signing (optional)
For code signing to work, you will need to set the `HF_PFX_FILE` and `HF_PFX_PASSPHRASE` environment variables to be present during CMake runtime and globally as we proceed to package the installer.
##### Creating the Installer
1. Perform a clean cmake from a new terminal.
1. Open the `vircadia.sln` solution with elevated (administrator) permissions on Visual Studio and select the **Release** configuration.
1. Build the solution.

View file

@ -183,7 +183,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
}
QString assignmentServerHostname;
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) {
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION)) {
assignmentServerHostname = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_HOSTNAME_OPTION).toString();
}
if (parser.isSet(assignmentServerHostnameOption)) {
@ -192,7 +192,7 @@ AssignmentClientApp::AssignmentClientApp(int argc, char* argv[]) :
// check for an overriden assignment server port
quint16 assignmentServerPort = DEFAULT_DOMAIN_SERVER_PORT;
if (argumentVariantMap.contains(ASSIGNMENT_WALLET_DESTINATION_ID_OPTION)) {
if (argumentVariantMap.contains(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION)) {
assignmentServerPort = argumentVariantMap.value(CUSTOM_ASSIGNMENT_SERVER_PORT_OPTION).toUInt();
}

View file

@ -23,6 +23,7 @@ macro(SET_PACKAGING_PARAMETERS)
set_from_env(RELEASE_TYPE RELEASE_TYPE "DEV")
set_from_env(RELEASE_NUMBER RELEASE_NUMBER "")
set_from_env(STABLE_BUILD STABLE_BUILD 0)
set_from_env(INITIAL_STARTUP_LOCATION INITIAL_STARTUP_LOCATION "")
message(STATUS "The RELEASE_TYPE variable is: ${RELEASE_TYPE}")

View file

@ -22,11 +22,12 @@ namespace BuildInfo {
const QString DOMAIN_SERVER_NAME = "domain-server";
const QString AC_CLIENT_SERVER_NAME = "ac-client";
const QString MODIFIED_ORGANIZATION = "@BUILD_ORGANIZATION@";
const QString ORGANIZATION_DOMAIN = "highfidelity.io";
const QString ORGANIZATION_DOMAIN = "vircadia.com";
const QString VERSION = "@BUILD_VERSION@";
const QString BUILD_NUMBER = "@BUILD_NUMBER@";
const QString BUILD_GLOBAL_SERVICES = "@BUILD_GLOBAL_SERVICES@";
const QString BUILD_TIME = "@BUILD_TIME@";
const QString INITIAL_STARTUP_LOCATION = "@INITIAL_STARTUP_LOCATION@";
enum BuildType {
Dev,

View file

@ -49,6 +49,12 @@ ScrollingWindow {
desktop.setAutoAdd(auto);
}
function openExternalBrowser() {
Qt.openUrlExternally(addressBar.text);
root.shown = false;
root.windowClosed();
}
Item {
id:item
width: pane.contentWidth
@ -58,34 +64,49 @@ ScrollingWindow {
id: buttons
spacing: 4
anchors.top: parent.top
anchors.topMargin: 8
anchors.topMargin: 4
anchors.left: parent.left
anchors.leftMargin: 8
HiFiGlyphs {
id: back;
enabled: webview.canGoBack;
id: back
enabled: webview.canGoBack
text: hifi.glyphs.backward
color: enabled ? hifi.colors.text : hifi.colors.disabledText
color: enabled ? (backMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goBack() }
MouseArea {
id: backMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.goBack();
}
}
HiFiGlyphs {
id: forward;
enabled: webview.canGoForward;
id: forward
enabled: webview.canGoForward
text: hifi.glyphs.forward
color: enabled ? hifi.colors.text : hifi.colors.disabledText
color: enabled ? (forwardMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
MouseArea {
id: forwardMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.goForward();
}
}
HiFiGlyphs {
id: reload;
enabled: webview.canGoForward;
id: reload
enabled: url !== ""
text: webview.loading ? hifi.glyphs.close : hifi.glyphs.reload
color: enabled ? hifi.colors.text : hifi.colors.disabledText
color: enabled ? (reloadMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 48
MouseArea { anchors.fill: parent; onClicked: webview.goForward() }
MouseArea {
id: reloadMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: webview.loading ? webview.stop() : webview.reload();
}
}
}
@ -94,52 +115,82 @@ ScrollingWindow {
id: border
height: 48
anchors.top: parent.top
anchors.topMargin: 8
anchors.topMargin: 4
anchors.right: parent.right
anchors.rightMargin: 8
anchors.left: buttons.right
anchors.leftMargin: 8
HiFiGlyphs {
id: externalBrowser
anchors.right: parent.right
anchors.top: parent.top
anchors.topMargin: 4
enabled: !HMD.active && url !== ""
font.family: "FontAwesome"
text: "\uf24d"
rotation: -90
color: enabled ? (externalBrowserMouseArea.containsMouse ? hifi.colors.blueHighlight : hifi.colors.faintGray) : hifi.colors.lightGray
size: 32
MouseArea {
id: externalBrowserMouseArea
anchors.fill: parent
hoverEnabled: true
onClicked: openExternalBrowser();
}
}
Item {
id: barIcon
width: parent.height
height: parent.height
Image {
source: webview.icon;
source: webview.loading ? "" : webview.icon
x: (parent.height - height) / 2
y: (parent.width - width) / 2
sourceSize: Qt.size(width, height);
verticalAlignment: Image.AlignVCenter;
width: 28
height: 28
verticalAlignment: Image.AlignVCenter
horizontalAlignment: Image.AlignHCenter
}
}
TextField {
id: addressBar
anchors.right: parent.right
anchors.rightMargin: 8
anchors.right: externalBrowser.left
anchors.rightMargin: 32
anchors.left: barIcon.right
anchors.leftMargin: 0
anchors.verticalCenter: parent.verticalCenter
focus: true
colorScheme: hifi.colorSchemes.dark
placeholderText: "Enter URL"
inputMethodHints: Qt.ImhUrlCharactersOnly
Component.onCompleted: ScriptDiscoveryService.scriptsModelFilter.filterRegExp = new RegExp("^.*$", "i")
Keys.onPressed: {
switch(event.key) {
case Qt.Key_Enter:
case Qt.Key_Return:
event.accepted = true
if (text.indexOf("http") != 0) {
if (text.indexOf("http") !== 0) {
text = "http://" + text;
}
// Setting webiew.url directly doesn't add the URL to the navigation history.
//webview.url = text;
// The following works around this bug.
text = encodeURI(text);
text = text.replace(/;/g, "%3b"); // Prevent script injection.
text = text.replace(/'/g, "%25"); // ""
webview.runJavaScript("window.location='" + text + "'");
root.hidePermissionsBar();
root.keyboardRaised = false;
webview.url = text;
break;
}
}
}
}
Rectangle {
@ -204,7 +255,7 @@ ScrollingWindow {
parentRoot: root
anchors.top: buttons.bottom
anchors.topMargin: 8
anchors.topMargin: 4
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
@ -216,7 +267,7 @@ ScrollingWindow {
Keys.onPressed: {
switch(event.key) {
case Qt.Key_L:
if (event.modifiers == Qt.ControlModifier) {
if (event.modifiers === Qt.ControlModifier) {
event.accepted = true
addressBar.selectAll()
addressBar.forceActiveFocus()
@ -224,4 +275,5 @@ ScrollingWindow {
break;
}
}
} // dialog

View file

@ -3976,6 +3976,11 @@ void Application::handleSandboxStatus(QNetworkReply* reply) {
// If this is a first run we short-circuit the address passed in
if (_firstRun.get()) {
if (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty()) {
DependencyManager::get<LocationBookmarks>()->setHomeLocationToAddress(NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS);
Menu::getInstance()->triggerOption(MenuOption::HomeLocation);
}
if (!_overrideEntry) {
DependencyManager::get<AddressManager>()->goToEntry();
sentTo = SENT_TO_ENTRY;
@ -7105,9 +7110,9 @@ void Application::updateWindowTitle() const {
QString currentPlaceName;
if (isServerlessMode()) {
if (isInErrorState) {
currentPlaceName = "serverless: " + nodeList->getDomainHandler().getErrorDomainURL().toString();
currentPlaceName = "Serverless: " + nodeList->getDomainHandler().getErrorDomainURL().toString();
} else {
currentPlaceName = "serverless: " + DependencyManager::get<AddressManager>()->getDomainURL().toString();
currentPlaceName = "Serverless: " + DependencyManager::get<AddressManager>()->getDomainURL().toString();
}
} else {
currentPlaceName = DependencyManager::get<AddressManager>()->getDomainURL().host();

View file

@ -238,11 +238,11 @@ Menu::Menu() {
// Navigate > Start-up Location
MenuWrapper* startupLocationMenu = navigateMenu->addMenu(MenuOption::StartUpLocation);
QActionGroup* startupLocatiopnGroup = new QActionGroup(startupLocationMenu);
startupLocatiopnGroup->setExclusive(true);
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::HomeLocation, 0,
QActionGroup* startupLocationGroup = new QActionGroup(startupLocationMenu);
startupLocationGroup->setExclusive(true);
startupLocationGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::HomeLocation, 0,
false));
startupLocatiopnGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::LastLocation, 0,
startupLocationGroup->addAction(addCheckableActionToQMenuAndActionHash(startupLocationMenu, MenuOption::LastLocation, 0,
true));
// Settings menu ----------------------------------

View file

@ -2072,7 +2072,6 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi
// NOTE: device start() uses the Qt internal device list
Lock lock(_deviceMutex);
Lock localAudioLock(_localAudioMutex);
_localSamplesAvailable.exchange(0, std::memory_order_release);
//wait on local injectors prep to finish running
@ -2080,6 +2079,8 @@ bool AudioClient::switchOutputToAudioDevice(const HifiAudioDeviceInfo outputDevi
_localPrepInjectorFuture.waitForFinished();
}
Lock localAudioLock(_localAudioMutex);
// cleanup any previously initialized device
if (_audioOutput) {
_audioOutputIODevice.close();

View file

@ -1460,6 +1460,31 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
emit requestRenderUpdate();
}
if (!_allProceduralMaterialsLoaded) {
std::lock_guard<std::mutex> lock(_materialsLock);
bool allProceduralMaterialsLoaded = true;
for (auto& shapeMaterialPair : _materials) {
auto material = shapeMaterialPair.second;
while (!material.empty()) {
auto mat = material.top();
if (mat.material && mat.material->isProcedural() && !mat.material->isReady()) {
allProceduralMaterialsLoaded = false;
break;
}
material.pop();
}
if (!allProceduralMaterialsLoaded) {
break;
}
}
if (!allProceduralMaterialsLoaded) {
emit requestRenderUpdate();
} else {
_allProceduralMaterialsLoaded = true;
model->setRenderItemsNeedUpdate();
}
}
// When the individual mesh parts of a model finish fading, they will mark their Model as needing updating
// we will watch for that and ask the model to update it's render items
if (model->getRenderItemsNeedUpdate()) {
@ -1584,6 +1609,10 @@ void ModelEntityRenderer::addMaterial(graphics::MaterialLayer material, const st
if (_model && _model->fetchRenderItemIDs().size() > 0) {
_model->addMaterial(material, parentMaterialName);
}
if (material.material && material.material->isProcedural()) {
_allProceduralMaterialsLoaded = false;
emit requestRenderUpdate();
}
}
void ModelEntityRenderer::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {

View file

@ -202,10 +202,10 @@ private:
bool _prevModelLoaded { false };
void processMaterials();
bool _allProceduralMaterialsLoaded { false };
static void metaBlendshapeOperator(render::ItemID renderItemID, int blendshapeNumber, const QVector<BlendshapeOffset>& blendshapeOffsets,
const QVector<int>& blendedMeshSizes, const render::ItemIDs& subItemIDs);
};
} } // namespace

View file

@ -32,7 +32,7 @@ bool ShapeEntityRenderer::needsRenderUpdate() const {
if (resultWithReadLock<bool>([&] {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() &&
mat->second.top().material->isEnabled()) {
mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
return true;
@ -88,7 +88,7 @@ void ShapeEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce
void ShapeEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) {
withReadLock([&] {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isEnabled()) {
if (mat != _materials.end() && mat->second.top().material && mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
procedural->setIsFading(Interpolate::calculateFadeRatio(procedural->getFadeStartTime()) < 1.0f);
@ -140,7 +140,7 @@ bool ShapeEntityRenderer::isTransparent() const {
auto mat = _materials.find("0");
if (mat != _materials.end() && mat->second.top().material) {
if (mat->second.top().material->isProcedural() && mat->second.top().material->isEnabled()) {
if (mat->second.top().material->isProcedural() && mat->second.top().material->isReady()) {
auto procedural = std::static_pointer_cast<graphics::ProceduralMaterial>(mat->second.top().material);
if (procedural->isFading()) {
return true;

View file

@ -746,6 +746,10 @@ QString ModelEntityItem::getBlendshapeCoefficients() const {
}
void ModelEntityItem::setBlendshapeCoefficients(const QString& blendshapeCoefficients) {
if (blendshapeCoefficients.isEmpty()) {
return;
}
QJsonParseError error;
QJsonDocument newCoefficientsJSON = QJsonDocument::fromJson(blendshapeCoefficients.toUtf8(), &error);
if (error.error != QJsonParseError::NoError) {

View file

@ -1019,6 +1019,8 @@ bool GLTFSerializer::buildGeometry(HFMModel& hfmModel, const hifi::VariantHash&
hfmModel.meshes.append(HFMMesh());
HFMMesh& mesh = hfmModel.meshes[hfmModel.meshes.size() - 1];
mesh.modelTransform = globalTransforms[nodeIndex];
if (!hfmModel.hasSkeletonJoints) {
HFMCluster cluster;
cluster.jointIndex = nodecount;

View file

@ -27,16 +27,22 @@
#include "NodeList.h"
#include "NetworkLogging.h"
#include "NetworkingConstants.h"
#include "UserActivityLogger.h"
#include "udt/PacketHeaders.h"
const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json";
const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json";
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
const QString REDIRECT_HIFI_ADDRESS = NetworkingConstants::REDIRECT_HIFI_ADDRESS;
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_HIFI_ADDRESS);
const QString DEFAULT_VIRCADIA_ADDRESS = (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty())
? BuildInfo::INITIAL_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
const QString DEFAULT_HOME_ADDRESS = (!BuildInfo::INITIAL_STARTUP_LOCATION.isEmpty())
? BuildInfo::INITIAL_STARTUP_LOCATION
: NetworkingConstants::DEFAULT_VIRCADIA_ADDRESS;
Setting::Handle<QUrl> currentAddressHandle(QStringList() << ADDRESS_MANAGER_SETTINGS_GROUP << "address", DEFAULT_VIRCADIA_ADDRESS);
bool AddressManager::isConnected() {
return DependencyManager::get<NodeList>()->getDomainHandler().isConnected();

View file

@ -22,8 +22,8 @@
#include "AccountManager.h"
extern const QString DEFAULT_HIFI_ADDRESS;
extern const QString REDIRECT_HIFI_ADDRESS;
extern const QString DEFAULT_VIRCADIA_ADDRESS;
extern const QString DEFAULT_HOME_ADDRESS;
const QString SANDBOX_HIFI_ADDRESS = "hifi://localhost";
@ -292,7 +292,8 @@ public slots:
* location history is correctly maintained.
*/
void goToLocalSandbox(QString path = "", LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger); }
handleUrl(SANDBOX_HIFI_ADDRESS + path, trigger);
}
/**jsdoc
* Takes you to the default "welcome" metaverse address.
@ -300,7 +301,9 @@ public slots:
* @param {location.LookupTrigger} trigger=StartupFromSettings - The reason for the function call. Helps ensure that user's
* location history is correctly maintained.
*/
void goToEntry(LookupTrigger trigger = LookupTrigger::StartupFromSettings) { handleUrl(DEFAULT_HIFI_ADDRESS, trigger); }
void goToEntry(LookupTrigger trigger = LookupTrigger::StartupFromSettings) {
handleUrl(DEFAULT_VIRCADIA_ADDRESS, trigger);
}
/**jsdoc
* Takes you to the specified user's location.

View file

@ -57,6 +57,9 @@ namespace NetworkingConstants {
const QUrl HELP_RELEASE_NOTES_URL{ "https://docs.vircadia.dev/release-notes.html" };
const QUrl HELP_BUG_REPORT_URL{ "https://github.com/kasenvr/project-athena/issues" };
const QString DEFAULT_VIRCADIA_ADDRESS = "file:///~/serverless/tutorial.json";
const QString DEFAULT_HOME_ADDRESS = "file:///~/serverless/tutorial.json";
const QString REDIRECT_HIFI_ADDRESS = "file:///~/serverless/redirect.json";
}
const QString HIFI_URL_SCHEME_ABOUT = "about";

View file

@ -520,8 +520,7 @@ void ModelMeshPartPayload::render(RenderArgs* args) {
batch.setDrawcallUniform(drawcallInfo);
}
if (!_drawMaterials.empty() && _drawMaterials.top().material && _drawMaterials.top().material->isProcedural() &&
_drawMaterials.top().material->isReady()) {
if (_shapeKey.hasOwnPipeline()) {
if (!(enableMaterialProceduralShaders)) {
return;
}

View file

@ -12,7 +12,9 @@
#include "ContextAwareProfile.h"
#include <cassert>
#include <QtCore/QReadLocker>
#include <QtCore/QThread>
#include <QtCore/QWriteLocker>
#include <QtQml/QQmlContext>
#include <shared/QtHelpers.h>
@ -20,20 +22,63 @@
static const QString RESTRICTED_FLAG_PROPERTY = "RestrictFileAccess";
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) :
ContextAwareProfileParent(context), _context(context) {
QReadWriteLock ContextAwareProfile::_contextMapProtect;
ContextAwareProfile::ContextMap ContextAwareProfile::_contextMap;
ContextAwareProfile::ContextAwareProfile(QQmlContext* context) : ContextAwareProfileParent(context), _context(context) {
assert(context);
{ // register our object for future updates
QWriteLocker guard(&_contextMapProtect);
ContextMap::iterator setLookup = _contextMap.find(_context);
if (setLookup == _contextMap.end()) {
setLookup = _contextMap.insert(_context, ContextAwareProfileSet());
}
assert(setLookup != _contextMap.end());
ContextAwareProfileSet& profileSet = setLookup.value();
assert(profileSet.find(this) == profileSet.end());
profileSet.insert(this);
}
_isRestricted.store(isRestrictedGetProperty());
}
ContextAwareProfile::~ContextAwareProfile() {
// deregister our object
QWriteLocker guard(&_contextMapProtect);
ContextMap::iterator setLookup = _contextMap.find(_context);
assert(setLookup != _contextMap.end());
if (setLookup != _contextMap.end()) {
ContextAwareProfileSet& profileSet = setLookup.value();
assert(profileSet.find(this) != profileSet.end());
profileSet.remove(this);
if (profileSet.isEmpty()) {
_contextMap.erase(setLookup);
}
}
}
void ContextAwareProfile::restrictContext(QQmlContext* context, bool restrict) {
// set the QML property
context->setContextProperty(RESTRICTED_FLAG_PROPERTY, restrict);
// broadcast the new value to any registered ContextAwareProfile objects
QReadLocker guard(&_contextMapProtect);
ContextMap::const_iterator setLookup = _contextMap.find(context);
if (setLookup != _contextMap.end()) {
const ContextAwareProfileSet& profileSet = setLookup.value();
for (ContextAwareProfileSet::const_iterator profileIterator = profileSet.begin();
profileIterator != profileSet.end(); profileIterator++) {
(*profileIterator)->_isRestricted.store(restrict);
}
}
}
bool ContextAwareProfile::isRestrictedInternal() {
bool ContextAwareProfile::isRestrictedGetProperty() {
if (QThread::currentThread() != thread()) {
bool restrictedResult = false;
BLOCKING_INVOKE_METHOD(this, "isRestrictedInternal", Q_RETURN_ARG(bool, restrictedResult));
BLOCKING_INVOKE_METHOD(this, "isRestrictedGetProperty", Q_RETURN_ARG(bool, restrictedResult));
return restrictedResult;
}
@ -48,10 +93,5 @@ bool ContextAwareProfile::isRestrictedInternal() {
}
bool ContextAwareProfile::isRestricted() {
auto now = usecTimestampNow();
if (now > _cacheExpiry) {
_cachedValue = isRestrictedInternal();
_cacheExpiry = now + MAX_CACHE_AGE;
}
return _cachedValue;
return _isRestricted.load();
}

View file

@ -11,7 +11,11 @@
#ifndef hifi_ContextAwareProfile_h
#define hifi_ContextAwareProfile_h
#include <QtCore/QtGlobal>
#include <atomic>
#include <QtCore/QHash>
#include <QtCore/QReadWriteLock>
#include <QtCore/QSet>
#include <QtCore/QSharedPointer>
#if !defined(Q_OS_ANDROID)
#include <QtWebEngine/QQuickWebEngineProfile>
@ -26,8 +30,6 @@ using ContextAwareProfileParent = QObject;
using RequestInterceptorParent = QObject;
#endif
#include <NumericalConstants.h>
class QQmlContext;
class ContextAwareProfile : public ContextAwareProfileParent {
@ -35,7 +37,7 @@ class ContextAwareProfile : public ContextAwareProfileParent {
public:
static void restrictContext(QQmlContext* context, bool restrict = true);
bool isRestricted();
Q_INVOKABLE bool isRestrictedInternal();
Q_INVOKABLE bool isRestrictedGetProperty();
protected:
class RequestInterceptor : public RequestInterceptorParent {
@ -47,10 +49,17 @@ protected:
};
ContextAwareProfile(QQmlContext* parent);
~ContextAwareProfile();
private:
typedef QSet<ContextAwareProfile*> ContextAwareProfileSet;
typedef QHash<QQmlContext*, ContextAwareProfileSet> ContextMap;
QQmlContext* _context{ nullptr };
bool _cachedValue{ false };
quint64 _cacheExpiry{ 0 };
constexpr static quint64 MAX_CACHE_AGE = MSECS_PER_SECOND;
std::atomic<bool> _isRestricted{ false };
static QReadWriteLock _contextMapProtect;
static ContextMap _contextMap;
};
#endif // hifi_FileTypeProfile_h

View file

@ -8,6 +8,13 @@
if (NOT APPLE)
set(TARGET_NAME hifiSdl2)
if (CMAKE_COMPILER_IS_GNUCC AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 10.0)
# GCC 10 and above sets -fno-common by default, and causes a linking problem here:
# multiple definition of `WAYLAND_wl_proxy_marshal'
#
# Work around it per https://medium.com/@clentfort/using-esy-sdl2-with-gcc-10-91b4fa0c5aa9
link_libraries("-Wl,--allow-multiple-definition")
endif()
setup_hifi_plugin(Qml)
link_hifi_libraries(shared controllers ui plugins input-plugins script-engine)
target_sdl2()

View file

@ -402,7 +402,7 @@
"tooltip": "Affects the size of the spotlight beam; the higher the value, the larger the beam."
},
"materialURL": {
"tooltip": "The URL to an external JSON file or \"materialData\", \"materialData?<material name> to use Material Data."
"tooltip": "The URL to an external JSON file or \"materialData\". Append \"?<material name>\" to select a single material if multiple are defined."
},
"materialData": {
"tooltip": "Can be used instead of a JSON file when material set to materialData."

View file

@ -736,6 +736,9 @@ var toolBar = (function () {
function handleNewMaterialDialogResult(result) {
if (result) {
var materialURL = result.textInput;
if (materialURL === "") {
materialURL = "materialData";
}
//var materialMappingMode;
//switch (result.comboBox) {
// case MATERIAL_MODE_PROJECTED:
@ -2443,8 +2446,8 @@ var PropertiesTool = function (opts) {
Entities.editEntity(entityID, properties);
});
if (properties.name !== undefined || properties.modelURL !== undefined || properties.materialURL !== undefined ||
properties.visible !== undefined || properties.locked !== undefined) {
if (properties.name !== undefined || properties.modelURL !== undefined || properties.imageURL !== undefined ||
properties.materialURL !== undefined || properties.visible !== undefined || properties.locked !== undefined) {
sendListUpdate = true;
}

View file

@ -4,6 +4,7 @@
//
// Created by Sam Gondelman on 1/17/18
// Copyright 2018 High Fidelity, Inc.
// Copyright 2020 Vircadia contributors
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -54,7 +55,7 @@ Rectangle {
Text {
id: text1
text: qsTr("Material URL")
text: qsTr("Material URL (Optional)")
color: "#ffffff"
font.pixelSize: 12
}
@ -139,7 +140,7 @@ Rectangle {
Button {
id: button1
text: qsTr("Add")
text: qsTr("Create")
z: -1
onClicked: {
newMaterialDialog.sendToScript({

View file

@ -4,6 +4,7 @@
//
// Created by Seth Alves on 2017-2-10
// Copyright 2017 High Fidelity, Inc.
// Copyright 2020 Vircadia contributors
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -208,7 +209,7 @@ Rectangle {
Button {
id: button1
text: qsTr("Add")
text: qsTr("Create")
z: -1
enabled: false
onClicked: {