1#ifndef DynamicNodeKit_H
2#define DynamicNodeKit_H
4#include <Inventor/nodekits/SoBaseKit.h>
5#include <Inventor/nodekits/SoSubKit.h>
7#include <Inventor/fields/SoFieldData.h>
8#include <Inventor/nodekits/SoNodekitCatalog.h>
10#include <Inventor/C/XML/parser.h>
11#include <Inventor/C/XML/document.h>
12#include <Inventor/C/XML/element.h>
13#include <Inventor/C/XML/attribute.h>
16class SoNodekitCatalog;
28 static SoType getClassTypeId(
void);
29 virtual SoType getTypeId(
void)
const;
30 static const SoNodekitCatalog * getClassNodekitCatalog(
void);
31 virtual const SoNodekitCatalog * getNodekitCatalog(
void)
const;
33 static const SoFieldData ** getFieldDataPtr(
void);
34 virtual const SoFieldData * getFieldData(
void)
const;
35 static const SoNodekitCatalog ** getClassNodekitCatalogPtr(
void);
37 static SoType classTypeId;
38 static void atexit_cleanup(
void);
39 static const SoFieldData ** parentFieldData;
40 static SoFieldData * fieldData;
41 static unsigned int classinstances;
42 static void * createInstance(
void);
43 static SoNodekitCatalog * classcatalog;
44 static const SoNodekitCatalog ** parentcatalogptr;
45 static void atexit_cleanupkit(
void);
52 static void initClass(
void);
53 virtual void copyContents(
const SoFieldContainer * from, SbBool copyconn);
56 bool addField(SbString name, SbString typeString, SbString defaultValue);
57 bool addPart(SbString name, SbString typeString, SbBool isDefaultNull, SbString parentName, SbString rightSiblingName, SbBool isPublic);
58 bool setNodekitDescription(SbString xmlDescription);
62 virtual SoNode * getAnyPart(
const SbName & partname, SbBool makeifneeded, SbBool leafcheck = 0, SbBool publiccheck = 0);
63 virtual SbBool setAnyPart(
const SbName & partname,
SoNode * from, SbBool anypart = 1);
69 SoNodekitCatalog * dynamicCatalog;
70 SoFieldData * dynamicFieldData;
71 bool addPartsFromXml(cc_xml_elt * element,
const char * parentName,
const char * rightSiblingName);
83#ifndef DYNAMIC_NODEKIT_NO_GENERATE_FUNCTIONS
93const SoNodekitCatalog *
101const SoNodekitCatalog **
168 return dynamicFieldData;
174const SoNodekitCatalog *
177 return this->dynamicCatalog;
186 SoType parentType = Base::getClassTypeId();
187 SbName parentName = parentType.getName();
190 SbString classNameString =
"Dynamic";
191 classNameString += parentName;
193 const char * classname = classNameString.getString();
197 SoType::createType(parentType,
200 SoNode::getNextActionMethodIndex());
201 SoNode::incNextActionMethodIndex();
218 this->dynamicFieldData =
new SoFieldData;
219 this->dynamicFieldData->copy(inherited::getFieldData());
222 this->staticPartCount = dynamicCatalog->getNumEntries();
224 this->finished =
false;
225 this->isEditing =
false;
233 const int n = this->dynamicFieldData->getNumFields();
234 for (
int i = 0; i < n; i++) {
235 SoField * f = this->dynamicFieldData->getField(
this, i);
236 if ((*this->getFieldDataPtr())->getIndex(
this, f) == -1) {
240 delete this->dynamicFieldData;
241 delete this->dynamicCatalog;
252 const SoFieldData * src = from->getFieldData();
253 const int n = src->getNumFields();
254 for (
int i = 0; i < n; i++) {
255 const SoField * f = src->getField(from, i);
256 if (this->dynamicFieldData->getIndex(
this, f) == -1) {
257 SoField * cp = (SoField*) f->getTypeId().createInstance();
258 cp->setFieldType(f->getFieldType());
259 cp->setContainer(
this);
260 this->dynamicFieldData->addField(
this, src->getFieldName(i), cp);
264 inherited::copyContents(from, copyconn);
272 if (!this->isEditing){
276 SoType type = SoType::fromName(typeString);
277 SoField * f =
static_cast<SoField *
>(type.createInstance());
278 f->setContainer(
this);
279 if (defaultValue !=
"") f->set(defaultValue.getString());
280 this->dynamicFieldData->addField(
this, name.getString(), f);
287DynamicNodeKit<Base>::addPart(SbString name, SbString typeString, SbBool isDefaultNull, SbString parentName, SbString rightSiblingName, SbBool isPublic)
289 if (!this->isEditing){
293 SoType type = SoType::fromName(typeString);
294 this->dynamicCatalog->addEntry(name, type, type, isDefaultNull, parentName, rightSiblingName, FALSE, SoType::badType(), SoType::badType(), isPublic);
296 SoSFNode * f =
new SoSFNode;
297 f->setContainer(
this);
299 this->dynamicFieldData->addField(
this, name.getString(), f);
312 this->isEditing =
true;
321 if (!this->isEditing || this->finished){
325 this->createFieldList();
326 this->createDefaultParts();
328 this->isEditing =
false;
329 this->finished =
true;
338 if (this->finished || this->isEditing){
342 cc_xml_document * xmldoc = cc_xml_read_buffer(xmlDescription.getString());
344 cc_xml_element * root = cc_xml_doc_get_root(xmldoc);
345 if (strcmp(cc_xml_elt_get_type(root),
"DynamicNodeKitDescription")){
349 this->startEditing();
351 int numFields = cc_xml_elt_get_num_children_of_type(root,
"Field");
352 for (
int i = 0; i < numFields; i++){
353 cc_xml_element * fieldElement = cc_xml_elt_get_child_of_type(root,
"Field", i);
354 const char * name = cc_xml_attr_get_value(cc_xml_elt_get_attribute(fieldElement,
"name"));
355 const char * type = cc_xml_attr_get_value(cc_xml_elt_get_attribute(fieldElement,
"type"));
356 const char * value = cc_xml_elt_get_cdata(fieldElement);
357 this->addField(name, type, value);
360 this->addPartsFromXml(root,
"this",
"");
361 this->finishEditing();
363 cc_xml_doc_delete_x(xmldoc);
372 const char * name = parentName;
373 if (!strcmp(cc_xml_elt_get_type(element),
"Part")){
374 name = cc_xml_attr_get_value(cc_xml_elt_get_attribute(element,
"name"));
375 const char * type = cc_xml_attr_get_value(cc_xml_elt_get_attribute(element,
"type"));
376 cc_xml_attribute * isDefaultNullAttr = cc_xml_elt_get_attribute(element,
"isNullByDefault");
377 const char * isDefaultNull = isDefaultNullAttr ? cc_xml_attr_get_value(isDefaultNullAttr) :
"false";
378 cc_xml_attribute * isPublicAttr = cc_xml_elt_get_attribute(element,
"isPublic");
379 const char * isPublic = isPublicAttr ? cc_xml_attr_get_value(isPublicAttr) :
"false";
380 this->addPart(name, type, strcmp(isDefaultNull,
"false"), parentName, rightSiblingName, strcmp(isPublic,
"false"));
383 int numChildren = cc_xml_elt_get_num_children_of_type(element,
"Part");
384 for (
int i = 0; i < numChildren; i++){
385 cc_xml_element * partElement = cc_xml_elt_get_child_of_type(element,
"Part", i);
386 const char * nextSiblingName =
"";
387 if (i < numChildren - 1){
388 cc_xml_element * siblingElement = cc_xml_elt_get_child_of_type(element,
"Part", i + 1);
389 nextSiblingName = cc_xml_attr_get_value(cc_xml_elt_get_attribute(siblingElement,
"name"));
391 this->addPartsFromXml(partElement, name, nextSiblingName);
402 return inherited::getAnyPart(partname, makeifneeded, leafcheck, publiccheck);
410 return inherited::setAnyPart(partname, from, anypart);
Definition DynamicNodeKit.h:21