#include "X3DAbstractNode.h" #include "SFType.h" #include #include using namespace std; namespace X3DTK { X3DAbstractNode::X3DAbstractNode() : _name(""), _type(0) { define(Recorder::getTypeName("X3DAbstractNode", "Abstract", "Abstract")); } X3DAbstractNode::X3DAbstractNode(const X3DAbstractNode &N) : _name(""), _type(N._type) { addOneReference(); } SFNode X3DAbstractNode::clone() const { SFNode clone = _type->_cloner->create(); clone->_name = ""; clone->_type = _type; addOneReference(); // copying attributes SFType *type = _type; while (type != 0) { const std::map &attributesMap = type->_attributesMap; for (std::map::const_iterator a = attributesMap.begin(); a != attributesMap.end(); ++a) clone->set((*a).first, get((*a).first)); const vector > &nodeMap = type->_nodeMap; for (vector >::const_iterator s = nodeMap.begin(); s != nodeMap.end(); ++s) clone->setChild((*s).second->getNode(this)); const vector > &nodesMap = type->_nodesMap; for (vector >::const_iterator m = nodesMap.begin(); m != nodesMap.end(); ++m) { const MFNode &nodes = (*m).second->getNodes(this); for (MFNode::const_iterator n = nodes.begin(); n != nodes.end(); ++n) clone->setChild(*n); } type = type->_parent; } return clone; } X3DAbstractNode::~X3DAbstractNode() { // Removes the instance for all the parents MFNode parentList = _parentList; for (MFNode::const_iterator p = parentList.begin(); p != parentList.end(); ++p) (*p)->removeChild(this); //this method is recursive and removes one instance for all the parents of //the SFType. SFType::removeOneReference(_type); } void X3DAbstractNode::removeChildren() { // Removes the children. SFType *type = _type; while (type != 0) { const vector > &nodeMap = type->_nodeMap; for (vector >::const_iterator s = nodeMap.begin(); s != nodeMap.end(); ++s) (*s).second->removeThisNode(this); // removes MFNode const vector > &nodesMap = type->_nodesMap; for (vector >::const_iterator m = nodesMap.begin(); m != nodesMap.end(); ++m) (*m).second->removeTheseNodes(this); type = type->_parent; } } void X3DAbstractNode::setName(const SFString &name) { _name = name; } void X3DAbstractNode::addParent(const SFNode &N) { if (N != 0) _parentList.push_back(N); } bool X3DAbstractNode::removeParent(const SFNode &N) { if (N != 0) { MFNode::iterator res = find(_parentList.begin(), _parentList.end(), N); if (res != _parentList.end()) { _parentList.erase(res); return true; } } return false; } MFNode X3DAbstractNode::getChildList() { MFNode result; SFType *type = _type; while (type != 0) { const vector > &nodeMap = type->_nodeMap; for (vector >::const_iterator s = nodeMap.begin(); s != nodeMap.end(); ++s) result.push_back((*s).second->getNode(this)); // concatenate MFNode const vector > &nodesMap = type->_nodesMap; for (vector >::const_iterator m = nodesMap.begin(); m != nodesMap.end(); ++m) { const MFNode &nodes = (*m).second->getNodes(this); for (MFNode::const_iterator n = nodes.begin(); n != nodes.end(); ++n) result.push_back(*n); } type = type->_parent; } return result; } bool X3DAbstractNode::setChild(X3DAbstractNode *C) { SFType *type = _type; while (type != 0) { const vector > &nodeMap = type->_nodeMap; for (vector >::const_iterator s = nodeMap.begin(); s != nodeMap.end(); ++s) { if ((*s).second->setNode(this, C)) return true; } const vector > &nodesMap = type->_nodesMap; for (vector >::const_iterator m = nodesMap.begin(); m != nodesMap.end(); ++m) { if ((*m).second->addNode(this, C)) return true; } type = type->_parent; } if (C != 0) cx3d << "X3DAbstractNode::setChild: a " << C->getSceneGraphName() << "::" << C->getTypeName() << " node cannot be a child of a " << getSceneGraphName() << "::" << getTypeName() << " node!" << endl; else cx3d << "X3DAbstractNode::setChild: cannot set a NULL child!" << endl; return false; } bool X3DAbstractNode::removeChild(X3DAbstractNode *C) { SFType *type = _type; while (type != 0) { const vector > &nodeMap = type->_nodeMap; for (vector >::const_iterator s = nodeMap.begin(); s != nodeMap.end(); ++s) { if ((*s).second->removeNode(this, C)) return true; } const vector > &nodesMap = type->_nodesMap; for (vector >::const_iterator m = nodesMap.begin(); m != nodesMap.end(); ++m) { if ((*m).second->removeNode(this, C)) return true; } type = type->_parent; } return false; } X3DField X3DAbstractNode::get(const SFString &name) const { X3DMemberFunctor *mf = 0; SFType *type = _type; while ((mf == 0) && (type != 0)) { mf = type->getMemberFunctor(name); type = type->_parent; } if (mf != 0) return mf->getValueOf(this); cx3d << "X3DAbstractNode::set: incompatible types!" << endl; return X3DField::null; } void X3DAbstractNode::set(const SFString &name, const X3DField &field) { X3DMemberFunctor *mf = 0; SFType *type = _type; while ((mf == 0) && (type != 0)) { mf = type->getMemberFunctor(name); type = type->_parent; } if (mf != 0) mf->setValueOf(this, field); cx3d << "X3DAbstractNode::set: incompatible types!" << endl; } void X3DAbstractNode::loadAttribute(const SFString &name, const SFString &value) { X3DField field = get(name); if (field != X3DField::null) { _type->getFieldLoader(name)->load(field, value); return; } cx3d << "X3DAbstractNode::loadAttribute: " << name << " is not an attribute of " << _type->getSceneGraphName() << "::" << getTypeName() << " !" << endl; } SFString X3DAbstractNode::writeAttribute(const SFString &name) { X3DField field = get(name); if (field != X3DField::null) return _type->getFieldWriter(name)->write(field); cx3d << "X3DAbstractNode::writeAttribute: " << name << " is not an attribute of " << _type->getSceneGraphName() << "::" << getTypeName() << " !" << endl; return SFString(); } void X3DAbstractNode::loadAttributes(const X3DFileElement *element) { int index; SFType *type = _type; while (type != 0) { std::map &attributesMap = type->_attributesMap; for (std::map::iterator a = attributesMap.begin(); a != attributesMap.end(); ++a) { index = element->getIndexAttribute((*a).first); if (index != -1) { X3DField field = get((*a).first); (*a).second.loader->load(field, element->getAttribute(index)); } } type = type->_parent; } } void X3DAbstractNode::writeAttributes(SFString &output) { SFType *type = _type; while (type != 0) { const std::map &attributesMap = type->_attributesMap; for (std::map::const_iterator a = attributesMap.begin(); a != attributesMap.end(); ++a) { X3DField field = get((*a).first); (*a).second.writer->writeToFile(output, (*a).first, field, (*a).second.init); } type = type->_parent; } } void X3DAbstractNode::addParentToChild(SFNode parent, SFNode child) { if (child != 0) child->addParent(parent); } void X3DAbstractNode::removeParentFromChild(SFNode parent, SFNode child) { if (child != 0) child->removeParent(parent); } }