// This file may be redistributed and modified only under the terms of
// the GNU Lesser General Public License (See COPYING for details).
// Copyright 2000-2001 Aloril,
// Copyright 2004-2005 Alistair Riddoch
#include <Atlas/Objects/loadDefaults.h>
#include <Atlas/Objects/SmartPtr.h>
#include <Atlas/Objects/Anonymous.h>
#include <Atlas/Objects/objectFactory.h>
#include <Atlas/Message/DecoderBase.h>
#include <Atlas/Codecs/XML.h>
#include <fstream>
#include <set>
using Atlas::Message::Element;
using Atlas::Message::ListType;
using Atlas::Message::MapType;
namespace Atlas { namespace Objects {
typedef std::map<std::string, Element> MessageElementMap;
class LoadDefaultsDecoder : public Atlas::Message::DecoderBase
{
public:
LoadDefaultsDecoder(const std::string& filename);
const Element & getMessageElement(const std::string& id) const;
protected:
virtual void messageArrived(const MapType&);
private:
void setAttributes(Root &obj, //Root &obj_inst,
const Element& melem,
std::set<std::string> used_attributes);
void fillDefaults();
MessageElementMap m_objects;
};
LoadDefaultsDecoder::LoadDefaultsDecoder(const std::string& filename)
{
std::fstream stream;
stream.open(filename.c_str(), std::ios::in);
if (!stream) {
throw DefaultLoadingException("Failed to open file " + filename);
}
//replace following code with:
//getCodecByName(const std::string& name, Stream& stream, Bridge* bridge)
//typedef list<Atlas::Factory<Atlas::Codec<std::iostream> >*> FactoryCodecs;
//FactoryCodecs *myCodecs = Factory<Codec<std::iostream> >::factories();
//FactoryCodecs::iterator i;
//Atlas::Codec<std::iostream> *codec = NULL;
//for (i = myCodecs->begin(); i != myCodecs->end(); ++i)
//if((*i)->getName() == "XML")
//codec = (*i)->New(Codec<std::iostream>::Parameters((iostream&)stream, this));
//end of replace
Atlas::Codec *codec = new Atlas::Codecs::XML(stream, *this);
if (!codec) {
throw DefaultLoadingException("XML codec not found");
}
while(stream) {
codec->poll();
}
delete codec;
MapType anonymous_obj;
m_objects["anonymous"] = anonymous_obj;
MapType generic_obj;
m_objects["generic"] = generic_obj;
fillDefaults();
}
const Element & LoadDefaultsDecoder::getMessageElement(const std::string& id) const
{
MessageElementMap::const_iterator I = m_objects.find(id);
if (I == m_objects.end()) {
throw DefaultLoadingException(id + " not found in XML file");
} else {
return (*I).second;
}
}
void LoadDefaultsDecoder::messageArrived(const MapType& o)
{
MessageElementMap::const_iterator I = o.find("id");
if (I == o.end()) {
return;
}
std::string id(I->second.asString());
m_objects[id] = o;
}
void LoadDefaultsDecoder::setAttributes(Root &obj, //Root &obj_inst,
const Element& melem,
std::set<std::string> used_attributes)
{
MapType::const_iterator I;
for (I = melem.asMap().begin(); I != melem.asMap().end(); I++) {
std::set<std::string>::const_iterator attr_found =
used_attributes.find(I->first);
if (attr_found == used_attributes.end()) {
//cout<<" -->"<<I->first<<endl;
obj->setAttr(I->first, I->second);
//obj_inst->setAttr(I->first, I->second);
}
used_attributes.insert(I->first);
}
I = melem.asMap().find(Atlas::Objects::PARENTS_ATTR);
if (I != melem.asMap().end()) {
for (ListType::const_iterator J = I->second.asList().begin();
J != I->second.asList().end(); J++) {
//cout<<" >"<<J->asString()<<endl;
const Element & parent_melem = getMessageElement(J->asString());
setAttributes(obj, /*obj_inst,*/ parent_melem, used_attributes);
}
}
}
void LoadDefaultsDecoder::fillDefaults()
{
std::list<std::string> keys = Factories::instance()->getKeys();
for(std::list<std::string>::const_iterator I = keys.begin();
I != keys.end();
I++) {
//cout<<(*I)<<endl;
//get atlas.xml object
const Element & melem = getMessageElement(*I);
//get class instances
Root obj = Factories::instance()->createObject(*I).getDefaultObject();
//Root obj_inst = objectInstanceFactory.createObject(*I).getDefaultObject();
//add attributes recursively
std::set<std::string> used_attributes;
setAttributes(obj, /*obj_inst,*/ melem, used_attributes);
//add object definition
Root obj_def = Factories::instance()->createObject(*I);
obj_def->setObjtype(obj->getObjtype());
MapType::const_iterator J;
for (J = melem.asMap().begin(); J != melem.asMap().end(); J++) {
obj_def->setAttr(J->first, J->second);
}
objectDefinitions[obj_def->getId()] = obj_def;
//modify attributes in instance that differ from definitions
std::list<std::string> parents;
parents.push_back(std::string(*I));
obj/*_inst*/->setParents(parents);
obj/*_inst*/->setId("");
if(obj/*_inst*/->getObjtype()=="op_definition")
obj/*_inst*/->setObjtype("op");
else
obj/*_inst*/->setObjtype("obj");
}
}
void loadDefaults(const std::string& filename)
{
LoadDefaultsDecoder load_defaults(filename);
Entity::Anonymous e;
e = e->getDefaultObject();
std::vector<double> coords(3, 0.0);
e->setPos(coords);
e->setVelocity(coords);
std::list<std::string> parents;
e->setParents(parents);
}
} } // namespace Atlas::Objects
syntax highlighted by Code2HTML, v. 0.9.1