Add some locking

This commit is contained in:
Simon Walton 2018-08-10 10:11:46 -07:00
parent 875407b3fe
commit a8b9568c92
2 changed files with 24 additions and 29 deletions

View file

@ -35,6 +35,7 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
auto entityTree = entityTreeRenderer->getTree(); auto entityTree = entityTreeRenderer->getTree();
if (entityTree) { if (entityTree) {
Locker lock(_lock);
_entityTree = entityTree; _entityTree = entityTree;
connect(std::const_pointer_cast<EntityTree>(_entityTree).get(), connect(std::const_pointer_cast<EntityTree>(_entityTree).get(),
&EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity);
@ -47,6 +48,7 @@ void SafeLanding::startEntitySequence(QSharedPointer<EntityTreeRenderer> entityT
} }
void SafeLanding::stopEntitySequence() { void SafeLanding::stopEntitySequence() {
Locker lock(_lock);
_trackingEntities = false; _trackingEntities = false;
_initialStart = INVALID_SEQUENCE; _initialStart = INVALID_SEQUENCE;
_initialEnd = INVALID_SEQUENCE; _initialEnd = INVALID_SEQUENCE;
@ -62,10 +64,11 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
const auto& entityType = entity->getType(); const auto& entityType = entity->getType();
if (entityType == EntityTypes::Model) { if (entityType == EntityTypes::Model) {
ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get(); ModelEntityItem * modelEntity = std::dynamic_pointer_cast<ModelEntityItem>(entity).get();
auto shapeType = modelEntity->getShapeType(); static const std::set<ShapeType> downloadedCollisionTypes
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_STATIC_MESH || { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL };
shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) { if (downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
// Only track entities with downloaded collision bodies. // Only track entities with downloaded collision bodies.
Locker lock(_lock);
_trackedEntities.emplace(entityID, entity); _trackedEntities.emplace(entityID, entity);
qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName();
} }
@ -75,27 +78,37 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) {
} }
void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) {
Locker lock(_lock);
_trackedEntities.erase(entityID); _trackedEntities.erase(entityID);
} }
void SafeLanding::setCompletionSequenceNumbers(int first, int last) { void SafeLanding::setCompletionSequenceNumbers(int first, int last) {
Locker lock(_lock);
_initialStart = first; _initialStart = first;
_initialEnd = (last + 1) % SEQUENCE_MODULO; _initialEnd = (last + 1) % SEQUENCE_MODULO;
auto firstIter = _sequenceNumbers.find(_initialStart);
if (firstIter != _sequenceNumbers.end()) {
_sequenceNumbers.erase(_sequenceNumbers.begin(), firstIter);
}
_sequenceNumbers.erase(_sequenceNumbers.find(_initialEnd), _sequenceNumbers.end());
} }
void SafeLanding::sequenceNumberReceived(int sequenceNumber) { void SafeLanding::sequenceNumberReceived(int sequenceNumber) {
if (_trackingEntities) { if (_trackingEntities) {
Locker lock(_lock);
_sequenceNumbers.insert(sequenceNumber); _sequenceNumbers.insert(sequenceNumber);
} }
} }
bool SafeLanding::isLoadSequenceComplete() {
if (sequenceNumbersComplete() && entityPhysicsComplete()) {
Locker lock(_lock);
_trackingEntities = false;
_trackedEntities.clear();
qCDebug(interfaceapp) << "Safe Landing: load sequence complete";
}
return !_trackingEntities;
}
bool SafeLanding::sequenceNumbersComplete() { bool SafeLanding::sequenceNumbersComplete() {
if (_initialStart != INVALID_SEQUENCE) { if (_initialStart != INVALID_SEQUENCE) {
Locker lock(_lock);
auto startIter = _sequenceNumbers.find(_initialStart); auto startIter = _sequenceNumbers.find(_initialStart);
if (startIter != _sequenceNumbers.end()) { if (startIter != _sequenceNumbers.end()) {
_sequenceNumbers.erase(_sequenceNumbers.begin(), startIter); _sequenceNumbers.erase(_sequenceNumbers.begin(), startIter);
@ -109,27 +122,8 @@ bool SafeLanding::sequenceNumbersComplete() {
return false; return false;
} }
void SafeLanding::resourceLoaded() {
QObject * sender = QObject::sender();
if (sender) {
Resource * resource = dynamic_cast<Resource*>(sender);
const QString resourceURL = resource->getURL().toString();
_trackedURLs.erase(resourceURL);
qCDebug(interfaceapp) << "Safe Landing: Removed tracked URL" << resourceURL;
}
}
bool SafeLanding::isLoadSequenceComplete() {
if (sequenceNumbersComplete() && entityPhysicsComplete()) {
_trackingEntities = false;
_trackedEntities.clear();
qCDebug(interfaceapp) << "Safe Landing: load sequence complete";
}
return !_trackingEntities;
}
bool SafeLanding::entityPhysicsComplete() { bool SafeLanding::entityPhysicsComplete() {
Locker lock(_lock);
for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) { for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) {
auto entity = entityMapIter->second; auto entity = entityMapIter->second;
if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) { if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) {

View file

@ -33,13 +33,14 @@ public:
private slots: private slots:
void addTrackedEntity(const EntityItemID& entityID); void addTrackedEntity(const EntityItemID& entityID);
void deleteTrackedEntity(const EntityItemID& entityID); void deleteTrackedEntity(const EntityItemID& entityID);
void resourceLoaded();
private: private:
bool sequenceNumbersComplete(); bool sequenceNumbersComplete();
void debugDumpSequenceIDs() const; void debugDumpSequenceIDs() const;
bool entityPhysicsComplete(); bool entityPhysicsComplete();
std::mutex _lock;
using Locker = std::lock_guard<std::mutex>;
bool _trackingEntities { false }; bool _trackingEntities { false };
EntityTreePointer _entityTree; EntityTreePointer _entityTree;
using EntityMap = std::map<EntityItemID, EntityItemPointer>; using EntityMap = std::map<EntityItemID, EntityItemPointer>;