int main(int argc, char** argv) { std::string atlas_xml_path; char * srcdir_env = getenv("srcdir"); if (srcdir_env != 0) { atlas_xml_path = srcdir_env; atlas_xml_path += "/"; } atlas_xml_path += "../../protocol/spec/atlas.xml"; try { Atlas::Objects::loadDefaults(atlas_xml_path); } catch(Atlas::Objects::DefaultLoadingException e) { std::cout << "DefaultLoadingException: " << e.getDescription() << std::endl; } Root root = Atlas::Objects::objectDefinitions.find("root")->second; Root root_inst; root_inst->setAttr("id", std::string("root_instantiation")); assert(root->getAttr("id").asString() == "root"); assert(root_inst->getAttr("id").asString() == "root_instantiation"); assert(root->getAttr("parents").asList().size() == 0); assert(root_inst->getAttr("parents").asList().size() == 1); assert((*root_inst->getAttr("parents").asList().begin()).asString() == "root"); Look look = smart_dynamic_cast<Look>(objectDefinitions.find("look")->second); Look look_inst; look_inst->setAttr("id", std::string("look_instantiation")); assert(look->getAttr("id").asString() == "look"); assert(look_inst->getAttr("id").asString() == "look_instantiation"); assert(look->getAttr("parents").asList().size() == 1); assert((*look->getAttr("parents").asList().begin()).asString() == "perceive"); assert(look_inst->getAttr("parents").asList().size() == 1); assert((*look_inst->getAttr("parents").asList().begin()).asString() == "look"); Account acct = smart_dynamic_cast<Account>(objectDefinitions.find("account")->second); Account acct_inst; acct_inst->setAttr("id", std::string("account_instantiation")); assert(acct->getAttr("id").asString() == "account"); assert(acct_inst->getAttr("id").asString() == "account_instantiation"); assert(acct->getAttr("parents").asList().size() == 1); assert((*acct->getAttr("parents").asList().begin()).asString() == "admin_entity"); assert(acct_inst->getAttr("parents").asList().size() == 1); assert((*acct_inst->getAttr("parents").asList().begin()).asString() == "account"); { Atlas::Objects::Entity::Anonymous anon; anon->setLoc("12345"); ListType velocity; velocity.push_back(1.4); velocity.push_back(2.4); velocity.push_back(3.4); anon->setVelocityAsList(velocity); ListType bbox; bbox.push_back(1.4); bbox.push_back(2.4); bbox.push_back(3.4); bbox.push_back(2.4); anon->setAttr("bbox", bbox); Atlas::Objects::Operation::Move move; move->setFrom("123456"); move->setTo("123456"); move->setSeconds(12345678); move->setId("123456"); move->setArgs1(anon); Atlas::Objects::Operation::Sight sight; sight->setFrom("123456"); sight->setTo("123456"); sight->setSeconds(12345678); sight->setId("123456"); sight->setArgs1(move); Atlas::Message::MapType map; sight->addToMessage(map); std::cout << map.size() << std::flush; assert(map.size() == 7); assert(map["objtype"].String() == "op"); assert(map["from"].String() == "123456"); assert(map["to"].String() == "123456"); assert(map["seconds"].Float() == 12345678); assert(map["id"].String() == "123456"); assert(map["args"].List().size() == 1); } }
void StorageManager::restorePropertiesRecursively(LocatedEntity * ent) { Database * db = Database::instance(); PropertyManager * pm = PropertyManager::instance(); DatabaseResult res = db->selectProperties(ent->getId()); //Keep track of those properties that have been set on the instance, so we'll know what //type properties we should ignore. std::unordered_set<std::string> instanceProperties; DatabaseResult::const_iterator I = res.begin(); DatabaseResult::const_iterator Iend = res.end(); for (; I != Iend; ++I) { const std::string name = I.column("name"); if (name.empty()) { log(ERROR, compose("No name column in property row for %1", ent->getId())); continue; } const std::string val_string = I.column("value"); if (name.empty()) { log(ERROR, compose("No value column in property row for %1,%2", ent->getId(), name)); continue; } MapType prop_data; db->decodeMessage(val_string, prop_data); MapType::const_iterator J = prop_data.find("val"); if (J == prop_data.end()) { log(ERROR, compose("No property value data for %1:%2", ent->getId(), name)); continue; } assert(ent->getType() != 0); const Element & val = J->second; Element existingVal; if (ent->getAttr(name, existingVal) == 0) { if (existingVal == val) { //If the existing property, either on the instance or the type, is equal to the persisted one just skip it. continue; } } PropertyBase * prop = ent->modProperty(name); if (prop == nullptr) { prop = pm->addProperty(name, val.getType()); prop->install(ent, name); //This transfers ownership of the property to the entity. ent->setProperty(name, prop); } //If we get to here the property either doesn't exists, or have a different value than the default or existing property. prop->set(val); prop->setFlags(per_clean | per_seen); prop->apply(ent); instanceProperties.insert(name); } if (ent->getType()) { for (auto& propIter : ent->getType()->defaults()) { if (!instanceProperties.count(propIter.first)) { PropertyBase * prop = propIter.second; // If a property is in the class it won't have been installed // as setAttr() checks prop->install(ent, propIter.first); // The property will have been applied if it has an overriden // value, so we only apply it the value is still default. prop->apply(ent); } } } //Now restore all properties of the child entities. if (ent->m_contains) { for (auto& childEntity : *ent->m_contains) { restorePropertiesRecursively(childEntity); } } //We must send a sight op to the entity informing it of itself before we send any thoughts. //Else the mind won't have any information about itself. { Atlas::Objects::Operation::Sight sight; sight->setTo(ent->getId()); Atlas::Objects::Entity::Anonymous args; ent->addToEntity(args); sight->setArgs1(args); ent->sendWorld(sight); } //We should also send a sight op to the parent entity which owns the entity. //TODO: should this really be necessary or should we rely on other Sight functionality? if (ent->m_location.m_loc) { Atlas::Objects::Operation::Sight sight; sight->setTo(ent->m_location.m_loc->getId()); Atlas::Objects::Entity::Anonymous args; ent->addToEntity(args); sight->setArgs1(args); ent->m_location.m_loc->sendWorld(sight); } restoreThoughts(ent); }