autogen.C

00001 /*
00002  * This file is part of the "Archon" framework.
00003  * (http://files3d.sourceforge.net)
00004  *
00005  * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.
00006  *
00007  * Permission to use, copy, modify, and distribute this software and
00008  * its documentation under the terms of the GNU General Public License is
00009  * hereby granted. No representations are made about the suitability of
00010  * this software for any purpose. It is provided "as is" without express
00011  * or implied warranty. See the GNU General Public License
00012  * (http://www.gnu.org/copyleft/gpl.html) for more details.
00013  *
00014  * The characters in this file are ISO8859-1 encoded.
00015  *
00016  * The documentation in this file is in "Doxygen" style
00017  * (http://www.doxygen.org).
00018  */
00019 
00020 #include <fstream>
00021 
00022 #include <archon/util/exception.H>
00023 #include <archon/x3d/server/exception.H>
00024 #include <archon/x3d/server/x3d.H>
00025 
00026 using namespace std;
00027 using namespace Archon::Utilities;
00028 using namespace Archon::X3D;
00029 
00030 map<const FieldType *, string> retTypes;
00031 map<const FieldType *, string> argTypes;
00032 
00033 int indentationStep;
00034 
00035 inline string indent(int level)
00036 {
00037   int n = level * indentationStep;
00038   int m = 0;
00039   while(n>=8) { n -= 8; ++m; }
00040   return string(m, '\t') + string(n, ' ');
00041 }
00042 
00043 int autogen(int argc, const char *argv[])
00044 {
00045   indentationStep = argc > 1 ? atoi(argv[1]) : 2;
00046   string config_H = argc > 2 ? argv[2] : "config.autogen.H";
00047   string type_C   = argc > 3 ? argv[3] : "type.autogen.C";
00048   string node_H   = argc > 4 ? argv[4] : "node.autogen.H";
00049 
00050   Archon::X3D::initialize();
00051 
00052   retTypes[SFBool::type] = "bool ";
00053   retTypes[MFBool::type] = "std::vector<bool> ";
00054 
00055   retTypes[SFColor::type] = "Vector3 ";
00056   retTypes[MFColor::type] = "std::vector<Vector3> ";
00057 
00058   retTypes[SFColorRGBA::type] = "Vector4 ";
00059   retTypes[MFColorRGBA::type] = "std::vector<Vector4> ";
00060 
00061   retTypes[SFDouble::type] = "double ";
00062   retTypes[MFDouble::type] = "std::vector<double> ";
00063 
00064   retTypes[SFFloat::type] = "double ";
00065   retTypes[MFFloat::type] = "std::vector<double> ";
00066 
00067   retTypes[SFImage::type] = "Image ";
00068   retTypes[MFImage::type] = "std::vector<Image> ";
00069 
00070   retTypes[SFInt32::type] = "int ";
00071   retTypes[MFInt32::type] = "std::vector<int> ";
00072 
00073   retTypes[SFRotation::type] = "Rotation3 ";
00074   retTypes[MFRotation::type] = "std::vector<Rotation3> ";
00075 
00076   retTypes[SFString::type] = "std::string ";
00077   retTypes[MFString::type] = "std::vector<std::string> ";
00078 
00079   retTypes[SFTime::type] = "Time ";
00080   retTypes[MFTime::type] = "std::vector<Time> ";
00081 
00082   retTypes[SFVec2d::type] = "Vector2 ";
00083   retTypes[MFVec2d::type] = "std::vector<Vector2> ";
00084 
00085   retTypes[SFVec2f::type] = "Vector2 ";
00086   retTypes[MFVec2f::type] = "std::vector<Vector2> ";
00087 
00088   retTypes[SFVec3d::type] = "Vector3 ";
00089   retTypes[MFVec3d::type] = "std::vector<Vector3> ";
00090 
00091   retTypes[SFVec3f::type] = "Vector3 ";
00092   retTypes[MFVec3f::type] = "std::vector<Vector3> ";
00093 
00094 
00095   argTypes[SFBool::type] = "bool ";
00096   argTypes[MFBool::type] = "const std::vector<bool> &";
00097 
00098   argTypes[SFColor::type] = "Vector3 ";
00099   argTypes[MFColor::type] = "const std::vector<Vector3> &";
00100 
00101   argTypes[SFColorRGBA::type] = "Vector4 ";
00102   argTypes[MFColorRGBA::type] = "const std::vector<Vector4> &";
00103 
00104   argTypes[SFDouble::type] = "double ";
00105   argTypes[MFDouble::type] = "const std::vector<double> &";
00106 
00107   argTypes[SFFloat::type] = "double ";
00108   argTypes[MFFloat::type] = "const std::vector<double> &";
00109 
00110   argTypes[SFImage::type] = "const Image &";
00111   argTypes[MFImage::type] = "const std::vector<Image> &";
00112 
00113   argTypes[SFInt32::type] = "int ";
00114   argTypes[MFInt32::type] = "const std::vector<int> &";
00115 
00116   argTypes[SFRotation::type] = "Rotation3 ";
00117   argTypes[MFRotation::type] = "const std::vector<Rotation3> &";
00118 
00119   argTypes[SFString::type] = "std::string ";
00120   argTypes[MFString::type] = "const std::vector<std::string> &";
00121 
00122   argTypes[SFTime::type] = "Time ";
00123   argTypes[MFTime::type] = "const std::vector<Time> &";
00124 
00125   argTypes[SFVec2d::type] = "Vector2 ";
00126   argTypes[MFVec2d::type] = "const std::vector<Vector2> &";
00127 
00128   argTypes[SFVec2f::type] = "Vector2 ";
00129   argTypes[MFVec2f::type] = "const std::vector<Vector2> &";
00130 
00131   argTypes[SFVec3d::type] = "Vector3 ";
00132   argTypes[MFVec3d::type] = "const std::vector<Vector3> &";
00133 
00134   argTypes[SFVec3f::type] = "Vector3 ";
00135   argTypes[MFVec3f::type] = "const std::vector<Vector3> &";
00136 
00137 
00138   // node.H
00139 
00140   {
00141     int l = 0;
00142 
00143     ofstream out(node_H.c_str());
00144 
00145     out
00146       << indent(l) << "/*\n"
00147       << indent(l) << " * This file is part of the \"Archon\" framework.\n"
00148       << indent(l) << " * (http://files3d.sourceforge.net)\n"
00149       << indent(l) << " *\n"
00150       << indent(l) << " * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.\n"
00151       << indent(l) << " *\n"
00152       << indent(l) << " * Permission to use, copy, modify, and distribute this software and\n"
00153       << indent(l) << " * its documentation under the terms of the GNU General Public License is\n"
00154       << indent(l) << " * hereby granted. No representations are made about the suitability of\n"
00155       << indent(l) << " * this software for any purpose. It is provided \"as is\" without express\n"
00156       << indent(l) << " * or implied warranty. See the GNU General Public License\n"
00157       << indent(l) << " * (http://www.gnu.org/copyleft/gpl.html) for more details.\n"
00158       << indent(l) << " *\n"
00159       << indent(l) << " * The characters in this file are ISO8859-1 encoded.\n"
00160       << indent(l) << " *\n"
00161       << indent(l) << " * The documentation in this file is in \"Doxygen\" style\n"
00162       << indent(l) << " * (http://www.doxygen.org).\n"
00163       << indent(l) << " */\n"
00164       << "\n"
00165       << indent(l) << "/*\n"
00166       << indent(l) << " * Note: This file is auto-generated, so don't edit it!\n"
00167       << indent(l) << " */\n"
00168       << "\n"
00169       << "#ifndef ARCHON_X3D_PROXY_NODE_AUTOGEN_H\n"
00170       << "#define ARCHON_X3D_PROXY_NODE_AUTOGEN_H\n"
00171       << "\n"
00172       << "#include <archon/x3d/proxy/field_type.H>\n"
00173       << "#include <archon/x3d/proxy/field.H>\n"
00174       << "\n"
00175       << indent(l) << "namespace Archon\n"
00176       << indent(l) << "{\n"
00177       << indent(l+1) << "namespace X3D\n"
00178       << indent(l+1) << "{\n"
00179       << indent(l+1+1) << "namespace Proxy\n"
00180       << indent(l+1+1) << "{\n";
00181 
00182     l += 3;
00183 
00184     for(unsigned long i=0; i<NodeType::getTotalNumber(); ++i)
00185     {
00186       const NodeType *t = NodeType::get(i);
00187 
00188       if(i) out
00189         << "\n"
00190         << "\n"
00191         << "\n";
00192 
00193       out
00194         << indent(l) << "/**\n"
00195         << indent(l) << " * " << (t->isAbstract() ? "Abstract" : "Concrete") << " X3D node" << (t->isVirtualBase() ? " (virtual base)" : "") << "\n"
00196         << indent(l) << " */\n"
00197         << indent(l) << "struct " << t->getName() << ": ";
00198 
00199       {
00200         NodeType::iterator j = t->derivedFromBegin();
00201         if(j == t->derivedFromEnd()) out
00202           << "virtual NodeBase";
00203         else
00204         {
00205           while(j != t->derivedFromEnd())
00206           {
00207             const NodeType *d = *j;
00208             if(j != t->derivedFromBegin()) out
00209               << ", ";
00210             if(d->isVirtualBase()) out
00211               << "virtual ";
00212             out
00213               << d->getName();
00214             ++j;
00215           }
00216         }
00217       }
00218 
00219       out
00220         << "\n"
00221         << indent(l) << "{\n";
00222 
00223       if(!t->isAbstract())
00224       {
00225         out
00226           << indent(l+1) << "static Ref<" << t->getName() << "> create(Ref<ExecutionContext> c)\n"
00227           << indent(l+1) << "{\n"
00228           << indent(l+1+1) << "return NodeBase::create<" << t->getName() << ">(c.get(), " + Archon::Utilities::Text::toString(i) + ");\n"
00229           << indent(l+1) << "}\n"
00230           << "\n";
00231       }
00232 
00233       for(unsigned long j=0; j<t->getNumberOfImmediateFields(); ++j)
00234       {
00235         const FieldBase *f = t->getImmediateField(j);
00236 
00237         string name = f->getName();
00238 
00239         string access =
00240           f->getIsEventSource() ?
00241           f->getIsEventTarget() ? "InputOutput" : "OutputOnly" :
00242           f->getIsEventTarget() ? "InputOnly" : "InitializeOnly";
00243 
00244         if(f->getType()->getIsMultiple())
00245           access += "Seq";
00246 
00247         string type =
00248           f->getType()->getName();
00249 
00250         if(const NodeFieldBase *nf = dynamic_cast<const NodeFieldBase *>(f))
00251           type += "<" + nf->getNodeType()->getName() + "> ";
00252 
00253         out
00254           << indent(l+1) << access << "<" << type << "> "
00255           << name << ";\n";
00256       }
00257 
00258       if(t->getNumberOfImmediateFields()) out
00259         << "\n";
00260 
00261       for(unsigned long j=0; j<t->getNumberOfImmediateFields(); ++j)
00262       {
00263         const FieldBase *f = t->getImmediateField(j);
00264 
00265         string name = f->getName();
00266 
00267         out
00268           << indent(l+1) << "/*\n"
00269           << indent(l+1) << " * " << name << "\n"
00270           << indent(l+1) << " */\n";
00271 
00272         // Determine field type
00273         string cap = Archon::Utilities::Text::initCap(name);
00274         string set = "set" + cap;
00275         if(const NodeSequenceFieldBase *f2 =
00276            dynamic_cast<const NodeSequenceFieldBase *>(f))
00277         {
00278           string child = f2->getNodeType()->getName();
00279           if(f->getIsEventSource() || !f->getIsEventTarget()) out
00280             << indent(l+1) << "std::vector<Ref<" << child << "> > get" << cap << "()\n"
00281             << indent(l+1) << "{\n"
00282             << indent(l+1+1) << "return " + name + ";\n"
00283             << indent(l+1) << "}\n";
00284           if(!f->getIsEventSource() || f->getIsEventTarget()) out
00285             << indent(l+1) << "void " << set << "(const std::vector<Ref<" + child + "> > &v)\n"
00286             << indent(l+1) << "{\n"
00287             << indent(l+1+1) << name + " = v;\n"
00288             << indent(l+1) << "}\n";
00289         }
00290         else if(const NodeFieldBase *f2 =
00291                 dynamic_cast<const NodeFieldBase *>(f))
00292         {
00293           string child = f2->getNodeType()->getName();
00294           if(f->getIsEventSource() || !f->getIsEventTarget()) out
00295             << indent(l+1) << "Ref<" + child + "> get" << cap << "()\n"
00296             << indent(l+1) << "{\n"
00297             << indent(l+1+1) << "return " + name + ";\n"
00298             << indent(l+1) << "}\n";
00299           if(!f->getIsEventSource() || f->getIsEventTarget()) out
00300             << indent(l+1) << "void " << set << "(Ref<" + child + "> v)\n"
00301             << indent(l+1) << "{\n"
00302             << indent(l+1+1) << name + " = v;\n"
00303             << indent(l+1) << "}\n";
00304         }
00305         else
00306         {
00307           string ret = retTypes[f->getType()];
00308           string arg = argTypes[f->getType()];
00309           string type = f->getType()->getName();
00310           if(f->getIsEventSource() || !f->getIsEventTarget()) out
00311             << indent(l+1) << ret << "get" << cap << "()\n"
00312             << indent(l+1) << "{\n"
00313             << indent(l+1+1) << "return " + name + ";\n"
00314             << indent(l+1) << "}\n";
00315           if(!f->getIsEventSource() || f->getIsEventTarget()) out
00316             << indent(l+1) << "void " << set << "(" << arg << "v)\n"
00317             << indent(l+1) << "{\n"
00318             << indent(l+1+1) << name + " = v;\n"
00319             << indent(l+1) << "}\n";
00320         }
00321         out
00322           << "\n";
00323       }
00324 
00325       string fieldInit;
00326       for(unsigned long j=0; j<t->getNumberOfImmediateFields(); ++j)
00327       {
00328         const FieldBase *f = t->getImmediateField(j);
00329 
00330         string name = f->getName();
00331 
00332         fieldInit += string(j||!t->isAbstract()?",":":") + "\n" + indent(l+1+1) + name + "(this, " + Archon::Utilities::Text::toString(f->getId()) + ")";
00333       }
00334 
00335       if(t->isAbstract())
00336       {
00337         out
00338           << indent(l) << "protected:\n"
00339           << indent(l+1) << t->getName() << "()" << fieldInit << " {}\n";
00340       }
00341       else
00342       {
00343         out
00344           << indent(l) << "private:\n"
00345           << indent(l+1) << t->getName() << "(Session *s, unsigned long i): NodeBase(s, i)" << fieldInit << " {}\n"
00346           << "\n"
00347           << indent(l) << "public:\n"
00348           << indent(l+1) << "static NodeBase *instantiate(Session *s, unsigned long i)\n"
00349           << indent(l+1) << "{\n"
00350           << indent(l+1+1) << "return new " << t->getName() << "(s, i);\n"
00351           << indent(l+1) << "}\n";
00352       }
00353 
00354       out
00355         << indent(l) << "};\n";
00356 
00357       cout << t->getName() << "\n";
00358     }
00359 
00360     l -= 3;
00361 
00362     out
00363       << indent(l+1+1) << "}\n"
00364       << indent(l+1) << "}\n"
00365       << indent(l) << "}\n"
00366       << "\n"
00367       << "#endif // ARCHON_X3D_PROXY_NODE_AUTOGEN_H\n";
00368   }
00369 
00370 
00371   // config.H
00372 
00373   {
00374     int l = 0;
00375 
00376     ofstream out(config_H.c_str());
00377 
00378     out
00379       << indent(l) << "/*\n"
00380       << indent(l) << " * This file is part of the \"Archon\" framework.\n"
00381       << indent(l) << " * (http://files3d.sourceforge.net)\n"
00382       << indent(l) << " *\n"
00383       << indent(l) << " * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.\n"
00384       << indent(l) << " *\n"
00385       << indent(l) << " * Permission to use, copy, modify, and distribute this software and\n"
00386       << indent(l) << " * its documentation under the terms of the GNU General Public License is\n"
00387       << indent(l) << " * hereby granted. No representations are made about the suitability of\n"
00388       << indent(l) << " * this software for any purpose. It is provided \"as is\" without express\n"
00389       << indent(l) << " * or implied warranty. See the GNU General Public License\n"
00390       << indent(l) << " * (http://www.gnu.org/copyleft/gpl.html) for more details.\n"
00391       << indent(l) << " *\n"
00392       << indent(l) << " * The characters in this file are ISO8859-1 encoded.\n"
00393       << indent(l) << " *\n"
00394       << indent(l) << " * The documentation in this file is in \"Doxygen\" style\n"
00395       << indent(l) << " * (http://www.doxygen.org).\n"
00396       << indent(l) << " */\n"
00397       << "\n"
00398       << indent(l) << "/*\n"
00399       << indent(l) << " * Note: This file is auto-generated, so don't edit it!\n"
00400       << indent(l) << " */\n"
00401       << "\n"
00402       << "#ifndef ARCHON_X3D_PROXY_CONFIG_AUTOGEN_H\n"
00403       << "#define ARCHON_X3D_PROXY_CONFIG_AUTOGEN_H\n"
00404       << "\n"
00405       << indent(l) << "namespace Archon\n"
00406       << indent(l) << "{\n"
00407       << indent(l+1) << "namespace X3D\n"
00408       << indent(l+1) << "{\n"
00409       << indent(l+1+1) << "namespace Proxy\n"
00410       << indent(l+1+1) << "{\n"
00411       << indent(l+1+1+1) << "const unsigned long numberOfNodeTypes = " << NodeType::getTotalNumber() << ";\n"
00412       << indent(l+1+1) << "}\n"
00413       << indent(l+1) << "}\n"
00414       << indent(l) << "}\n"
00415       << "\n"
00416       << "#endif // ARCHON_X3D_PROXY_CONFIG_AUTOGEN_H\n";
00417   }
00418 
00419 
00420 
00421   // type.C
00422 
00423   {
00424     int l = 0;
00425 
00426     ofstream out(type_C.c_str());
00427 
00428     out
00429       << indent(l) << "/*\n"
00430       << indent(l) << " * This file is part of the \"Archon\" framework.\n"
00431       << indent(l) << " * (http://files3d.sourceforge.net)\n"
00432       << indent(l) << " *\n"
00433       << indent(l) << " * Copyright © 2002 by Kristian Spangsege and Brian Kristiansen.\n"
00434       << indent(l) << " *\n"
00435       << indent(l) << " * Permission to use, copy, modify, and distribute this software and\n"
00436       << indent(l) << " * its documentation under the terms of the GNU General Public License is\n"
00437       << indent(l) << " * hereby granted. No representations are made about the suitability of\n"
00438       << indent(l) << " * this software for any purpose. It is provided \"as is\" without express\n"
00439       << indent(l) << " * or implied warranty. See the GNU General Public License\n"
00440       << indent(l) << " * (http://www.gnu.org/copyleft/gpl.html) for more details.\n"
00441       << indent(l) << " *\n"
00442       << indent(l) << " * The characters in this file are ISO8859-1 encoded.\n"
00443       << indent(l) << " *\n"
00444       << indent(l) << " * The documentation in this file is in \"Doxygen\" style\n"
00445       << indent(l) << " * (http://www.doxygen.org).\n"
00446       << indent(l) << " */\n"
00447       << "\n"
00448       << indent(l) << "/*\n"
00449       << indent(l) << " * Note: This file is auto-generated, so don't edit it!\n"
00450       << indent(l) << " */\n"
00451       << "\n"
00452       << "#include <archon/x3d/proxy/type.H>\n"
00453       << "#include <archon/x3d/proxy/" << node_H << ">\n"
00454       << "\n"
00455       << indent(l) << "namespace Archon\n"
00456       << indent(l) << "{\n"
00457       << indent(l+1) << "namespace X3D\n"
00458       << indent(l+1) << "{\n"
00459       << indent(l+1+1) << "namespace Proxy\n"
00460       << indent(l+1+1) << "{\n";
00461 
00462     l += 3;
00463 
00464     for(unsigned long i=0; i<NodeType::getTotalNumber(); ++i)
00465     {
00466       const NodeType *t = NodeType::get(i);
00467 
00468       if(!t->getNumberOfImmediateFields()) continue;
00469 
00470       out
00471         << indent(l) << "const FieldDef fieldsOf" + t->getName() + "[] =\n"
00472         << indent(l) << "{\n";
00473 
00474       l += 1;
00475 
00476       for(unsigned long j=0; j<t->getNumberOfImmediateFields(); ++j)
00477       {
00478         const FieldBase *f = t->getImmediateField(j);
00479 
00480         out
00481           << indent(l) << "{ \"" << f->getName() << "\" },\n";
00482       }
00483 
00484       l -= 1;
00485 
00486       out
00487         << indent(l) << "};\n"
00488         << "\n";
00489     }
00490 
00491 
00492     out
00493       << indent(l) << "const NodeDef nodeDefs[] =\n"
00494       << indent(l) << "{\n";
00495 
00496     l += 1;
00497 
00498     for(unsigned long i=0; i<NodeType::getTotalNumber(); ++i)
00499     {
00500       const NodeType *t = NodeType::get(i);
00501 
00502       out
00503         << indent(l) << "{ " << "\"" << t->getName() << "\"";
00504 
00505       if(t->isUserInstantiable()) out
00506         << ", &" << t->getName() << "::instantiate";
00507       else out
00508         << ", 0";
00509 
00510       out
00511         << ", " << t->getNumberOfImmediateFields();
00512 
00513       if(t->getNumberOfImmediateFields()) out
00514         << ", fieldsOf" + t->getName();
00515       else out
00516         << ", 0";
00517 
00518       out
00519         << " },\n";
00520     }
00521 
00522     l -= 4;
00523 
00524     out
00525       << indent(l+1+1+1) << "};\n"
00526       << indent(l+1+1) << "}\n"
00527       << indent(l+1) << "}\n"
00528       << indent(l) << "}\n";
00529   }
00530 
00531   return 0;
00532 }
00533 
00534 int main(int argc, const char *argv[]) throw()
00535 {
00536   set_unexpected(Exception::terminal<Archon::X3D::exceptionCatchInfo>);
00537   set_terminate (Exception::terminal<Archon::X3D::exceptionCatchInfo>);
00538 
00539   return autogen(argc, argv);
00540 }

Generated on Sun Jul 30 22:55:46 2006 for Archon by  doxygen 1.4.4