Optimized getEntityProperties

This commit is contained in:
ksuprynowicz 2023-04-16 16:06:24 +02:00
parent c18fd9092e
commit fdd8cb290c
17 changed files with 133 additions and 96 deletions

View file

@ -8219,7 +8219,7 @@ void Application::addAssetToWorldCheckModelSize() {
propertyFlags += PROP_NAME;
propertyFlags += PROP_DIMENSIONS;
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
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<EntityScriptingInterface>();
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());

View file

@ -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];
}
}

View file

@ -71,7 +71,7 @@ PickResultPointer ParabolaPick::getEntityIntersection(const PickParabola& pick)
if (getFilter().doesPickLocalEntities()) {
EntityPropertyFlags desiredProperties;
desiredProperties += PROP_ENTITY_HOST_TYPE;
if (DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) {
if (DependencyManager::get<EntityScriptingInterface>()->getEntityPropertiesInternal(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) {
type = IntersectionType::LOCAL_ENTITY;
}
}

View file

@ -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();

View file

@ -40,7 +40,7 @@ PickResultPointer RayPick::getEntityIntersection(const PickRay& pick) {
if (getFilter().doesPickLocalEntities()) {
EntityPropertyFlags desiredProperties;
desiredProperties += PROP_ENTITY_HOST_TYPE;
if (DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityRes.entityID, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) {
if (DependencyManager::get<EntityScriptingInterface>()->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<EntityScriptingInterface>()->getEntityProperties(entityID, desiredProperties);
auto props = DependencyManager::get<EntityScriptingInterface>()->getEntityPropertiesInternal(entityID, desiredProperties);
return projectOntoXYPlane(worldPos, props.getPosition(), props.getRotation(), props.getDimensions(), props.getRegistrationPoint(), unNormalized);
}

View file

@ -34,7 +34,7 @@ void WalletScriptingInterface::setWalletStatus(const uint& status) {
void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) {
QSharedPointer<ContextOverlayInterface> contextOverlayInterface = DependencyManager::get<ContextOverlayInterface>();
EntityItemProperties entityProperties = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(entityID,
EntityItemProperties entityProperties = DependencyManager::get<EntityScriptingInterface>()->getEntityPropertiesInternal(entityID,
contextOverlayInterface->getEntityPropertyFlags());
if (entityProperties.getEntityHostType() == entity::HostType::AVATAR) {
if (!entityID.isNull() && entityProperties.getCertificateID().length() > 0) {

View file

@ -118,7 +118,7 @@ std::pair<glm::vec3, glm::quat> calculateKeyboardPositionAndOrientation() {
EntityPropertyFlags desiredProperties;
desiredProperties += PROP_POSITION;
desiredProperties += PROP_ROTATION;
auto properties = DependencyManager::get<EntityScriptingInterface>()->getEntityProperties(tabletID, desiredProperties);
auto properties = DependencyManager::get<EntityScriptingInterface>()->getEntityPropertiesInternal(tabletID, desiredProperties);
auto tablet = DependencyManager::get<TabletScriptingInterface>()->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<EntityScriptingInterface>()->getEntityProperties(_keyID, desiredProperties);
auto properties = DependencyManager::get<EntityScriptingInterface>()->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<EntityScriptingInterface>()->getEntityProperties(id, desiredProperties).getPosition();
glm::vec3 keyWorldPosition = DependencyManager::get<EntityScriptingInterface>()->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<EntityScriptingInterface>();
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;

View file

@ -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<NodeList>();
@ -399,7 +399,7 @@ void ContextOverlayInterface::deletingEntity(const EntityItemID& entityID) {
void ContextOverlayInterface::startChallengeOwnershipTimer(const EntityItemID& entityItemID) {
auto ledger = DependencyManager::get<Ledger>();
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;

View file

@ -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<EntityPropertyList, QString> _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);

View file

@ -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);

View file

@ -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); \

View file

@ -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 <bitset>
#include <type_traits>
namespace EntityPsuedoPropertyFlag {
namespace EntityPseudoPropertyFlag {
enum {
None = 0,
FlagsActive,
@ -38,6 +38,6 @@ namespace EntityPsuedoPropertyFlag {
NumFlags
};
}
typedef std::bitset<EntityPsuedoPropertyFlag::NumFlags> EntityPsuedoPropertyFlags;
typedef std::bitset<EntityPseudoPropertyFlag::NumFlags> EntityPseudoPropertyFlags;
#endif // hifi_EntityPsuedoPropertyFlag_h
#endif // hifi_EntityPseudoPropertyFlag_h

View file

@ -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<QUuid> 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<EntityPropertyFlags>(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;

View file

@ -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<bool(LineEntityItem&)> 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);

View file

@ -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()) {

View file

@ -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; } },"

View file

@ -162,6 +162,7 @@ ScriptValue ScriptValueV8Wrapper::construct(const ScriptValueList& args) {
}
v8::Local<v8::Function> v8Function = v8::Local<v8::Function>::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<v8::Object> result;
if (maybeResult.ToLocal(&result)) {