DOM code generator

From COLLADA Public Wiki
Revision as of 21:08, 23 March 2007 by Elf (talk | contribs) (copy in Andy's text from word doc)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

COLLADA Code Generator

dom generated types

The DOM has it’s basic types defined in daeTypes.h . There are mappings from XML Schema basic types to DOM types in daeDomTypes.h

Any other new types defined in the schema document generate new atomic types or add name bindings to existing atomic types in the DOM.

All types defined in the schema are either restrictions, extensions, unions, or lists of existing types.

The dom generates types in domTypes.h

The format is “typedef base_type_name domNew_type_name” for most type declarations.

“typedef daeTArray< base_type_name > domNew_type_name” is used for list types.

Enum types take the form of “enum domNew_type_name”. Each enum value is then created as “NEW_TYPE_NAME_Enum”.

Union types are only supported for unions of enums. A new enum is generated for that union type containing the symbols and values of all enums contained in the union.

These types are registered in the registerDomTypes function found in domTypes.cpp. For all types except enums code is generated that looks like type = daeAtomicType::get("base_type_name"); if ( type == NULL ) { //register as a raw type type = new daeRawRefType; type->_nameBindings.append("new_type_name"); daeAtomicType::append( type ); } else { //add binding to existing type type->_nameBindings.append("new_type_name "); } This code searches for a type for the base_type_name. If it finds one it adds new_type_name as a name binding for that type. If the base type does not exist then a new rawRefType is created.

Enums always get a new type generated. The two arrays _strings and _values get populated with the enum values.

In the schema, if an enumeration has an <xs:annotation> with an <xs:appinfo> value=value the enum created will have a value value.

dom generated classes

Interface

Each <xs:element> <xs:group> and <xs:complexType> generates a new daeElement subclass name domElement_name.

Each attribute and child element and a value (if it has one) gets its data storage and accessor and mutators. Array types and URIs get returned by reference. All other types are returned by value.

If an element has an xs:choice content model group and more than a single child element it will have a _contents, _contentsOrder, and _CMData arrays to store the data needed to represent the ordering of children in the content model.

An xs:complexType generates two classes. The first is the class description/interface. The second is a daeElement subclass that inherits from both daeElement and the new class interface.

Any class defined in XMLSchema global scope (not defined as a child of another element) generates a new daeElement subclass. This new element, if the type attribute is a complex type, also inherits from the complex type interface and daeElement.

An element that is part of a substitution group inherits from the element it is substitutable for. Then the DOM uses polymorphism and stores a pointer to the base class which could be an object of any of the substitutable classes.

The code generator does allow for schema type inheritance by either extension or restriction. In either case the new class inherits from the base class. Restriction is handled with the DOM meta information since C++ can only do inheritance by extension. The current (COLLADA 1.4.1) schema does not take advantage of this feature.

The code generator allows for scoped type definitions. This would happen when a simple type is created anonymously in the schema document instead of creating a global simple type and referencing it. The current (COLLADA 1.4.1) schema does not take advantage of this feature.

When generating mutators for string data attributes or values, the generator creates code *(daeStringRef*)&attrAttribute_name = atAttribute_name that lets the DOM create memory to store it’s string data.

The xmlns attribute is specially created only for elements that have an <xs:annotation> <xs:appinfo> that contains “enable-xmlns”

Meta generation

Each element that gets generated has a function registerElement. RegisterElement is the function that gets called to create the meta information that describes the new element.

Every element’s _Meta descriptor has a name and a pointer to the element’s creation function create(daeInt bytes).

If the new element is created from an <xs:group> then the meta will be tagged as transparent. Transparent means that the IOplugin will not create an XML tag or any attributes for this element when it gets saved out. Essentially, the transparent flag means that the element exists in the COLLADA DOM content but doesn’t really exist in the XML content.

If the new element is abstract the abstract flag is set for the meta. Abstract element’s cannot be placed in the DOM.

If the element is not declared in the schema’s global scope then the isInnerClass flag is set to true. This flag is used by the metaAny content model group. Any globally declared elements can be created as part of the “any” content model but not scoped inner classes. Any other children of an “any” group become the weakly typed domAny elements.

Each attribute has a new metaAttribute or metaArrayAttribute created to describe it. This metaAttribute is given a name, a type, and the pointer offset into the class where the data can be found.

The value is treated the same as a normal attribute.

If the attribute is marked required or given a default value that is also set on the metaAttribute.

The metaCMPolicy object tree is generated to match the content model specified in the schema. Only the xs:any content model group is not supported.

Any content model that contains a choice and more than one child element or an element that is the base for a substitution group will have a _contents and _contentsOrder metaAttributes added.

If the element’s content model contains an xs:choice group then the meta will have a _CMData metaAttribute created.

code generator program flow & systems

The codegenerator is run by starting gen.php with a php interpreter. The gen.php requires at least one argument which is the schema to use for code generation.

The generator, by default, creates the full integration classes. Pass an argument (after the schema) min to generate the minimal integration classes.

The generator, by default, puts the SCEA SNIP copyright as the header of all of the files. Pass an argument cprt for the generator to use the SCEA Shared Source License copyright as the header. This is the way the generated classes should be created.

The generator starts by parsing the schema document and creating it’s own DOM like structure to store the info from the schema.

For each schema element that might be encountered there needs to be a source file xsElementName.php . This class is used to store the data related to that element. The source file needs to be included (require_once in PHP) in the object-model.php file.

Each of the object model classes has a constructor that registers what element’s and attributes (along with their min and maxOccurs) are valid for that element.

The SchemaParser class uses the default PHP SAX XML parser to parse the schema document and create the custom DOM used for code generation.

The generator then gets all elements that are xs:simpleType and calls generate on them. Generate creates a TypeMeta object that contains the data needed to generate the COLLADA simple types.

Then the generator does the same for xs:complexType, xs:group, and xs:element.

The template-engine source file contains the logic on how to apply a template. Templates take the form of two source files. One usually suffixed with –file contains the logic on creating a new c++ source or header file and then applying another template to actually write the code.

The most significant templates are tpl-types-header.php for generated type definitions, tpl-types-cpp.php for type registration, tpl-class-def.php for generated class interfaces, and tpl-cpp-methods for the generation of the meta for each class.