From fdd8cb290cb51cd53390c45689b2c300d0f884e9 Mon Sep 17 00:00:00 2001 From: ksuprynowicz Date: Sun, 16 Apr 2023 16:06:24 +0200 Subject: [PATCH] Optimized getEntityProperties --- interface/src/Application.cpp | 4 +- interface/src/raypick/LaserPointer.cpp | 4 +- interface/src/raypick/ParabolaPick.cpp | 2 +- interface/src/raypick/PathPointer.cpp | 4 +- interface/src/raypick/RayPick.cpp | 4 +- .../scripting/WalletScriptingInterface.cpp | 2 +- interface/src/ui/Keyboard.cpp | 10 +- .../ui/overlays/ContextOverlayInterface.cpp | 8 +- .../entities/src/EntityItemProperties.cpp | 43 +++---- libraries/entities/src/EntityItemProperties.h | 4 +- .../entities/src/EntityItemPropertiesMacros.h | 8 +- ...rtyFlags.h => EntityPseudoPropertyFlags.h} | 12 +- .../entities/src/EntityScriptingInterface.cpp | 111 +++++++++++------- .../entities/src/EntityScriptingInterface.h | 6 +- libraries/script-engine/src/ScriptManager.cpp | 2 + .../script-engine/src/ScriptValueUtils.cpp | 4 +- .../src/v8/ScriptValueV8Wrapper.cpp | 1 + 17 files changed, 133 insertions(+), 96 deletions(-) rename libraries/entities/src/{EntityPsuedoPropertyFlags.h => EntityPseudoPropertyFlags.h} (70%) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5da3b5112d..4449e95d55 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -8219,7 +8219,7 @@ void Application::addAssetToWorldCheckModelSize() { propertyFlags += PROP_NAME; propertyFlags += PROP_DIMENSIONS; auto entityScriptingInterface = DependencyManager::get(); - auto properties = entityScriptingInterface->getEntityProperties(entityID, propertyFlags); + auto properties = entityScriptingInterface->getEntityPropertiesInternal(entityID, propertyFlags); auto name = properties.getName(); auto dimensions = properties.getDimensions(); @@ -9209,7 +9209,7 @@ void Application::updateLoginDialogPosition() { auto entityScriptingInterface = DependencyManager::get(); EntityPropertyFlags desiredProperties; desiredProperties += PROP_POSITION; - auto properties = entityScriptingInterface->getEntityProperties(_loginDialogID, desiredProperties); + auto properties = entityScriptingInterface->getEntityPropertiesInternal(_loginDialogID, desiredProperties); auto positionVec = properties.getPosition(); auto cameraPositionVec = _myCamera.getPosition(); auto cameraOrientation = cancelOutRollAndPitch(_myCamera.getOrientation()); diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index f623684da2..6e09f3a2e7 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -138,12 +138,12 @@ LaserPointer::RenderState::RenderState(const QUuid& startID, const QUuid& pathID { EntityPropertyFlags desiredProperties; desiredProperties += PROP_IGNORE_PICK_INTERSECTION; - _pathIgnorePicks = entityScriptingInterface->getEntityProperties(getPathID(), desiredProperties).getIgnorePickIntersection(); + _pathIgnorePicks = entityScriptingInterface->getEntityPropertiesInternal(getPathID(), desiredProperties).getIgnorePickIntersection(); } { EntityPropertyFlags desiredProperties; desiredProperties += PROP_STROKE_WIDTHS; - auto widths = entityScriptingInterface->getEntityProperties(getPathID(), desiredProperties).getStrokeWidths(); + auto widths = entityScriptingInterface->getEntityPropertiesInternal(getPathID(), desiredProperties).getStrokeWidths(); _lineWidth = widths.length() == 0 ? PolyLineEntityItem::DEFAULT_LINE_WIDTH : widths[0]; } } diff --git a/interface/src/raypick/ParabolaPick.cpp b/interface/src/raypick/ParabolaPick.cpp index 7a0eed96a8..378a46b96b 100644 --- a/interface/src/raypick/ParabolaPick.cpp +++ b/interface/src/raypick/ParabolaPick.cpp @@ -71,7 +71,7 @@ PickResultPointer ParabolaPick::getEntityIntersection(const PickParabola& pick) if (getFilter().doesPickLocalEntities()) { EntityPropertyFlags desiredProperties; desiredProperties += PROP_ENTITY_HOST_TYPE; - if (DependencyManager::get()->getEntityProperties(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) { + if (DependencyManager::get()->getEntityPropertiesInternal(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) { type = IntersectionType::LOCAL_ENTITY; } } diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index 6cb24a5c52..ae2340ab7f 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -254,7 +254,7 @@ StartEndRenderState::StartEndRenderState(const QUuid& startID, const QUuid& endI EntityPropertyFlags desiredProperties; desiredProperties += PROP_DIMENSIONS; desiredProperties += PROP_IGNORE_PICK_INTERSECTION; - auto properties = entityScriptingInterface->getEntityProperties(_startID, desiredProperties); + auto properties = entityScriptingInterface->getEntityPropertiesInternal(_startID, desiredProperties); _startDim = properties.getDimensions(); _startIgnorePicks = properties.getIgnorePickIntersection(); } @@ -263,7 +263,7 @@ StartEndRenderState::StartEndRenderState(const QUuid& startID, const QUuid& endI desiredProperties += PROP_DIMENSIONS; desiredProperties += PROP_ROTATION; desiredProperties += PROP_IGNORE_PICK_INTERSECTION; - auto properties = entityScriptingInterface->getEntityProperties(_endID, desiredProperties); + auto properties = entityScriptingInterface->getEntityPropertiesInternal(_endID, desiredProperties); _endDim = properties.getDimensions(); _endRot = properties.getRotation(); _endIgnorePicks = properties.getIgnorePickIntersection(); diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 8157c32a93..17326baa1a 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -40,7 +40,7 @@ PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) { if (getFilter().doesPickLocalEntities()) { EntityPropertyFlags desiredProperties; desiredProperties += PROP_ENTITY_HOST_TYPE; - if (DependencyManager::get()->getEntityProperties(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) { + if (DependencyManager::get()->getEntityPropertiesInternal(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) { type = IntersectionType::LOCAL_ENTITY; } } @@ -123,6 +123,6 @@ glm::vec2 RayPick::projectOntoEntityXYPlane(const QUuid& entityID, const glm::ve desiredProperties += PROP_ROTATION; desiredProperties += PROP_DIMENSIONS; desiredProperties += PROP_REGISTRATION_POINT; - auto props = DependencyManager::get()->getEntityProperties(entityID, desiredProperties); + auto props = DependencyManager::get()->getEntityPropertiesInternal(entityID, desiredProperties); return projectOntoXYPlane(worldPos, props.getPosition(), props.getRotation(), props.getDimensions(), props.getRegistrationPoint(), unNormalized); } diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 0194c62b82..c27b3180e4 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -34,7 +34,7 @@ void WalletScriptingInterface::setWalletStatus(const uint& status) { void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) { QSharedPointer contextOverlayInterface = DependencyManager::get(); - EntityItemProperties entityProperties = DependencyManager::get()->getEntityProperties(entityID, + EntityItemProperties entityProperties = DependencyManager::get()->getEntityPropertiesInternal(entityID, contextOverlayInterface->getEntityPropertyFlags()); if (entityProperties.getEntityHostType() == entity::HostType::AVATAR) { if (!entityID.isNull() && entityProperties.getCertificateID().length() > 0) { diff --git a/interface/src/ui/Keyboard.cpp b/interface/src/ui/Keyboard.cpp index 9ddcff0c50..80ba33d0c7 100644 --- a/interface/src/ui/Keyboard.cpp +++ b/interface/src/ui/Keyboard.cpp @@ -118,7 +118,7 @@ std::pair calculateKeyboardPositionAndOrientation() { EntityPropertyFlags desiredProperties; desiredProperties += PROP_POSITION; desiredProperties += PROP_ROTATION; - auto properties = DependencyManager::get()->getEntityProperties(tabletID, desiredProperties); + auto properties = DependencyManager::get()->getEntityPropertiesInternal(tabletID, desiredProperties); auto tablet = DependencyManager::get()->getTablet("com.highfidelity.interface.tablet.system"); bool landscapeMode = tablet->getLandscape(); @@ -146,7 +146,7 @@ void Key::saveDimensionsAndLocalPosition() { EntityPropertyFlags desiredProperties; desiredProperties += PROP_LOCAL_POSITION; desiredProperties += PROP_DIMENSIONS; - auto properties = DependencyManager::get()->getEntityProperties(_keyID, desiredProperties); + auto properties = DependencyManager::get()->getEntityPropertiesInternal(_keyID, desiredProperties); _originalLocalPosition = properties.getLocalPosition(); _originalDimensions = properties.getDimensions(); @@ -469,7 +469,7 @@ void Keyboard::switchToLayer(int layerIndex) { EntityPropertyFlags desiredProperties; desiredProperties += PROP_POSITION; desiredProperties += PROP_ROTATION; - auto oldProperties = entityScriptingInterface->getEntityProperties(_anchor.entityID, desiredProperties); + auto oldProperties = entityScriptingInterface->getEntityPropertiesInternal(_anchor.entityID, desiredProperties); glm::vec3 currentPosition = oldProperties.getPosition(); glm::quat currentOrientation = oldProperties.getRotation(); @@ -530,7 +530,7 @@ void Keyboard::handleTriggerBegin(const QUuid& id, const PointerEvent& event) { EntityPropertyFlags desiredProperties; desiredProperties += PROP_POSITION; - glm::vec3 keyWorldPosition = DependencyManager::get()->getEntityProperties(id, desiredProperties).getPosition(); + glm::vec3 keyWorldPosition = DependencyManager::get()->getEntityPropertiesInternal(id, desiredProperties).getPosition(); AudioInjectorOptions audioOptions; audioOptions.localOnly = true; @@ -662,7 +662,7 @@ void Keyboard::handleTriggerContinue(const QUuid& id, const PointerEvent& event) auto entityScriptingInterface = DependencyManager::get(); EntityPropertyFlags desiredProperties; desiredProperties += PROP_ROTATION; - glm::quat orientation = entityScriptingInterface->getEntityProperties(id, desiredProperties).getRotation(); + glm::quat orientation = entityScriptingInterface->getEntityPropertiesInternal(id, desiredProperties).getRotation(); glm::vec3 yAxis = orientation * Z_AXIS; glm::vec3 yOffset = yAxis * Z_OFFSET; glm::vec3 localPosition = key.getCurrentLocalPosition() - yOffset; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 807eed89ba..d8e8bbbfb9 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -141,7 +141,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& qCDebug(context_overlay) << "Creating Context Overlay on top of entity with ID: " << entityItemID; // Add all necessary variables to the stack - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityPropertiesInternal(entityItemID, _entityPropertyFlags); glm::vec3 cameraPosition = qApp->getCamera().getPosition(); glm::vec3 entityDimensions = entityProperties.getDimensions(); glm::vec3 entityPosition = entityProperties.getPosition(); @@ -231,7 +231,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& } bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) { - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityPropertiesInternal(entityItemID, _entityPropertyFlags); return (entityProperties.getCertificateID().length() != 0); } @@ -294,7 +294,7 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID setLastInspectedEntity(entityID); - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityID, _entityPropertyFlags); + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityPropertiesInternal(entityID, _entityPropertyFlags); auto nodeList = DependencyManager::get(); @@ -399,7 +399,7 @@ void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) { void ContextOverlayInterface::startChallengeOwnershipTimer(const EntityItemID& entityItemID) { auto ledger = DependencyManager::get(); - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityPropertiesInternal(entityItemID, _entityPropertyFlags); connect(&_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out for" << entityItemID; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 5691455611..1c96c72775 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1578,7 +1578,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { */ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime, - bool strictSemantics, EntityPsuedoPropertyFlags psueudoPropertyFlags) const { + bool strictSemantics, + EntityPseudoPropertyFlags pseudoPropertyFlags) const { // If strictSemantics is true and skipDefaults is false, then all and only those properties are copied for which the property flag // is included in _desiredProperties, or is one of the specially enumerated ALWAYS properties below. @@ -1587,30 +1588,30 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s ScriptValue properties = engine->newObject(); EntityItemProperties defaultEntityProperties; - const bool psuedoPropertyFlagsActive = psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::FlagsActive); - // Fix to skip the default return all mechanism, when psuedoPropertyFlagsActive - const bool psuedoPropertyFlagsButDesiredEmpty = psuedoPropertyFlagsActive && _desiredProperties.isEmpty(); + const bool pseudoPropertyFlagsActive = pseudoPropertyFlags.test(EntityPseudoPropertyFlag::FlagsActive); + // Fix to skip the default return all mechanism, when pseudoPropertyFlagsActive + const bool pseudoPropertyFlagsButDesiredEmpty = pseudoPropertyFlagsActive && _desiredProperties.isEmpty(); if (_created == UNKNOWN_CREATED_TIME && !allowUnknownCreateTime) { // No entity properties can have been set so return without setting any default, zero property values. return properties; } - if (_idSet && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ID))) { + if (_idSet && (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::ID))) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(id, _id.toString()); } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Type)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::Type)) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_ALWAYS(type, EntityTypes::getEntityTypeName(_type)); } if ((!skipDefaults || _lifetime != defaultEntityProperties._lifetime) && !strictSemantics) { - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::Age)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::Age)) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(age, getAge()); // gettable, but not settable } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::AgeAsText)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::AgeAsText)) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(ageAsText, formatSecondsElapsed(getAge())); // gettable, but not settable } } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::LastEdited)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::LastEdited)) { properties.setProperty("lastEdited", convertScriptValue(engine, _lastEdited)); } if (!skipDefaults) { @@ -1768,7 +1769,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GROUP_CULLED, groupCulled); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_BLENDSHAPE_COEFFICIENTS, blendshapeCoefficients); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_USE_ORIGINAL_PIVOT, useOriginalPivot); - if (!psuedoPropertyFlagsButDesiredEmpty) { + if (!pseudoPropertyFlagsButDesiredEmpty) { _animation.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); } } @@ -1825,7 +1826,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(PROP_SHAPE_TYPE, shapeType, getShapeTypeAsString()); COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_COMPOUND_SHAPE_URL, compoundShapeURL); - if (!psuedoPropertyFlagsButDesiredEmpty) { + if (!pseudoPropertyFlagsButDesiredEmpty) { _keyLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); _ambientLight.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); _skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties); @@ -1926,7 +1927,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_SUB_IMAGE, subImage); // Handle conversions to old 'textures' property from "imageURL" - if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(PROP_IMAGE_URL)) && + if (((!pseudoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(PROP_IMAGE_URL)) && (!skipDefaults || defaultEntityProperties._imageURL != _imageURL)) { ScriptValue textures = engine->newObject(); textures.setProperty("tex.picture", _imageURL); @@ -1960,7 +1961,7 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s * @property {Vec3} dimensions - The dimensions of the AA box. */ if (!skipDefaults && !strictSemantics && - (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::BoundingBox))) { + (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::BoundingBox))) { AABox aaBox = getAABox(); ScriptValue boundingBox = engine->newObject(); @@ -1976,13 +1977,13 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s } QString textureNamesStr = QJsonDocument::fromVariant(_textureNames).toJson(); - if (!skipDefaults && !strictSemantics && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::OriginalTextures))) { + if (!skipDefaults && !strictSemantics && (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::OriginalTextures))) { COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(originalTextures, textureNamesStr); // gettable, but not settable } // Rendering info if (!skipDefaults && !strictSemantics && - (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::RenderInfo))) { + (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::RenderInfo))) { ScriptValue renderInfo = engine->newObject(); @@ -2009,20 +2010,20 @@ ScriptValue EntityItemProperties::copyToScriptValue(ScriptEngine* engine, bool s COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER_NO_SKIP(renderInfo, renderInfo); // Gettable but not settable } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::ClientOnly)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::ClientOnly)) { properties.setProperty("clientOnly", convertScriptValue(engine, getEntityHostType() == entity::HostType::AVATAR)); } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::AvatarEntity)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::AvatarEntity)) { properties.setProperty("avatarEntity", convertScriptValue(engine, getEntityHostType() == entity::HostType::AVATAR)); } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::LocalEntity)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::LocalEntity)) { properties.setProperty("localEntity", convertScriptValue(engine, getEntityHostType() == entity::HostType::LOCAL)); } - if (_type != EntityTypes::PolyLine && (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::FaceCamera))) { + if (_type != EntityTypes::PolyLine && (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::FaceCamera))) { properties.setProperty("faceCamera", convertScriptValue(engine, getBillboardMode() == BillboardMode::YAW)); } - if (!psuedoPropertyFlagsActive || psueudoPropertyFlags.test(EntityPsuedoPropertyFlag::IsFacingAvatar)) { + if (!pseudoPropertyFlagsActive || pseudoPropertyFlags.test(EntityPseudoPropertyFlag::IsFacingAvatar)) { properties.setProperty("isFacingAvatar", convertScriptValue(engine, getBillboardMode() == BillboardMode::FULL)); } @@ -2647,7 +2648,7 @@ static QHash _enumsToPropertyStrings; bool EntityItemProperties::getPropertyInfo(const QString& propertyName, EntityPropertyInfo& propertyInfo) { static std::once_flag initMap; - + // V8TODO: Probably needs mutex before call_once std::call_once(initMap, []() { // Core ADD_PROPERTY_TO_MAP(PROP_SIMULATION_OWNER, SimulationOwner, simulationOwner, SimulationOwner); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index d8753ba64f..faf93ccbc2 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -42,7 +42,7 @@ #include "EntityItemPropertiesMacros.h" #include "EntityTypes.h" #include "EntityPropertyFlags.h" -#include "EntityPsuedoPropertyFlags.h" +#include "EntityPseudoPropertyFlags.h" #include "SimulationOwner.h" #include "TextEntityItem.h" @@ -138,7 +138,7 @@ public: void setType(EntityTypes::EntityType type) { _type = type; } virtual ScriptValue copyToScriptValue(ScriptEngine* engine, bool skipDefaults, bool allowUnknownCreateTime = false, - bool strictSemantics = false, EntityPsuedoPropertyFlags psueudoPropertyFlags = EntityPsuedoPropertyFlags()) const; + bool strictSemantics = false, EntityPseudoPropertyFlags pseudoPropertyFlags = EntityPseudoPropertyFlags()) const; virtual void copyFromScriptValue(const ScriptValue& object, bool honorReadOnly); void copyFromJSONString(ScriptEngine& scriptEngine, const QString& jsonString); diff --git a/libraries/entities/src/EntityItemPropertiesMacros.h b/libraries/entities/src/EntityItemPropertiesMacros.h index 92e3481ffa..d6ee64ba9a 100644 --- a/libraries/entities/src/EntityItemPropertiesMacros.h +++ b/libraries/entities/src/EntityItemPropertiesMacros.h @@ -174,10 +174,10 @@ inline ScriptValue convertScriptValue(ScriptEngine* e, const AACube& v) { return } #define COPY_PROPERTY_TO_QSCRIPTVALUE(p,P) \ - if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ + if (((!pseudoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ ScriptValue V = convertScriptValue(engine, _##P); \ - properties.setProperty(#P, V); \ + properties.setProperty(#P, V); \ } #define COPY_PROPERTY_TO_QSCRIPTVALUE_TYPED(p,P,T) \ @@ -191,7 +191,7 @@ inline ScriptValue convertScriptValue(ScriptEngine* e, const AACube& v) { return properties.setProperty(#P, G); #define COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, G) \ - if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ + if (((!pseudoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ ScriptValue V = convertScriptValue(engine, G); \ properties.setProperty(#P, V); \ @@ -206,7 +206,7 @@ inline ScriptValue convertScriptValue(ScriptEngine* e, const AACube& v) { return // same as COPY_PROPERTY_TO_QSCRIPTVALUE_GETTER but uses #X instead of #P in the setProperty() step #define COPY_PROXY_PROPERTY_TO_QSCRIPTVALUE_GETTER(p, P, X, G) \ - if (((!psuedoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ + if (((!pseudoPropertyFlagsButDesiredEmpty && _desiredProperties.isEmpty()) || _desiredProperties.getHasProperty(p)) && \ (!skipDefaults || defaultEntityProperties._##P != _##P)) { \ ScriptValue V = convertScriptValue(engine, G); \ properties.setProperty(#X, V); \ diff --git a/libraries/entities/src/EntityPsuedoPropertyFlags.h b/libraries/entities/src/EntityPseudoPropertyFlags.h similarity index 70% rename from libraries/entities/src/EntityPsuedoPropertyFlags.h rename to libraries/entities/src/EntityPseudoPropertyFlags.h index d6326ee1f5..2535f5607b 100644 --- a/libraries/entities/src/EntityPsuedoPropertyFlags.h +++ b/libraries/entities/src/EntityPseudoPropertyFlags.h @@ -1,5 +1,5 @@ // -// EntityPsuedoPropertyFlags.h +// EntityPseudoPropertyFlags.h // libraries/entities/src // // Created by Thijs Wenker on 9/18/18. @@ -11,13 +11,13 @@ #pragma once -#ifndef hifi_EntityPsuedoPropertyFlag_h -#define hifi_EntityPsuedoPropertyFlag_h +#ifndef hifi_EntityPseudoPropertyFlag_h +#define hifi_EntityPseudoPropertyFlag_h #include #include -namespace EntityPsuedoPropertyFlag { +namespace EntityPseudoPropertyFlag { enum { None = 0, FlagsActive, @@ -38,6 +38,6 @@ namespace EntityPsuedoPropertyFlag { NumFlags }; } -typedef std::bitset EntityPsuedoPropertyFlags; +typedef std::bitset EntityPseudoPropertyFlags; -#endif // hifi_EntityPsuedoPropertyFlag_h +#endif // hifi_EntityPseudoPropertyFlag_h diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 605c0b8d86..fa417772c8 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -797,10 +797,38 @@ QUuid EntityScriptingInterface::cloneEntity(const QUuid& entityIDToClone) { EntityItemProperties EntityScriptingInterface::getEntityProperties(const QUuid& entityID) { const EntityPropertyFlags noSpecificProperties; - return getEntityProperties(entityID, noSpecificProperties); + return getEntityPropertiesInternal(entityID, noSpecificProperties); } -EntityItemProperties EntityScriptingInterface::getEntityProperties(const QUuid& entityID, EntityPropertyFlags desiredProperties) { +ScriptValue EntityScriptingInterface::getEntityProperties(const QUuid& entityID, const ScriptValue& extendedDesiredProperties) { + EntityPropertyFlags desiredProperties; + EntityItemProperties::entityPropertyFlagsFromScriptValue(extendedDesiredProperties, desiredProperties); + EntityPseudoPropertyFlags desiredPseudoPropertyFlags; + + if (extendedDesiredProperties.isString()) { + readExtendedPropertyStringValue(extendedDesiredProperties, desiredPseudoPropertyFlags); + desiredPseudoPropertyFlags.set(EntityPseudoPropertyFlag::FlagsActive); + } else if (extendedDesiredProperties.isArray()) { + const quint32 length = extendedDesiredProperties.property("length").toInt32(); + for (quint32 i = 0; i < length; i++) { + readExtendedPropertyStringValue(extendedDesiredProperties.property(i), desiredPseudoPropertyFlags); + } + desiredPseudoPropertyFlags.set(EntityPseudoPropertyFlag::FlagsActive); + } + + if (_entityTree) { + if (desiredPseudoPropertyFlags.none() && desiredProperties.isEmpty()) { + desiredPseudoPropertyFlags.set(); + } + } + + EntityItemProperties properties = getEntityPropertiesInternal(entityID, desiredProperties); + + return properties.copyToScriptValue(extendedDesiredProperties.engine().get(), false, false, false, desiredPseudoPropertyFlags); +} + +EntityItemProperties EntityScriptingInterface::getEntityPropertiesInternal(const QUuid& entityID, EntityPropertyFlags desiredProperties) { + PROFILE_RANGE(script_entities, __FUNCTION__); bool scalesWithParent { false }; @@ -864,50 +892,51 @@ ScriptValue EntityScriptingInterface::getMultipleEntityProperties(ScriptContext* return entityScriptingInterface->getMultipleEntityPropertiesInternal(engine, entityIDs, context->argument(ARGUMENT_EXTENDED_DESIRED_PROPERTIES)); } +void EntityScriptingInterface::readExtendedPropertyStringValue(const ScriptValue& extendedProperty, EntityPseudoPropertyFlags& pseudoPropertyFlags) { + const auto extendedPropertyString = extendedProperty.toString(); + if (extendedPropertyString == "id") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::ID); + } else if (extendedPropertyString == "type") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::Type); + } else if (extendedPropertyString == "age") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::Age); + } else if (extendedPropertyString == "ageAsText") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::AgeAsText); + } else if (extendedPropertyString == "lastEdited") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::LastEdited); + } else if (extendedPropertyString == "boundingBox") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::BoundingBox); + } else if (extendedPropertyString == "originalTextures") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::OriginalTextures); + } else if (extendedPropertyString == "renderInfo") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::RenderInfo); + } else if (extendedPropertyString == "clientOnly") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::ClientOnly); + } else if (extendedPropertyString == "avatarEntity") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::AvatarEntity); + } else if (extendedPropertyString == "localEntity") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::LocalEntity); + } else if (extendedPropertyString == "faceCamera") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::FaceCamera); + } else if (extendedPropertyString == "isFacingAvatar") { + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::IsFacingAvatar); + } +} + ScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(ScriptEngine* engine, QVector entityIDs, const ScriptValue& extendedDesiredProperties) { PROFILE_RANGE(script_entities, __FUNCTION__); - EntityPsuedoPropertyFlags psuedoPropertyFlags; - const auto readExtendedPropertyStringValue = [&](ScriptValue extendedProperty) { - const auto extendedPropertyString = extendedProperty.toString(); - if (extendedPropertyString == "id") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::ID); - } else if (extendedPropertyString == "type") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::Type); - } else if (extendedPropertyString == "age") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::Age); - } else if (extendedPropertyString == "ageAsText") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::AgeAsText); - } else if (extendedPropertyString == "lastEdited") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::LastEdited); - } else if (extendedPropertyString == "boundingBox") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::BoundingBox); - } else if (extendedPropertyString == "originalTextures") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::OriginalTextures); - } else if (extendedPropertyString == "renderInfo") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::RenderInfo); - } else if (extendedPropertyString == "clientOnly") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::ClientOnly); - } else if (extendedPropertyString == "avatarEntity") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::AvatarEntity); - } else if (extendedPropertyString == "localEntity") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::LocalEntity); - } else if (extendedPropertyString == "faceCamera") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FaceCamera); - } else if (extendedPropertyString == "isFacingAvatar") { - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::IsFacingAvatar); - } - }; + EntityPseudoPropertyFlags pseudoPropertyFlags; if (extendedDesiredProperties.isString()) { - readExtendedPropertyStringValue(extendedDesiredProperties); - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FlagsActive); + readExtendedPropertyStringValue(extendedDesiredProperties, pseudoPropertyFlags); + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::FlagsActive); } else if (extendedDesiredProperties.isArray()) { const quint32 length = extendedDesiredProperties.property("length").toInt32(); for (quint32 i = 0; i < length; i++) { - readExtendedPropertyStringValue(extendedDesiredProperties.property(i)); + readExtendedPropertyStringValue(extendedDesiredProperties.property(i), pseudoPropertyFlags); } - psuedoPropertyFlags.set(EntityPsuedoPropertyFlag::FlagsActive); + pseudoPropertyFlags.set(EntityPseudoPropertyFlag::FlagsActive); } EntityPropertyFlags desiredProperties = scriptvalue_cast(extendedDesiredProperties); @@ -935,7 +964,7 @@ ScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(Script const auto& entityID = entityIDs.at(i); const EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(entityID)); if (entity) { - if (psuedoPropertyFlags.none() && desiredProperties.isEmpty()) { + if (pseudoPropertyFlags.none() && desiredProperties.isEmpty()) { // these are left out of EntityItem::getEntityProperties so that localPosition and localRotation // don't end up in json saves, etc. We still want them here, though. EncodeBitstreamParams params; // unknown @@ -945,7 +974,7 @@ ScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(Script desiredProperties.setHasProperty(PROP_LOCAL_VELOCITY); desiredProperties.setHasProperty(PROP_LOCAL_ANGULAR_VELOCITY); desiredProperties.setHasProperty(PROP_LOCAL_DIMENSIONS); - psuedoPropertyFlags.set(); + pseudoPropertyFlags.set(); needsScriptSemantics = true; } @@ -963,12 +992,12 @@ ScriptValue EntityScriptingInterface::getMultipleEntityPropertiesInternal(Script PROFILE_RANGE(script_entities, "EntityScriptingInterface::getMultipleEntityProperties>Script Semantics"); foreach(const auto& result, resultProperties) { finalResult.setProperty(i++, convertPropertiesToScriptSemantics(result.properties, result.scalesWithParent) - .copyToScriptValue(engine, false, false, false, psuedoPropertyFlags)); + .copyToScriptValue(engine, false, false, false, pseudoPropertyFlags)); } } else { PROFILE_RANGE(script_entities, "EntityScriptingInterface::getMultipleEntityProperties>Skip Script Semantics"); foreach(const auto& result, resultProperties) { - finalResult.setProperty(i++, result.properties.copyToScriptValue(engine, false, false, false, psuedoPropertyFlags)); + finalResult.setProperty(i++, result.properties.copyToScriptValue(engine, false, false, false, pseudoPropertyFlags)); } } return finalResult; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index c47b4064c7..8e50675da5 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -413,7 +413,9 @@ public slots: * print("Entity color: " + JSON.stringify(properties.color)); */ Q_INVOKABLE EntityItemProperties getEntityProperties(const QUuid& entityID); - Q_INVOKABLE EntityItemProperties getEntityProperties(const QUuid& entityID, EntityPropertyFlags desiredProperties); + Q_INVOKABLE ScriptValue getEntityProperties(const QUuid& entityID, const ScriptValue &desiredProperties); + Q_INVOKABLE EntityItemProperties getEntityPropertiesInternal(const QUuid& entityID, EntityPropertyFlags desiwredProperties); + //Q_INVOKABLE EntityItemProperties getEntityProperties(const QUuid& entityID, EntityPropertyFlags desiredProperties); /*@jsdoc * Edits an entity, changing one or more of its property values. @@ -2562,6 +2564,8 @@ private: bool setPoints(QUuid entityID, std::function actor); void queueEntityMessage(PacketType packetType, EntityItemID entityID, const EntityItemProperties& properties); bool addLocalEntityCopy(EntityItemProperties& propertiesWithSimID, EntityItemID& id, bool isClone = false); + static void readExtendedPropertyStringValue(const ScriptValue& extendedProperty, + EntityPseudoPropertyFlags &pseudoPropertyFlags); EntityItemPointer checkForTreeEntityAndTypeMatch(const QUuid& entityID, EntityTypes::EntityType entityType = EntityTypes::Unknown); diff --git a/libraries/script-engine/src/ScriptManager.cpp b/libraries/script-engine/src/ScriptManager.cpp index 286e78b311..69f20d0370 100644 --- a/libraries/script-engine/src/ScriptManager.cpp +++ b/libraries/script-engine/src/ScriptManager.cpp @@ -2181,6 +2181,8 @@ void ScriptManager::entityScriptContentAvailable(const EntityItemID& entityID, c QUrl sandboxURL = currentSandboxURL.isEmpty() ? scriptOrURL : currentSandboxURL; auto initialization = [&]{ entityScriptConstructor = _engine->evaluate(contents, fileName); + //V8TODO: check if entityScriptConstructor is a function or not + //Throw V8 exception if it's not? entityScriptObject = entityScriptConstructor.construct(); if (_engine->hasUncaughtException()) { diff --git a/libraries/script-engine/src/ScriptValueUtils.cpp b/libraries/script-engine/src/ScriptValueUtils.cpp index c081a67925..bbe2184d4e 100644 --- a/libraries/script-engine/src/ScriptValueUtils.cpp +++ b/libraries/script-engine/src/ScriptValueUtils.cpp @@ -183,7 +183,7 @@ ScriptValue vec3ToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) { auto prototype = engine->globalObject().property("__hifi_vec3__"); if (!prototype.hasProperty("defined") || !prototype.property("defined").toBool()) { prototype = engine->evaluate( - "__hifi_vec3__ = Object.defineProperties({}, { " + "globalThis.__hifi_vec3__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.x = nv; }, get: function() { return this.x; } }," "1: { set: function(nv) { return this.y = nv; }, get: function() { return this.y; } }," @@ -209,7 +209,7 @@ ScriptValue vec3ColorToScriptValue(ScriptEngine* engine, const glm::vec3& vec3) auto prototype = engine->globalObject().property("__hifi_vec3_color__"); if (!prototype.property("defined").toBool()) { prototype = engine->evaluate( - "__hifi_vec3_color__ = Object.defineProperties({}, { " + "globalThis.__hifi_vec3_color__ = Object.defineProperties({}, { " "defined: { value: true }," "0: { set: function(nv) { return this.red = nv; }, get: function() { return this.red; } }," "1: { set: function(nv) { return this.green = nv; }, get: function() { return this.green; } }," diff --git a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp index f91681f86b..16189a4b8e 100644 --- a/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp +++ b/libraries/script-engine/src/v8/ScriptValueV8Wrapper.cpp @@ -162,6 +162,7 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) { } v8::Local v8Function = v8::Local::Cast(_value.get()); + //V8TODO: I'm not sure if this is correct, maybe use CallAsContructor instead? auto maybeResult = v8Function->NewInstance(_engine->getContext(), args.length(), v8Args); v8::Local result; if (maybeResult.ToLocal(&result)) {