Esempio n. 1
0
void StorageManager::restoreThoughts(LocatedEntity * ent)
{
    Database * db = Database::instance();
    const DatabaseResult res = db->selectThoughts(ent->getId());
    Atlas::Message::ListType thoughts_data;

    DatabaseResult::const_iterator I = res.begin();
    DatabaseResult::const_iterator Iend = res.end();
    for (; I != Iend; ++I) {
        const std::string thought = I.column("thought");
        if (thought.empty()) {
            log(ERROR,
                    compose("No thought column in property row for %1",
                            ent->getId()));
            continue;
        }
        MapType thought_data;
        db->decodeMessage(thought, thought_data);
        thoughts_data.push_back(thought_data);
    }

    if (!thoughts_data.empty()) {
        OpVector opRes;

        Atlas::Objects::Operation::Think thoughtOp;
        Atlas::Objects::Operation::Set setOp;
        setOp->setArgsAsList(thoughts_data);
        //Make the thought come from the entity itself
        thoughtOp->setArgs1(setOp);
        thoughtOp->setTo(ent->getId());
        thoughtOp->setFrom(ent->getId());

        ent->sendWorld(thoughtOp);
    }
}
Esempio n. 2
0
 /// \brief Read all the rules in one ruleset from the rules table.
 ///
 /// @param ruleset the name of the ruleset to be read.
 /// @param o Atlas map to store the rules in.
 void readRuleTable(const std::string & ruleset, MapType & o) {
     std::stringstream query;
     query << "SELECT * FROM " << m_connection.rule() << " WHERE "
           << " ruleset = '" << ruleset << "'";
     DatabaseResult res = m_connection.runSimpleSelectQuery(query.str());
     DatabaseResult::const_iterator I = res.begin();
     DatabaseResult::const_iterator Iend = res.end();
     for (; I != Iend; ++I) {
         MapType & data = (o[I.column("id")] = MapType()).asMap();
         m_connection.decodeMessage(I.column("contents"), data);
     }
 }
Esempio n. 3
0
 /// \brief Read all the rules sets from the rules table
 ///
 void readRuleTableSets(std::set<std::string> & sets) {
     std::stringstream query;
     query << "SELECT ruleset FROM " << m_connection.rule();
     DatabaseResult res = m_connection.runSimpleSelectQuery(query.str());
     DatabaseResult::const_iterator I = res.begin();
     DatabaseResult::const_iterator Iend = res.end();
     for (; I != Iend; ++I) {
         std::string ruleset_name = I.column("ruleset");
         if (sets.find(ruleset_name) == sets.end()) {
             sets.insert(ruleset_name);
         }
     }
 }
Esempio n. 4
0
void StorageManager::restoreChildren(LocatedEntity * parent)
{
    Database * db = Database::instance();
    DatabaseResult res = db->selectEntities(parent->getId());
    EntityBuilder * eb = EntityBuilder::instance();

    // Iterate over res creating entities, and sorting out position, location
    // and orientation. Restore children, but don't restore any properties yet.
    DatabaseResult::const_iterator I = res.begin();
    DatabaseResult::const_iterator Iend = res.end();
    for (; I != Iend; ++I) {
        const std::string id = I.column("id");
        const int int_id = forceIntegerId(id);
        const std::string type = I.column("type");
        //By sending an empty attributes pointer we're telling the builder not to apply any default
        //attributes. We will instead apply all attributes ourselves when we later on restore attributes.
        Atlas::Objects::SmartPtr<Atlas::Objects::Entity::RootEntityData> attrs(nullptr);
        LocatedEntity * child = eb->newEntity(id, int_id, type, attrs, BaseWorld::instance());
        if (!child) {
            log(ERROR, compose("Could not restore entity with id %1 of type %2"
                    ", most likely caused by this type missing.",
                    id, type));
            continue;
        }
        
        const std::string location_string = I.column("location");
        MapType loc_data;
        db->decodeMessage(location_string, loc_data);
        child->m_location.readFromMessage(loc_data);
        if (!child->m_location.pos().isValid()) {
            std::cout << "No pos data" << std::endl << std::flush;
            log(ERROR, compose("Entity %1 restored from database has no "
                               "POS data. Ignored.", child->getId()));
            delete child;
            continue;
        }
        child->m_location.m_loc = parent;
        child->setFlags(entity_clean | entity_pos_clean | entity_orient_clean);
        BaseWorld::instance().addEntity(child);
        restoreChildren(child);
    }
}
Esempio n. 5
0
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);

}