Main Page   Namespace List   Class Hierarchy   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

infoReader

Introduction

This is an example on how to create a parent node, meaning a node that can have children. That implies that we must extend the traversal algorithm to visit the children of the node. Here we define an X3D::Info node that can contain two nodes, X3D::Price and X3D::Modeler.

Defining X3D::Info

Like a node that can only be a child, the three special methods load, write and clone still have to be redefined. Nevertheless others methods must be redefined. For the X3D::Price child, the methods setPrice and getPrice are defined. Note in setPrice the calls to removeLink and addLink. Three other necessary methods are redefined: setChild, addChild and removeChild.

Defining X3D::Price and X3D::Modeler

These nodes are simple child nodes and are defined like the nodes of the precedent examples.

Extending the traversal algorithm

To enable the visit of the X3D::Price and X3D::Modeler, We have to extend the DFSGroupingWalker because X3D::Info belongs to the Grouping Component. To finish, we extend the DFS algorithm DFSGraphTraversal by defining MyDFSGraphTraversal.

Defining a new simple processor

To test MyDFS, we define a new processor called InfoReader that extracts and displays the content of the nodes X3D::Info, X3D::Price and X3D::Modeler.

code

Info

Info.h




#ifndef INFO_H
#define INFO_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

class Price;
class Modeler;

class Info : public X3DChildNode
{
public:
  // Constructor.
  Info();
  // Constructs a Cylinder from its attributes.
  Info(const SFString &date,
       SFNode price,
       SFNode modeler);
            
  // Clones the node.
  virtual SFNode clone() const;  
  // sets the date.
  void setDate(const SFString &date);
  // sets the Price node.
  void setPrice(Price *price);
  // sets the Modeler node.
  void setModeler(Modeler *modeler);  

  // gets the date.
  inline SFString getDate() const {return _date;};
  // sets the Price node.
  inline SFNode getPrice() const {return _price;};
  // sets the Modeler node.
  inline SFNode getModeler() const {return _modeler;};  
  
  virtual bool addChild(const SFAbstractNode &N);
  virtual bool setChild(const SFAbstractNode &N);
  virtual bool removeChild(const SFAbstractNode &N);
  
  // Loads the attributes from a X3DFileElement e.
  virtual void load(const X3DFileElement *element);
  // Writes the attributes of the node.
  virtual SFString write() const;

protected:
  // Copy constructor.     
  Info(const Info &I);

private:
  SFString _date;
  
  SFNode _price;
  SFNode _modeler;
};

}
}

#endif

Info.cpp

#include "Info.h"
#include "Price.h"
#include "Modeler.h"

namespace X3DTK {
namespace X3D {

Info::Info()
: X3DChildNode(), _date("0/0/0"), _price(0), _modeler(0)
{
  // Defines the tag of the node. This string must be the same than the one 
  // entered for the creation function, otherwise the node won't be loaded.
  defineTypeName("Info");
}

Info::Info(const SFString &date, SFNode price, SFNode modeler)
: X3DChildNode(), _date(date), _price(price), _modeler(modeler)
{
  // Defines the tag of the node.
  defineTypeName("Info");
}

Info::Info(const Info &I)
: X3DChildNode(I), _date(I._date), _price(I._price), _modeler(I._modeler)
{
}

SFNode Info::clone() const
{
  return new Info(*this);
}

void Info::setDate(const SFString &date)
{
  _date = date;
}

void Info::setPrice(Price *price)
{
  removeLink(this, _price);
  _price = price;
  addLink(this, _price);
}

void Info::setModeler(Modeler *modeler)
{
  removeLink(this, _modeler);
  _modeler = modeler;
  addLink(this, _modeler);
}

bool Info::addChild(const SFAbstractNode &N)
{
  if (dynamic_cast<Price *>(N) != 0)
  {
    if (_price != 0)
      return false;
      
    setPrice(static_cast<Price *>(N));
    return true;
  }
  
  if (dynamic_cast<Modeler *>(N) != 0)
  {
    if (_modeler != 0)
      return false;
      
    setModeler(static_cast<Modeler *>(N));
    return true;    
  }
  
  return false;
}

bool Info::setChild(const SFAbstractNode &N)
{
  if (dynamic_cast<Price *>(N) != 0)
  {
    setPrice(static_cast<Price *>(N));
    return true;
  }
  
  if (dynamic_cast<Modeler *>(N) != 0)
  {
    setModeler(static_cast<Modeler *>(N));
    return true;    
  }
  
  return false;
}

bool Info::removeChild(const SFAbstractNode &N)
{
  if (_price == N)
  {
    setPrice(0);
    return true;
  }
  
  if (_modeler == N)
  {
    setModeler(0);
    return true;
  }
  
  return false;
}

void Info::load(const X3DFileElement *element)
{
  int index;
  index = element->getIndexAttribute("date");
  if (index != -1)
    _date = element->getAttribute(index);
}

SFString Info::write() const
{
  SFString attr;
  if (_date != "0/0/0")    
    attr += " date=\"" + toSFString(_date) + "\"";
      
  return attr;
}

}
}

