void EntityImporterBase::sightArrived(const Operation & op, OpVector & res) { if (op->isDefaultArgs() || op->getArgs().empty()) { S_LOG_FAILURE("No arg"); return; } const Root & arg = op->getArgs().front(); switch (m_state) { case ENTITY_WALKSTART: if (op->isDefaultRefno()) { break; } if (arg->isDefaultId()) { S_LOG_WARNING("Corrupted top level entity: no id"); cancel(); return; } else { getEntity(arg->getId(), res); } // Expecting sight of world root break; case ENTITY_UPDATING: { const Operation& sub_op = smart_dynamic_cast<Operation>(arg); if (!sub_op.isValid()) { break; } if (sub_op->getClassNo() != Atlas::Objects::Operation::SET_NO || sub_op->getArgs().empty() || sub_op->isDefaultSerialno()) { S_LOG_FAILURE("This is not our entity update response."); break; } walkEntities(res); } break; case ENTITY_CREATING: case ENTITY_WALKING: //Just ignore sights when creating; these are sights of the actual creation ops. break; default: S_LOG_WARNING("Unexpected state in state machine: " << m_state); break; }; }
void EntityImporterBase::infoArrived(const Operation & op, OpVector & res) { if (op->isDefaultRefno()) { return; } if (op->isDefaultArgs() || op->getArgs().empty()) { S_LOG_FAILURE("Info with no arg."); return; } const Root & arg = op->getArgs().front(); if (m_state == RULE_WALKING) { auto& current = mRuleStack.back(); if (arg->getId() != current.definition->getId()) { S_LOG_WARNING("Got info on rule " << arg->getId() << " when expecting " << current.definition->getId() << "."); return; } updateRule(arg, current.definition, res); } else if (m_state == RULE_CREATING) { mStats.rulesProcessedCount++; mStats.rulesCreateCount++; EventProgress.emit(); walkRules(res); } else if (m_state == RULE_UPDATING) { mStats.rulesProcessedCount++; mStats.rulesUpdateCount++; EventProgress.emit(); walkRules(res); } else if (m_state == ENTITY_CREATING) { if (!op.isValid()) { return; } mNewIds.insert(arg->getId()); StackEntry & current = mTreeStack.back(); current.restored_id = arg->getId(); S_LOG_VERBOSE("Created: " << arg->getParent() << "(" << arg->getId() << ")"); auto I = mCreateEntityMapping.find(op->getRefno()); if (I != mCreateEntityMapping.end()) { //Check if there's a mind that we should send further on auto mindI = mPersistedMinds.find(I->second); if (mindI != mPersistedMinds.end()) { mResolvedMindMapping.emplace_back(arg->getId(), mindI->second); } mEntityIdMap.insert(std::make_pair(I->second, arg->getId())); mCreateEntityMapping.erase(op->getRefno()); } else { S_LOG_WARNING("Got info about create for an entity which we didn't seem to have sent."); } walkEntities(res); } else if (m_state == ENTITY_WALKING) { const RootEntity& ent = smart_dynamic_cast<RootEntity>(arg); if (!ent.isValid()) { S_LOG_FAILURE("Info response is not entity."); return; } if (arg->isDefaultId()) { S_LOG_FAILURE("Corrupted info response: no id."); } const std::string & id = arg->getId(); StackEntry & current = mTreeStack.back(); const RootEntity& obj = current.obj; assert(id == obj->getId()); if (mNewIds.find(id) != mNewIds.end() || (mTreeStack.size() != 1 && ent->isDefaultLoc()) || ent->getParent() != obj->getParent()) { createEntity(obj, res); } else { Root update = obj.copy(); current.restored_id = id; S_LOG_VERBOSE("Updating: " << obj->getId() << " ," << obj->getParent()); update->removeAttrFlag(Atlas::Objects::Entity::CONTAINS_FLAG); update->removeAttrFlag(Atlas::Objects::STAMP_FLAG); Set set; set->setArgs1(update); set->setFrom(mAvatarId); set->setTo(id); set->setSerialno(newSerialNumber()); res.push_back(set); //Check if there's a mind, and if so put it in our map of resolved entity-to-mind mappings (since we know the entity id) auto mindI = mPersistedMinds.find(obj->getId()); if (mindI != mPersistedMinds.end()) { mResolvedMindMapping.emplace_back(obj->getId(), mindI->second); } ++mStats.entitiesProcessedCount; ++mStats.entitiesUpdateCount; EventProgress.emit(); m_state = ENTITY_UPDATING; } } }