Thread safety for property getter/setters on entities

This commit is contained in:
Brad Davis 2017-03-30 17:53:54 -07:00
parent b0b214012c
commit 172fab6789
4 changed files with 682 additions and 133 deletions

View file

@ -909,19 +909,23 @@ void EntityItem::adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSk
float EntityItem::computeMass() const {
glm::vec3 dimensions = getDimensions();
return _density * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
return getDensity() * _volumeMultiplier * dimensions.x * dimensions.y * dimensions.z;
}
void EntityItem::setDensity(float density) {
_density = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
withWriteLock([&] {
_density = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
});
}
void EntityItem::updateDensity(float density) {
float clampedDensity = glm::max(glm::min(density, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
if (_density != clampedDensity) {
_density = clampedDensity;
_dirtyFlags |= Simulation::DIRTY_MASS;
}
withWriteLock([&] {
if (_density != clampedDensity) {
_density = clampedDensity;
_dirtyFlags |= Simulation::DIRTY_MASS;
}
});
}
void EntityItem::setMass(float mass) {
@ -941,10 +945,12 @@ void EntityItem::setMass(float mass) {
} else {
newDensity = glm::max(glm::min(mass / volume, ENTITY_ITEM_MAX_DENSITY), ENTITY_ITEM_MIN_DENSITY);
}
if (_density != newDensity) {
_density = newDensity;
_dirtyFlags |= Simulation::DIRTY_MASS;
}
withWriteLock([&] {
if (_density != newDensity) {
_density = newDensity;
_dirtyFlags |= Simulation::DIRTY_MASS;
}
});
}
void EntityItem::setHref(QString value) {
@ -952,32 +958,47 @@ void EntityItem::setHref(QString value) {
if (! (value.toLower().startsWith("hifi://")) ) {
return;
}
_href = value;
withWriteLock([&] {
_href = value;
});
}
void EntityItem::setCollisionSoundURL(const QString& value) {
if (_collisionSoundURL != value) {
_collisionSoundURL = value;
bool modified = false;
withWriteLock([&] {
if (_collisionSoundURL != value) {
_collisionSoundURL = value;
modified = true;
}
});
if (modified) {
if (auto myTree = getTree()) {
myTree->notifyNewCollisionSoundURL(_collisionSoundURL, getEntityItemID());
myTree->notifyNewCollisionSoundURL(value, getEntityItemID());
}
}
}
SharedSoundPointer EntityItem::getCollisionSound() {
if (!_collisionSound) {
_collisionSound = DependencyManager::get<SoundCache>()->getSound(_collisionSoundURL);
SharedSoundPointer result;
withReadLock([&] {
result = _collisionSound;
});
if (!result) {
result = DependencyManager::get<SoundCache>()->getSound(_collisionSoundURL);
withWriteLock([&] {
_collisionSound = result;
});
}
return _collisionSound;
return result;
}
void EntityItem::simulate(const quint64& now) {
if (_lastSimulated == 0) {
_lastSimulated = now;
if (0 == getLastSimulated()) {
setLastSimulated(now);
}
float timeElapsed = (float)(now - _lastSimulated) / (float)(USECS_PER_SECOND);
float timeElapsed = (float)(now - getLastSimulated()) / (float)(USECS_PER_SECOND);
#ifdef WANT_DEBUG
qCDebug(entities) << "********** EntityItem::simulate()";
@ -1024,7 +1045,7 @@ void EntityItem::simulate(const quint64& now) {
_dirtyFlags |= Simulation::DIRTY_MOTION_TYPE;
setAcceleration(Vectors::ZERO);
}
_lastSimulated = now;
setLastSimulated(now);
}
bool EntityItem::stepKinematicMotion(float timeElapsed) {
@ -1056,9 +1077,10 @@ bool EntityItem::stepKinematicMotion(float timeElapsed) {
timeElapsed = glm::min(timeElapsed, MAX_TIME_ELAPSED);
if (isSpinning) {
float angularDamping = getAngularDamping();
// angular damping
if (_angularDamping > 0.0f) {
angularVelocity *= powf(1.0f - _angularDamping, timeElapsed);
if (angularDamping > 0.0f) {
angularVelocity *= powf(1.0f - angularDamping, timeElapsed);
}
const float MIN_KINEMATIC_ANGULAR_SPEED_SQUARED =
@ -1086,15 +1108,17 @@ bool EntityItem::stepKinematicMotion(float timeElapsed) {
glm::vec3 deltaVelocity = Vectors::ZERO;
// linear damping
if (_damping > 0.0f) {
deltaVelocity = (powf(1.0f - _damping, timeElapsed) - 1.0f) * linearVelocity;
float damping = getDamping();
if (damping > 0.0f) {
deltaVelocity = (powf(1.0f - damping, timeElapsed) - 1.0f) * linearVelocity;
}
const float MIN_KINEMATIC_LINEAR_ACCELERATION_SQUARED = 1.0e-4f; // 0.01 m/sec^2
if (glm::length2(_acceleration) > MIN_KINEMATIC_LINEAR_ACCELERATION_SQUARED) {
vec3 acceleration = getAcceleration();
if (glm::length2(acceleration) > MIN_KINEMATIC_LINEAR_ACCELERATION_SQUARED) {
// yes acceleration
// acceleration is in world-frame but we need it in local-frame
glm::vec3 linearAcceleration = _acceleration;
glm::vec3 linearAcceleration = acceleration;
bool success;
Transform parentTransform = getParentTransform(success);
if (success) {
@ -1180,7 +1204,7 @@ bool EntityItem::lifetimeHasExpired() const {
}
quint64 EntityItem::getExpiry() const {
return _created + (quint64)(_lifetime * (float)USECS_PER_SECOND);
return getCreated() + (quint64)(getLifetime() * (float)USECS_PER_SECOND);
}
EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProperties) const {
@ -1189,10 +1213,10 @@ EntityItemProperties EntityItem::getProperties(EntityPropertyFlags desiredProper
EntityItemProperties properties(propertyFlags);
properties._id = getID();
properties._idSet = true;
properties._created = _created;
properties._lastEdited = _lastEdited;
properties.setClientOnly(_clientOnly);
properties.setOwningAvatarID(_owningAvatarID);
properties._created = getCreated();
properties._lastEdited = getLastEdited();
properties.setClientOnly(getClientOnly());
properties.setOwningAvatarID(getOwningAvatarID());
properties._type = getType();
@ -1259,7 +1283,7 @@ void EntityItem::getAllTerseUpdateProperties(EntityItemProperties& properties) c
properties._angularVelocity = getLocalAngularVelocity();
}
if (!properties._accelerationChanged) {
properties._acceleration = _acceleration;
properties._acceleration = getAcceleration();
}
properties._positionChanged = true;
@ -1777,20 +1801,26 @@ void EntityItem::updateRestitution(float value) {
void EntityItem::updateFriction(float value) {
float clampedValue = glm::max(glm::min(ENTITY_ITEM_MAX_FRICTION, value), ENTITY_ITEM_MIN_FRICTION);
if (_friction != clampedValue) {
_friction = clampedValue;
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
}
withWriteLock([&] {
if (_friction != clampedValue) {
_friction = clampedValue;
_dirtyFlags |= Simulation::DIRTY_MATERIAL;
}
});
}
void EntityItem::setRestitution(float value) {
float clampedValue = glm::max(glm::min(ENTITY_ITEM_MAX_RESTITUTION, value), ENTITY_ITEM_MIN_RESTITUTION);
_restitution = clampedValue;
withWriteLock([&] {
_restitution = clampedValue;
});
}
void EntityItem::setFriction(float value) {
float clampedValue = glm::max(glm::min(ENTITY_ITEM_MAX_FRICTION, value), ENTITY_ITEM_MIN_FRICTION);
_friction = clampedValue;
withWriteLock([&] {
_friction = clampedValue;
});
}
void EntityItem::updateLifetime(float value) {
@ -2327,3 +2357,436 @@ bool EntityItem::matchesJSONFilters(const QJsonObject& jsonFilters) const {
// the json filter syntax did not match what we expected, return a match
return true;
}
quint64 EntityItem::getLastSimulated() const {
quint64 result;
withReadLock([&] {
result = _lastSimulated;
});
return result;
}
void EntityItem::setLastSimulated(quint64 now) {
withWriteLock([&] {
_lastSimulated = now;
});
}
quint64 EntityItem::getLastEdited() const {
quint64 result;
withReadLock([&] {
result = _lastEdited;
});
return result;
}
void EntityItem::setLastEdited(quint64 lastEdited) {
withWriteLock([&] {
_lastEdited = _lastUpdated = lastEdited;
_changedOnServer = glm::max(lastEdited, _changedOnServer);
});
}
quint64 EntityItem::getLastBroadcast() const {
quint64 result;
withReadLock([&] {
result = _lastBroadcast;
});
return result;
}
void EntityItem::setLastBroadcast(quint64 lastBroadcast) {
withWriteLock([&] {
_lastBroadcast = lastBroadcast;
});
}
void EntityItem::markAsChangedOnServer() {
withWriteLock([&] {
_changedOnServer = usecTimestampNow();
});
}
quint64 EntityItem::getLastChangedOnServer() const {
quint64 result;
withReadLock([&] {
result = _changedOnServer;
});
return result;
}
void EntityItem::update(const quint64& now) {
withWriteLock([&] {
_lastUpdated = now;
});
}
quint64 EntityItem::getLastUpdated() const {
quint64 result;
withReadLock([&] {
result = _lastUpdated;
});
return result;
}
void EntityItem::requiresRecalcBoxes() {
withWriteLock([&] {
_recalcAABox = true;
_recalcMinAACube = true;
_recalcMaxAACube = true;
});
}
QString EntityItem::getHref() const {
QString result;
withReadLock([&] {
result = _href;
});
return result;
}
QString EntityItem::getDescription() const {
QString result;
withReadLock([&] {
result = _description;
});
return result;
}
void EntityItem::setDescription(const QString& value) {
withWriteLock([&] {
_description = value;
});
}
float EntityItem::getLocalRenderAlpha() const {
float result;
withReadLock([&] {
result = _localRenderAlpha;
});
return result;
}
void EntityItem::setLocalRenderAlpha(float localRenderAlpha) {
withWriteLock([&] {
_localRenderAlpha = localRenderAlpha;
});
}
glm::vec3 EntityItem::getGravity() const {
glm::vec3 result;
withReadLock([&] {
result = _gravity;
});
return result;
}
void EntityItem::setGravity(const glm::vec3& value) {
withWriteLock([&] {
_gravity = value;
});
}
glm::vec3 EntityItem::getAcceleration() const {
glm::vec3 result;
withReadLock([&] {
result = _acceleration;
});
return result;
}
void EntityItem::setAcceleration(const glm::vec3& value) {
withWriteLock([&] {
_acceleration = value;
});
}
float EntityItem::getDamping() const {
float result;
withReadLock([&] {
result = _damping;
});
return result;
}
void EntityItem::setDamping(float value) {
withWriteLock([&] {
_damping = value;
});
}
float EntityItem::getRestitution() const {
float result;
withReadLock([&] {
result = _restitution;
});
return result;
}
float EntityItem::getFriction() const {
float result;
withReadLock([&] {
result = _friction;
});
return result;
}
// lifetime related properties.
float EntityItem::getLifetime() const {
float result;
withReadLock([&] {
result = _lifetime;
});
return result;
}
void EntityItem::setLifetime(float value) {
withWriteLock([&] {
_lifetime = value;
});
}
quint64 EntityItem::getCreated() const {
quint64 result;
withReadLock([&] {
result = _created;
});
return result;
}
void EntityItem::setCreated(quint64 value) {
withWriteLock([&] {
_created = value;
});
}
QString EntityItem::getScript() const {
QString result;
withReadLock([&] {
result = _script;
});
return result;
}
void EntityItem::setScript(const QString& value) {
withWriteLock([&] {
_script = value;
});
}
quint64 EntityItem::getScriptTimestamp() const {
quint64 result;
withReadLock([&] {
result = _scriptTimestamp;
});
return result;
}
void EntityItem::setScriptTimestamp(const quint64 value) {
withWriteLock([&] {
_scriptTimestamp = value;
});
}
QString EntityItem::getServerScripts() const {
QString result;
withReadLock([&] {
result = _serverScripts;
});
return result;
}
void EntityItem::setServerScripts(const QString& serverScripts) {
withWriteLock([&] {
_serverScripts = serverScripts;
_serverScriptsChangedTimestamp = usecTimestampNow();
});
}
QString EntityItem::getCollisionSoundURL() const {
QString result;
withReadLock([&] {
result = _collisionSoundURL;
});
return result;
}
void EntityItem::setCollisionSound(SharedSoundPointer sound) {
withWriteLock([&] {
_collisionSound = sound;
});
}
glm::vec3 EntityItem::getRegistrationPoint() const {
glm::vec3 result;
withReadLock([&] {
result = _registrationPoint;
});
return result;
}
void EntityItem::setRegistrationPoint(const glm::vec3& value) {
withWriteLock([&] {
_registrationPoint = glm::clamp(value, 0.0f, 1.0f);
});
dimensionsChanged(); // Registration Point affects the bounding box
}
float EntityItem::getAngularDamping() const {
float result;
withReadLock([&] {
result = _angularDamping;
});
return result;
}
void EntityItem::setAngularDamping(float value) {
withWriteLock([&] {
_angularDamping = value;
});
}
QString EntityItem::getName() const {
QString result;
withReadLock([&] {
result = _name;
});
return result;
}
void EntityItem::setName(const QString& value) {
withWriteLock([&] {
_name = value;
});
}
QString EntityItem::getDebugName() {
QString result = getName();
if (result.isEmpty()) {
result = getID().toString();
}
return result;
}
bool EntityItem::getVisible() const {
bool result;
withReadLock([&] {
result = _visible;
});
return result;
}
void EntityItem::setVisible(bool value) {
withWriteLock([&] {
_visible = value;
});
}
bool EntityItem::getCollisionless() const {
bool result;
withReadLock([&] {
result = _collisionless;
});
return result;
}
void EntityItem::setCollisionless(bool value) {
withWriteLock([&] {
_collisionless = value;
});
}
uint8_t EntityItem::getCollisionMask() const {
uint8_t result;
withReadLock([&] {
result = _collisionMask;
});
return result;
}
void EntityItem::setCollisionMask(uint8_t value) {
withWriteLock([&] {
_collisionMask = value;
});
}
bool EntityItem::getDynamic() const {
if (SHAPE_TYPE_STATIC_MESH == getShapeType()) {
return false;
}
bool result;
withReadLock([&] {
result = _dynamic;
});
return result;
}
void EntityItem::setDynamic(bool value) {
withWriteLock([&] {
_dynamic = value;
});
}
bool EntityItem::getLocked() const {
bool result;
withReadLock([&] {
result = _locked;
});
return result;
}
void EntityItem::setLocked(bool value) {
withWriteLock([&] {
_locked = value;
});
}
QString EntityItem::getUserData() const {
QString result;
withReadLock([&] {
result = _userData;
});
return result;
}
void EntityItem::setUserData(const QString& value) {
withWriteLock([&] {
_userData = value;
});
}
QString EntityItem::getMarketplaceID() const {
QString result;
withReadLock([&] {
result = _marketplaceID;
});
return result;
}
void EntityItem::setMarketplaceID(const QString& value) {
withWriteLock([&] {
_marketplaceID = value;
});
}
uint32_t EntityItem::getDirtyFlags() const {
uint32_t result;
withReadLock([&] {
result = _dirtyFlags;
});
return result;
}
void EntityItem::clearDirtyFlags(uint32_t mask) {
withWriteLock([&] {
_dirtyFlags &= ~mask;
});
}
float EntityItem::getDensity() const {
float result;
withReadLock([&] {
result = _density;
});
return result;
}

View file

@ -110,22 +110,21 @@ public:
virtual void somethingChangedNotification() { }
void recordCreationTime(); // set _created to 'now'
quint64 getLastSimulated() const { return _lastSimulated; } /// Last simulated time of this entity universal usecs
void setLastSimulated(quint64 now) { _lastSimulated = now; }
quint64 getLastSimulated() const; /// Last simulated time of this entity universal usecs
void setLastSimulated(quint64 now);
/// Last edited time of this entity universal usecs
quint64 getLastEdited() const { return _lastEdited; }
void setLastEdited(quint64 lastEdited)
{ _lastEdited = _lastUpdated = lastEdited; _changedOnServer = glm::max(lastEdited, _changedOnServer); }
quint64 getLastEdited() const;
void setLastEdited(quint64 lastEdited);
float getEditedAgo() const /// Elapsed seconds since this entity was last edited
{ return (float)(usecTimestampNow() - getLastEdited()) / (float)USECS_PER_SECOND; }
/// Last time we sent out an edit packet for this entity
quint64 getLastBroadcast() const { return _lastBroadcast; }
void setLastBroadcast(quint64 lastBroadcast) { _lastBroadcast = lastBroadcast; }
quint64 getLastBroadcast() const;
void setLastBroadcast(quint64 lastBroadcast);
void markAsChangedOnServer() { _changedOnServer = usecTimestampNow(); }
quint64 getLastChangedOnServer() const { return _changedOnServer; }
void markAsChangedOnServer();
quint64 getLastChangedOnServer() const;
// TODO: eventually only include properties changed since the params.lastQuerySent time
virtual EntityPropertyFlags getEntityProperties(EncodeBitstreamParams& params) const;
@ -163,8 +162,8 @@ public:
static void adjustEditPacketForClockSkew(QByteArray& buffer, qint64 clockSkew);
// perform update
virtual void update(const quint64& now) { _lastUpdated = now; }
quint64 getLastUpdated() const { return _lastUpdated; }
virtual void update(const quint64& now);
quint64 getLastUpdated() const;
// perform linear extrapolation for SimpleEntitySimulation
void simulate(const quint64& now);
@ -188,63 +187,63 @@ public:
const Transform getTransformToCenter(bool& success) const;
inline void requiresRecalcBoxes() { _recalcAABox = true; _recalcMinAACube = true; _recalcMaxAACube = true; }
inline void requiresRecalcBoxes();
// Hyperlink related getters and setters
QString getHref() const { return _href; }
QString getHref() const;
void setHref(QString value);
QString getDescription() const { return _description; }
void setDescription(QString value) { _description = value; }
QString getDescription() const;
void setDescription(const QString& value);
/// Dimensions in meters (0.0 - TREE_SCALE)
inline const glm::vec3 getDimensions() const { return getScale(); }
virtual void setDimensions(const glm::vec3& value);
float getLocalRenderAlpha() const { return _localRenderAlpha; }
void setLocalRenderAlpha(float localRenderAlpha) { _localRenderAlpha = localRenderAlpha; }
float getLocalRenderAlpha() const;
void setLocalRenderAlpha(float localRenderAlpha);
void setDensity(float density);
float computeMass() const;
void setMass(float mass);
float getDensity() const { return _density; }
float getDensity() const;
bool hasVelocity() const { return getVelocity() != ENTITY_ITEM_ZERO_VEC3; }
bool hasLocalVelocity() const { return getLocalVelocity() != ENTITY_ITEM_ZERO_VEC3; }
const glm::vec3& getGravity() const { return _gravity; } /// get gravity in meters
void setGravity(const glm::vec3& value) { _gravity = value; } /// gravity in meters
bool hasGravity() const { return _gravity != ENTITY_ITEM_ZERO_VEC3; }
glm::vec3 getGravity() const; /// get gravity in meters
void setGravity(const glm::vec3& value); /// gravity in meters
bool hasGravity() const { return getGravity() != ENTITY_ITEM_ZERO_VEC3; }
const glm::vec3& getAcceleration() const { return _acceleration; } /// get acceleration in meters/second/second
void setAcceleration(const glm::vec3& value) { _acceleration = value; } /// acceleration in meters/second/second
bool hasAcceleration() const { return _acceleration != ENTITY_ITEM_ZERO_VEC3; }
glm::vec3 getAcceleration() const; /// get acceleration in meters/second/second
void setAcceleration(const glm::vec3& value); /// acceleration in meters/second/second
bool hasAcceleration() const { return getAcceleration() != ENTITY_ITEM_ZERO_VEC3; }
float getDamping() const { return _damping; }
void setDamping(float value) { _damping = value; }
float getDamping() const;
void setDamping(float value);
float getRestitution() const { return _restitution; }
float getRestitution() const;
void setRestitution(float value);
float getFriction() const { return _friction; }
float getFriction() const;
void setFriction(float value);
// lifetime related properties.
float getLifetime() const { return _lifetime; } /// get the lifetime in seconds for the entity
void setLifetime(float value) { _lifetime = value; } /// set the lifetime in seconds for the entity
float getLifetime() const; /// get the lifetime in seconds for the entity
void setLifetime(float value); /// set the lifetime in seconds for the entity
quint64 getCreated() const { return _created; } /// get the created-time in useconds for the entity
void setCreated(quint64 value) { _created = value; } /// set the created-time in useconds for the entity
quint64 getCreated() const; /// get the created-time in useconds for the entity
void setCreated(quint64 value); /// set the created-time in useconds for the entity
/// is this entity immortal, in that it has no lifetime set, and will exist until manually deleted
bool isImmortal() const { return _lifetime == ENTITY_ITEM_IMMORTAL_LIFETIME; }
bool isImmortal() const { return getLifetime() == ENTITY_ITEM_IMMORTAL_LIFETIME; }
/// is this entity mortal, in that it has a lifetime set, and will automatically be deleted when that lifetime expires
bool isMortal() const { return _lifetime != ENTITY_ITEM_IMMORTAL_LIFETIME; }
bool isMortal() const { return getLifetime() != ENTITY_ITEM_IMMORTAL_LIFETIME; }
/// age of this entity in seconds
float getAge() const { return (float)(usecTimestampNow() - _created) / (float)USECS_PER_SECOND; }
float getAge() const { return (float)(usecTimestampNow() - getCreated()) / (float)USECS_PER_SECOND; }
bool lifetimeHasExpired() const;
quint64 getExpiry() const;
@ -256,63 +255,61 @@ public:
using SpatiallyNestable::getQueryAACube;
virtual AACube getQueryAACube(bool& success) const override;
QString getScript() const { return _script; }
void setScript(const QString& value) { _script = value; }
QString getScript() const;
void setScript(const QString& value);
quint64 getScriptTimestamp() const { return _scriptTimestamp; }
void setScriptTimestamp(const quint64 value) { _scriptTimestamp = value; }
quint64 getScriptTimestamp() const;
void setScriptTimestamp(const quint64 value);
QString getServerScripts() const { return _serverScripts; }
void setServerScripts(const QString& serverScripts)
{ _serverScripts = serverScripts; _serverScriptsChangedTimestamp = usecTimestampNow(); }
QString getServerScripts() const;
void setServerScripts(const QString& serverScripts);
const QString& getCollisionSoundURL() const { return _collisionSoundURL; }
QString getCollisionSoundURL() const;
void setCollisionSoundURL(const QString& value);
SharedSoundPointer getCollisionSound();
void setCollisionSound(SharedSoundPointer sound) { _collisionSound = sound; }
void setCollisionSound(SharedSoundPointer sound);
const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity
glm::vec3 getRegistrationPoint() const; /// registration point as ratio of entity
/// registration point as ratio of entity
void setRegistrationPoint(const glm::vec3& value) {
_registrationPoint = glm::clamp(value, 0.0f, 1.0f); dimensionsChanged(); // Registration Point affects the bounding box
}
void setRegistrationPoint(const glm::vec3& value);
bool hasAngularVelocity() const { return getAngularVelocity() != ENTITY_ITEM_ZERO_VEC3; }
bool hasLocalAngularVelocity() const { return getLocalAngularVelocity() != ENTITY_ITEM_ZERO_VEC3; }
float getAngularDamping() const { return _angularDamping; }
void setAngularDamping(float value) { _angularDamping = value; }
float getAngularDamping() const;
void setAngularDamping(float value);
QString getName() const { return _name; }
void setName(const QString& value) { _name = value; }
QString getDebugName() { return _name != "" ? _name : getID().toString(); }
QString getName() const;
void setName(const QString& value);
QString getDebugName();
bool getVisible() const { return _visible; }
void setVisible(bool value) { _visible = value; }
bool isVisible() const { return _visible; }
bool isInvisible() const { return !_visible; }
bool getVisible() const;
void setVisible(bool value);
inline bool isVisible() const { return getVisible(); }
inline bool isInvisible() const { return !getVisible(); }
bool getCollisionless() const { return _collisionless; }
void setCollisionless(bool value) { _collisionless = value; }
bool getCollisionless() const;
void setCollisionless(bool value);
uint8_t getCollisionMask() const { return _collisionMask; }
void setCollisionMask(uint8_t value) { _collisionMask = value; }
uint8_t getCollisionMask() const;
void setCollisionMask(uint8_t value);
void computeCollisionGroupAndFinalMask(int16_t& group, int16_t& mask) const;
bool getDynamic() const { return SHAPE_TYPE_STATIC_MESH == getShapeType() ? false : _dynamic; }
void setDynamic(bool value) { _dynamic = value; }
bool getDynamic() const;
void setDynamic(bool value);
virtual bool shouldBePhysical() const { return false; }
bool getLocked() const { return _locked; }
void setLocked(bool value) { _locked = value; }
bool getLocked() const;
void setLocked(bool value);
const QString& getUserData() const { return _userData; }
virtual void setUserData(const QString& value) { _userData = value; }
QString getUserData() const;
virtual void setUserData(const QString& value);
// FIXME not thread safe?
const SimulationOwner& getSimulationOwner() const { return _simulationOwner; }
void setSimulationOwner(const QUuid& id, quint8 priority);
void setSimulationOwner(const SimulationOwner& owner);
@ -325,8 +322,8 @@ public:
void setPendingOwnershipPriority(quint8 priority, const quint64& timestamp);
void rememberHasSimulationOwnershipBid() const;
const QString& getMarketplaceID() const { return _marketplaceID; }
void setMarketplaceID(const QString& value) { _marketplaceID = value; }
QString getMarketplaceID() const;
void setMarketplaceID(const QString& value);
// TODO: get rid of users of getRadius()...
float getRadius() const;
@ -369,8 +366,8 @@ public:
void updateCreated(uint64_t value);
virtual void setShapeType(ShapeType type) { /* do nothing */ }
uint32_t getDirtyFlags() const { return _dirtyFlags; }
void clearDirtyFlags(uint32_t mask = 0xffffffff) { _dirtyFlags &= ~mask; }
uint32_t getDirtyFlags() const;
void clearDirtyFlags(uint32_t mask = 0xffffffff);
bool isMoving() const;
bool isMovingRelativeToParent() const;

View file

@ -141,3 +141,98 @@ bool TextEntityItem::findDetailedRayIntersection(const glm::vec3& origin, const
// FIXME - should set face and surfaceNormal
return findRayRectangleIntersection(origin, direction, rotation, position, xyDimensions, distance);
}
void TextEntityItem::setText(const QString& value) {
withWriteLock([&] {
_text = value;
});
}
QString TextEntityItem::getText() const {
QString result;
withReadLock([&] {
result = _text;
});
return result;
}
void TextEntityItem::setLineHeight(float value) {
withWriteLock([&] {
_lineHeight = value;
});
}
float TextEntityItem::getLineHeight() const {
float result;
withReadLock([&] {
result = _lineHeight;
});
return result;
}
const rgbColor& TextEntityItem::getTextColor() const {
return _textColor;
}
const rgbColor& TextEntityItem::getBackgroundColor() const {
return _backgroundColor;
}
xColor TextEntityItem::getTextColorX() const {
xColor result;
withReadLock([&] {
result = { _textColor[RED_INDEX], _textColor[GREEN_INDEX], _textColor[BLUE_INDEX] };
});
return result;
}
void TextEntityItem::setTextColor(const rgbColor& value) {
withWriteLock([&] {
memcpy(_textColor, value, sizeof(_textColor));
});
}
void TextEntityItem::setTextColor(const xColor& value) {
withWriteLock([&] {
_textColor[RED_INDEX] = value.red;
_textColor[GREEN_INDEX] = value.green;
_textColor[BLUE_INDEX] = value.blue;
});
}
xColor TextEntityItem::getBackgroundColorX() const {
xColor result;
withReadLock([&] {
result = { _backgroundColor[RED_INDEX], _backgroundColor[GREEN_INDEX], _backgroundColor[BLUE_INDEX] };
});
return result;
}
void TextEntityItem::setBackgroundColor(const rgbColor& value) {
withWriteLock([&] {
memcpy(_backgroundColor, value, sizeof(_backgroundColor));
});
}
void TextEntityItem::setBackgroundColor(const xColor& value) {
withWriteLock([&] {
_backgroundColor[RED_INDEX] = value.red;
_backgroundColor[GREEN_INDEX] = value.green;
_backgroundColor[BLUE_INDEX] = value.blue;
});
}
bool TextEntityItem::getFaceCamera() const {
bool result;
withReadLock([&] {
result = _faceCamera;
});
return result;
}
void TextEntityItem::setFaceCamera(bool value) {
withWriteLock([&] {
_faceCamera = value;
});
}

View file

@ -53,38 +53,32 @@ public:
void** intersectedObject, bool precisionPicking) const override;
static const QString DEFAULT_TEXT;
void setText(const QString& value) { _text = value; }
const QString& getText() const { return _text; }
void setText(const QString& value);
QString getText() const;
static const float DEFAULT_LINE_HEIGHT;
void setLineHeight(float value) { _lineHeight = value; }
float getLineHeight() const { return _lineHeight; }
void setLineHeight(float value);
float getLineHeight() const;
static const xColor DEFAULT_TEXT_COLOR;
const rgbColor& getTextColor() const { return _textColor; }
xColor getTextColorX() const { xColor color = { _textColor[RED_INDEX], _textColor[GREEN_INDEX], _textColor[BLUE_INDEX] }; return color; }
// FIXME should not return a reference because of thread safety, but can't return an array
const rgbColor& getTextColor() const;
xColor getTextColorX() const;
void setTextColor(const rgbColor& value) { memcpy(_textColor, value, sizeof(_textColor)); }
void setTextColor(const xColor& value) {
_textColor[RED_INDEX] = value.red;
_textColor[GREEN_INDEX] = value.green;
_textColor[BLUE_INDEX] = value.blue;
}
void setTextColor(const rgbColor& value);
void setTextColor(const xColor& value);
static const xColor DEFAULT_BACKGROUND_COLOR;
const rgbColor& getBackgroundColor() const { return _backgroundColor; }
xColor getBackgroundColorX() const { xColor color = { _backgroundColor[RED_INDEX], _backgroundColor[GREEN_INDEX], _backgroundColor[BLUE_INDEX] }; return color; }
// FIXME should not return a reference because of thread safety, but can't return an array
const rgbColor& getBackgroundColor() const;
xColor getBackgroundColorX() const;
void setBackgroundColor(const rgbColor& value) { memcpy(_backgroundColor, value, sizeof(_backgroundColor)); }
void setBackgroundColor(const xColor& value) {
_backgroundColor[RED_INDEX] = value.red;
_backgroundColor[GREEN_INDEX] = value.green;
_backgroundColor[BLUE_INDEX] = value.blue;
}
void setBackgroundColor(const rgbColor& value);
void setBackgroundColor(const xColor& value);
static const bool DEFAULT_FACE_CAMERA;
bool getFaceCamera() const { return _faceCamera; }
void setFaceCamera(bool value) { _faceCamera = value; }
bool getFaceCamera() const;
void setFaceCamera(bool value);
protected:
QString _text;