Price

Price.h




#ifndef PRICE_H
#define PRICE_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

class Price : public X3DChildNode
{
public:
  // Constructor.
  Price();
  // Constructs a Cylinder from its attributes.
  Price(SFFloat price,
        const SFString &money);
            
  // Clones the node.
  virtual SFNode clone() const;  
  // sets the date.
  void setPrice(SFFloat price);
  // sets the date.
  void setMoney(const SFString &money);

  // gets the price.
  inline SFFloat getPrice() const {return _price;};
  // sets the money.
  inline SFString getMoney() const {return _money;};
 
  // Loads the attributes from a X3DFileElement e.
  virtual void load(const X3DFileElement *element);
  // Writes the attributes of the node.
  virtual SFString write() const;

protected:
  // Copy constructor.     
  Price(const Price &I);

private:
  SFFloat _price;
  SFString _money;
};

}
}

#endif

Price.cpp

#include "Price.h"

namespace X3DTK {
namespace X3D {

Price::Price()
: X3DChildNode(), _price(0.0f), _money("euro")
{
  // Defines the tag of the node. This string must be the same than the one 
  // entered for the creation function, otherwise the node won't be loaded.
  defineTypeName("Price");
}

Price::Price(SFFloat price, const SFString &money)
: X3DChildNode(), _price(price), _money(money)
{
  // Defines the tag of the node.
  defineTypeName("Price");
}

Price::Price(const Price &P)
: X3DChildNode(P), _price(P._price), _money(P._money)
{
}

SFNode Price::clone() const
{
  return new Price(*this);
}

void Price::setPrice(SFFloat price)
{
  _price = price;
}

void Price::setMoney(const SFString &money)
{
  _money = money;
}

void Price::load(const X3DFileElement *element)
{
  int index;
  index = element->getIndexAttribute("price");
  if (index != -1)
    _price = element->getAttribute(index).toFloat();
  
  index = element->getIndexAttribute("money");
  if (index != -1)
    _money = element->getAttribute(index);  
}

SFString Price::write() const
{
  SFString attr;
  if (_price != 0.0f)    
    attr += " price=\"" + toSFString(_price) + "\"";
  if (_money != "euro")
    attr += " money=\"" + _money + "\"";
      
  return attr;
}

}
}

Modeler

Modeler.h




#ifndef MODELER_H
#define MODELER_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

class Modeler : public X3DChildNode
{
public:
  // Constructor.
  Modeler();
  // Constructs a Cylinder from its attributes.
  Modeler(const SFString &name);
            
  // Clones the node.
  virtual SFNode clone() const;  
  // sets the date.
  void setName(const SFString &name);

  // gets the name.
  inline SFString getName() const {return _name;};
 
