示例#1
0
        Model::EntityDefinition* DefParser::nextDefinition() {
            Token token = m_tokenizer.nextToken();
            while (token.type() != Eof && token.type() != ODefinition)
                token = m_tokenizer.nextToken();
            if (token.type() == Eof)
                return NULL;

            expect(ODefinition, token);
            
            StringList baseClasses;
            ClassInfo classInfo;
            
            token = m_tokenizer.nextToken();
            expect(Word, token);
            classInfo.name = token.data();

            token = m_tokenizer.peekToken();
            expect(OParenthesis | Newline, token);
            if (token.type() == OParenthesis) {
                classInfo.setColor(parseColor());
                
                token = m_tokenizer.peekToken();
                expect(OParenthesis | Question, token);
                if (token.type() == OParenthesis) {
                    classInfo.setSize(parseBounds());
                } else {
                    m_tokenizer.nextToken();
                }
                
                token = m_tokenizer.peekToken();
                if (token.type() == Word) {
                    Model::FlagsPropertyDefinition::Ptr spawnflags = parseFlags();
                    classInfo.properties[spawnflags->name()] = spawnflags;
                }
            }

            expect(Newline, token = m_tokenizer.nextToken());
            parseProperties(classInfo.properties, classInfo.models, baseClasses);
            
            classInfo.setDescription(parseDescription());
            expect(CDefinition, token = m_tokenizer.nextToken());

            Model::EntityDefinition* definition = NULL;
            
            if (classInfo.hasColor) {
                ClassInfo::resolveBaseClasses(m_baseClasses, baseClasses, classInfo);
                if (classInfo.hasSize) { // point definition
                    definition = new Model::PointEntityDefinition(classInfo.name, classInfo.color, classInfo.size, classInfo.description, classInfo.propertyList(), classInfo.models);
                } else {
                    definition = new Model::BrushEntityDefinition(classInfo.name, classInfo.color, classInfo.description, classInfo.propertyList());
                }
            } else { // base definition
                m_baseClasses[classInfo.name] = classInfo;
                definition = nextDefinition();
            }
            
            return definition;
        }
示例#2
0
        void ClassInfo::resolveBaseClasses(const Map& baseClasses, const StringList& classnames, ClassInfo& classInfo) {
            StringList::const_reverse_iterator classnameIt, classnameEnd;
            for (classnameIt = classnames.rbegin(), classnameEnd = classnames.rend(); classnameIt != classnameEnd; ++classnameIt) {
                const String& classname = *classnameIt;
                ClassInfo::Map::const_iterator baseClassIt = baseClasses.find(classname);
                if (baseClassIt != baseClasses.end()) {
                    const ClassInfo& baseClass = baseClassIt->second;
                    if (!classInfo.hasDescription && baseClass.hasDescription)
                        classInfo.setDescription(baseClass.description);
                    if (!classInfo.hasColor && baseClass.hasColor)
                        classInfo.setColor(baseClass.color);
                    if (!classInfo.hasSize && baseClass.hasSize)
                        classInfo.setSize(baseClass.size);
                    
                    Model::PropertyDefinition::Map::const_iterator propertyIt, propertyEnd;
                    for (propertyIt = baseClass.properties.begin(), propertyEnd = baseClass.properties.end(); propertyIt != propertyEnd; ++propertyIt) {
                        const Model::PropertyDefinition::Ptr baseclassProperty = propertyIt->second;

                        Model::PropertyDefinition::Map::iterator classPropertyIt = classInfo.properties.find(baseclassProperty->name());
                        if (classPropertyIt != classInfo.properties.end()) {
                            // the class already has a definition for this property, attempt merging them
                            mergeProperties(baseclassProperty.get(), classPropertyIt->second.get());
                        } else {
                            // the class doesn't have a definition for this property, add the base class property
                            classInfo.properties[baseclassProperty->name()] = baseclassProperty;
                        }
                    }
                    
                    Model::ModelDefinition::List::const_iterator modelIt, modelEnd;
                    for (modelIt = baseClass.models.begin(), modelEnd = baseClass.models.end(); modelIt != modelEnd; ++modelIt) {
                        const Model::ModelDefinition::Ptr model = *modelIt;
                        classInfo.models.push_back(model);
                    }
                }
            }
        }