00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "vrmlNodeType.h"
00016 #include "vrmlNode.h"
00017 #include "vrmlParser.h"
00018 #include "pnotify.h"
00019 #include "indent.h"
00020
00021 #include <stdio.h>
00022
00023
00024
00025
00026
00027 plist<VrmlNodeType*> VrmlNodeType::typeList;
00028
00029 static ostream &
00030 output_array(ostream &out, const MFArray *mf,
00031 int type, int indent_level, int items_per_row) {
00032 if (mf->empty()) {
00033 out << "[ ]";
00034 } else {
00035 out << "[";
00036 MFArray::const_iterator mi;
00037 int col = 0;
00038 for (mi = mf->begin(); mi != mf->end(); ++mi) {
00039 if (col == 0) {
00040 out << "\n";
00041 indent(out, indent_level + 2);
00042 }
00043 output_value(out, (*mi), type, indent_level + 2);
00044 if (++col >= items_per_row) {
00045 col = 0;
00046 } else {
00047 out << " ";
00048 }
00049 }
00050 out << "\n";
00051 indent(out, indent_level) << "]";
00052 }
00053 return out;
00054 }
00055
00056 ostream &
00057 output_value(ostream &out, const VrmlFieldValue &value, int type,
00058 int indent) {
00059 switch (type) {
00060 case SFBOOL:
00061 return out << (value._sfbool ? "TRUE" : "FALSE");
00062
00063 case SFFLOAT:
00064 case SFTIME:
00065 return out << value._sffloat;
00066
00067 case SFINT32:
00068 return out << value._sfint32;
00069
00070 case SFSTRING:
00071 {
00072 out << '"';
00073 for (const char *p = value._sfstring; *p != '\0'; p++) {
00074 if (*p == '"') {
00075 out << "\\\"";
00076 } else {
00077 out << *p;
00078 }
00079 }
00080 return out << '"';
00081 }
00082
00083 case SFVEC2F:
00084 return out << value._sfvec[0] << " " << value._sfvec[1];
00085
00086 case SFCOLOR:
00087 case SFVEC3F:
00088 return out << value._sfvec[0] << " " << value._sfvec[1] << " "
00089 << value._sfvec[2];
00090
00091 case SFROTATION:
00092 return out << value._sfvec[0] << " " << value._sfvec[1] << " "
00093 << value._sfvec[2] << " " << value._sfvec[3];
00094
00095 case SFNODE:
00096 switch (value._sfnode._type) {
00097 case SFNodeRef::T_null:
00098 return out << "NULL";
00099
00100 case SFNodeRef::T_unnamed:
00101 nassertr(value._sfnode._p != NULL, out);
00102 value._sfnode._p->output(out, indent);
00103 return out;
00104
00105 case SFNodeRef::T_def:
00106 out << "DEF " << value._sfnode._name << " ";
00107 value._sfnode._p->output(out, indent);
00108 return out;
00109
00110 case SFNodeRef::T_use:
00111 return out << "USE " << value._sfnode._name;
00112 }
00113 return out << "(invalid)";
00114
00115 case SFIMAGE:
00116 return out << "(image)";
00117
00118 case MFCOLOR:
00119 return output_array(out, value._mf, SFCOLOR, indent, 1);
00120
00121 case MFFLOAT:
00122 return output_array(out, value._mf, SFFLOAT, indent, 5);
00123
00124 case MFINT32:
00125 return output_array(out, value._mf, SFINT32, indent, 10);
00126
00127 case MFROTATION:
00128 return output_array(out, value._mf, SFROTATION, indent, 1);
00129
00130 case MFSTRING:
00131 return output_array(out, value._mf, SFSTRING, indent, 1);
00132
00133 case MFVEC2F:
00134 return output_array(out, value._mf, SFVEC2F, indent, 1);
00135
00136 case MFVEC3F:
00137 return output_array(out, value._mf, SFVEC3F, indent, 1);
00138
00139 case MFNODE:
00140 return output_array(out, value._mf, SFNODE, indent, 1);
00141 }
00142
00143 return out << "(unknown)";
00144 }
00145
00146 VrmlNodeType::VrmlNodeType(const char *nm)
00147 {
00148 nassertv(nm != NULL);
00149 name = strdup(nm);
00150 }
00151
00152 VrmlNodeType::~VrmlNodeType()
00153 {
00154 free(name);
00155
00156
00157 plist<NameTypeRec*>::iterator i;
00158
00159 for (i = eventIns.begin(); i != eventIns.end(); i++) {
00160 NameTypeRec *r = *i;
00161 free(r->name);
00162 delete r;
00163 }
00164 for (i = eventOuts.begin(); i != eventOuts.end(); i++) {
00165 NameTypeRec *r = *i;
00166 free(r->name);
00167 delete r;
00168 }
00169 for (i = fields.begin(); i != fields.end(); i++) {
00170 NameTypeRec *r = *i;
00171 free(r->name);
00172 delete r;
00173 }
00174 }
00175
00176 void
00177 VrmlNodeType::addToNameSpace(VrmlNodeType *_type)
00178 {
00179 if (find(_type->getName()) != NULL) {
00180 cerr << "PROTO " << _type->getName() << " already defined\n";
00181 return;
00182 }
00183 typeList.push_front(_type);
00184 }
00185
00186
00187
00188
00189
00190
00191 void
00192 VrmlNodeType::pushNameSpace()
00193 {
00194 typeList.push_front(NULL);
00195 }
00196
00197 void
00198 VrmlNodeType::popNameSpace()
00199 {
00200
00201 plist<VrmlNodeType*>::iterator i;
00202 for (i = typeList.begin(); i != typeList.end();) {
00203 VrmlNodeType *nodeType = *i;
00204 ++i;
00205 typeList.pop_front();
00206
00207 if (nodeType == NULL) {
00208 break;
00209 }
00210 else {
00211
00212
00213
00214
00215 delete nodeType;
00216 }
00217 }
00218 }
00219
00220 const VrmlNodeType *
00221 VrmlNodeType::find(const char *_name)
00222 {
00223
00224 plist<VrmlNodeType*>::iterator i;
00225 for (i = typeList.begin(); i != typeList.end(); i++) {
00226 const VrmlNodeType *nt = *i;
00227 if (nt != NULL && strcmp(nt->getName(),_name) == 0) {
00228 return nt;
00229 }
00230 }
00231 return NULL;
00232 }
00233
00234 void
00235 VrmlNodeType::addEventIn(const char *name, int type,
00236 const VrmlFieldValue *dflt)
00237 {
00238 add(eventIns, name, type, dflt);
00239 };
00240 void
00241 VrmlNodeType::addEventOut(const char *name, int type,
00242 const VrmlFieldValue *dflt)
00243 {
00244 add(eventOuts, name, type, dflt);
00245 };
00246 void
00247 VrmlNodeType::addField(const char *name, int type,
00248 const VrmlFieldValue *dflt)
00249 {
00250 add(fields, name, type, dflt);
00251 };
00252 void
00253 VrmlNodeType::addExposedField(const char *name, int type,
00254 const VrmlFieldValue *dflt)
00255 {
00256 char tmp[1000];
00257 add(fields, name, type, dflt);
00258 sprintf(tmp, "set_%s", name);
00259 add(eventIns, tmp, type, dflt);
00260 sprintf(tmp, "%s_changed", name);
00261 add(eventOuts, tmp, type, dflt);
00262 };
00263
00264 void
00265 VrmlNodeType::add(plist<NameTypeRec*> &recs, const char *name, int type,
00266 const VrmlFieldValue *dflt)
00267 {
00268 NameTypeRec *r = new NameTypeRec;
00269 r->name = strdup(name);
00270 r->type = type;
00271 if (dflt != NULL) {
00272 r->dflt = *dflt;
00273 } else {
00274 memset(&r->dflt, 0, sizeof(r->dflt));
00275 }
00276 recs.push_front(r);
00277 }
00278
00279 const VrmlNodeType::NameTypeRec *
00280 VrmlNodeType::hasEventIn(const char *name) const
00281 {
00282 return has(eventIns, name);
00283 }
00284
00285 const VrmlNodeType::NameTypeRec *
00286 VrmlNodeType::hasEventOut(const char *name) const
00287 {
00288 return has(eventOuts, name);
00289 }
00290
00291 const VrmlNodeType::NameTypeRec *
00292 VrmlNodeType::hasField(const char *name) const
00293 {
00294 return has(fields, name);
00295 }
00296
00297 const VrmlNodeType::NameTypeRec *
00298 VrmlNodeType::hasExposedField(const char *name) const
00299 {
00300
00301
00302 char tmp[1000];
00303 const NameTypeRec *base, *set_name, *name_changed;
00304
00305 base = has(fields, name);
00306
00307 sprintf(tmp, "set_%s\n", name);
00308 nassertr(strlen(tmp) < 1000, NULL);
00309 set_name = has(eventIns, tmp);
00310
00311 sprintf(tmp, "%s_changed\n", name);
00312 nassertr(strlen(tmp) < 1000, NULL);
00313 name_changed = has(eventOuts, tmp);
00314
00315 if (base == NULL || set_name == NULL || name_changed == NULL) {
00316 return NULL;
00317 }
00318
00319 if (base->type != set_name->type || base->type != name_changed->type) {
00320 return NULL;
00321 }
00322
00323 return base;
00324 }
00325
00326 const VrmlNodeType::NameTypeRec *
00327 VrmlNodeType::has(const plist<NameTypeRec*> &recs, const char *name) const
00328 {
00329 plist<NameTypeRec*>::const_iterator i;
00330 for (i = recs.begin(); i != recs.end(); i++) {
00331 if (strcmp((*i)->name, name) == 0)
00332 return (*i);
00333 }
00334 return NULL;
00335 }
00336