  // Loads the attributes from a X3DFileElement e.
  virtual void load(const X3DFileElement *element);
  // Writes the attributes of the node.
  virtual SFString write() const;

protected:
  // Copy constructor.     
  Modeler(const Modeler &I);

private:
  SFString _name;
};

}
}

#endif

Modeler.cpp

#include "Modeler.h"

namespace X3DTK {
namespace X3D {

Modeler::Modeler()
: X3DChildNode(), _name("")
{
  // Defines the tag of the node. This string must be the same than the one 
  // entered for the creation function, otherwise the node won't be loaded.
  defineTypeName("Modeler");
}

Modeler::Modeler(const SFString &name)
: X3DChildNode(), _name(name)
{
  // Defines the tag of the node.
  defineTypeName("Modeler");
}

Modeler::Modeler(const Modeler &P)
: X3DChildNode(P), _name(P._name)
{
}

SFNode Modeler::clone() const
{
  return new Modeler(*this);
}

void Modeler::setName(const SFString &name)
{
  _name = name;
}

void Modeler::load(const X3DFileElement *element)
{
  int index;
  index = element->getIndexAttribute("name");
  if (index != -1)
    _name = element->getAttribute(index);  
}

SFString Modeler::write() const
{
  SFString attr;
  if (_name != "")    
    attr += " name=\"" + _name + "\"";
      
  return attr;
}

}
}

MyGroupingCreator

MyGroupingCreator.h




#ifndef MYGROUPINGCREATOR_H
#define MYGROUPINGCREATOR_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

// Concrete component Creator for the Grouping component defining the default 
// X3D nodes.

class MyGroupingCreator : public GroupingCreator
{
public:
  // Constructor.
  MyGroupingCreator();
};

}
}

#endif

MyGroupingCreator.cpp

#include "MyGroupingCreator.h"
#include "Info.h"
#include "Price.h"
#include "Modeler.h"

namespace X3DTK {
namespace X3D {

MyGroupingCreator::MyGroupingCreator()
: GroupingCreator()
{
  // Defines the new creation functions for the new nodes.
  defineNewNode<Info>();
  defineNewNode<Price>();
  defineNewNode<Modeler>();  
}

}
}

MyDFSGroupingWalker

MyDFSGroupingWalker.h




#ifndef MyDFSGROUPINGWALKER_H
#define MyDFSGROUPINGWALKER_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

class Info;


class MyDFSGroupingWalker : public DFSGroupingWalker
{
public:
  MyDFSGroupingWalker();
  virtual ~MyDFSGroupingWalker();
  
  virtual void walkInfo(Info *I) const;
};

}
}

#endif

MyDFSGroupingWalker.cpp

#include "MyDFSGroupingWalker.h"
#include "Info.h"
#include "Price.h"
#include "Modeler.h"

#include <iostream>
using namespace std;

namespace X3DTK {
namespace X3D {

MyDFSGroupingWalker::MyDFSGroupingWalker()
: DFSGroupingWalker()
{
  defineNewWalkingFunction(&MyDFSGroupingWalker::walkInfo);
}

MyDFSGroupingWalker::~MyDFSGroupingWalker()
{
}

void MyDFSGroupingWalker::walkInfo(Info *I) const
{
  visitor->enter(I);
  
  SFNode N = I->getPrice();
  if ((N != 0) && (visitor->walkOn(I, N)))
    walker->walk(N);
  
  N = I->getModeler();
  if ((N != 0) && (visitor->walkOn(I, N)))
    walker->walk(N);  
  
  visitor->leave(I);
}

}
}

MyDFSGraphTraversal

MyDFSGraphTraversal.h




#ifndef MYDFSGRAPHTRAVERSAL_H
#define MYDFSGRAPHTRAVERSAL_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {


class MyDFSGraphTraversal : public DFSGraphTraversal
{
public:
  MyDFSGraphTraversal();
};

}
}

#endif

MyDFSGraphTraversal.cpp

#include "MyDFSGraphTraversal.h"
#include "MyDFSGroupingWalker.h"

namespace X3DTK {
namespace X3D {

MyDFSGraphTraversal::MyDFSGraphTraversal()
{
  setComponentWalker(new MyDFSGroupingWalker());
}

}
}

InfoReaderGroupingVisitor

InfoReaderGroupingVisitor.h




#ifndef INFOREADERGROUPINGVISITOR_H
#define INFOREADERGROUPINGVISITOR_H

#include <X3DTK/x3dscenegraph.h>

namespace X3DTK {
namespace X3D {

class Info;
class Price;
class Modeler;


class InfoReaderGroupingVisitor : public GroupingVisitor
{
public:
  InfoReaderGroupingVisitor();
  virtual ~InfoReaderGroupingVisitor();

  virtual void enterInfo(Info *I) const;
  virtual void enterPrice(Price *P) const;
  virtual void enterModeler(Modeler *M) const;
};

}
}

#endif

InfoReaderGroupingVisitor.cpp

#include "InfoReaderGroupingVisitor.h"
#include "Info.h"
#include "Price.h"
#include "Modeler.h"

#include <iostream>

using namespace std;

namespace X3DTK {
namespace X3D {

InfoReaderGroupingVisitor::InfoReaderGroupingVisitor()
: GroupingVisitor()
{
  // WalkOn functions.
  defineNewEnterFunction(&InfoReaderGroupingVisitor::enterInfo);
  defineNewEnterFunction(&InfoReaderGroupingVisitor::enterPrice);
  defineNewEnterFunction(&InfoReaderGroupingVisitor::enterModeler);    
}

InfoReaderGroupingVisitor::~InfoReaderGroupingVisitor()
{
}

void InfoReaderGroupingVisitor::enterInfo(Info *I) const
{
  cout << "Informations relative to the scene:"<< endl;
}

void InfoReaderGroupingVisitor::enterPrice(Price *P) const
{
  cout << "  price = " << P->getPrice() << " " << P->getMoney() << endl;
}

void InfoReaderGroupingVisitor::enterModeler(Modeler *M) const
{
  cout << "  realized on the " << M->getName() << " modeler" << endl;
}

}
}

InfoReader

InfoReader.h




#ifndef INFOREADER_H
#define INFOREADER_H

#include <X3DTK/kernel.h>

namespace X3DTK {
namespace X3D {


class InfoReader : public X3DOnePassProcessor
{
public:
  InfoReader();
  virtual ~InfoReader();
  
  virtual void read(SFNode N);
};

}
}

#endif

InfoReader.cpp

#include "InfoReader.h"
#include "MyDFSGraphTraversal.h"
#include "InfoReaderGroupingVisitor.h"

namespace X3DTK {
namespace X3D {

InfoReader::InfoReader()
{
  graphTraversal = new MyDFSGraphTraversal();
  
  graphTraversal->setComponentVisitor(new InfoReaderGroupingVisitor());
}

InfoReader::~InfoReader()
{
  delete graphTraversal;
}

void InfoReader::read(SFNode N)
{
  graphTraversal->traverse(N);
}

}
}

Main

main.cpp

#include "InfoReader.h"
#include "MyGroupingCreator.h"

#include <X3DTK/x3dscenegraph.h>
#include <iostream>

using namespace X3DTK;
using namespace std;

int main(int argc, char *argv[])
{
  if (argc <= 1)
  {
    cerr << "usage: infoReader input" << endl;
    exit(0);
  }
  
  // DefaultLoader to load the default X3D Nodes.
  X3D::Loader *loader = new X3D::Loader();
  loader->setComponentCreator(new X3D::MyGroupingCreator());
  
  // Instanciation of the new InfoReader.
  X3D::InfoReader *infoReader = new X3D::InfoReader();
  
  // Loads the scene.
  X3D::Scene *s = loader->load(argv[1], false);
  // reads the graph.
  infoReader->read(s);
      
  return 1;
}


Generated on Thu Oct 9 13:50:57 2003 for X3DToolKit by doxygen1.2.18