diff --git a/VkCppGenerator.cpp b/VkCppGenerator.cpp index ba3dbe4..70c26c5 100644 --- a/VkCppGenerator.cpp +++ b/VkCppGenerator.cpp @@ -249,15 +249,44 @@ struct MemberData bool optional; }; -struct StructData +struct CommandData { - StructData() - : returnedOnly(false) + CommandData() + : handleCommand(false) + , twoStep(false) {} - bool returnedOnly; - std::vector members; - std::string protect; + std::string returnType; + std::vector arguments; + std::vector successCodes; + std::string protect; + bool handleCommand; + bool twoStep; +}; + +struct DependencyData +{ + enum class Category + { + COMMAND, + ENUM, + FLAGS, + FUNC_POINTER, + HANDLE, + REQUIRED, + SCALAR, + STRUCT, + UNION + }; + + DependencyData(Category c, std::string const& n) + : category(c) + , name(n) + {} + + Category category; + std::string name; + std::set dependencies; }; struct NameValue @@ -277,19 +306,9 @@ struct EnumData void addEnum(std::string const & name, std::string const& tag); }; -struct CommandData +struct FlagData { - CommandData() - : handleCommand(false) - , twoStep(false) - {} - - std::string returnType; - std::vector arguments; - std::vector successCodes; - std::string protect; - bool handleCommand; - bool twoStep; + std::string protect; }; struct HandleData @@ -297,42 +316,39 @@ struct HandleData std::vector commands; }; -struct FlagData -{ - std::string protect; -}; - struct ScalarData { std::string protect; }; -struct DependencyData +struct StructData { - enum class Category - { - COMMAND, - ENUM, - FLAGS, - FUNC_POINTER, - HANDLE, - REQUIRED, - SCALAR, - STRUCT, - UNION - }; - - DependencyData( Category c, std::string const& n ) - : category(c) - , name(n) + StructData() + : returnedOnly(false) {} - Category category; - std::string name; - std::set dependencies; + bool returnedOnly; + std::vector members; + std::string protect; }; -void createDefaults( std::vector const& dependencies, std::map const& enums, std::map & defaultValues ); +struct VkData +{ + std::map commands; + std::list dependencies; + std::map enums; + std::map flags; + std::map handles; + std::map scalars; + std::map structs; + std::set tags; + std::string typesafeCheck; + std::string version; + std::set vkTypes; + std::string vulkanLicenseHeader; +}; + +void createDefaults( VkData const& vkData, std::map & defaultValues ); std::string determineFunctionName(std::string const& name, CommandData const& commandData); std::string determineReturnType(CommandData const& commandData, size_t returnIndex, bool isVector = false); void enterProtect(std::ofstream &ofs, std::string const& protect); @@ -347,33 +363,34 @@ bool isVectorSizeParameter(std::map const& vectorParameters, siz void leaveProtect(std::ofstream &ofs, std::string const& protect); bool noDependencies(std::set const& dependencies, std::map & listedTypes); bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData, std::vector & arguments ); -std::map::iterator readCommandProto(tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands); -void readCommands( tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands, std::map & handles, std::set const& tags ); -void readCommandsCommand(tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands, std::map & handles, std::set const& tags); +std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData); +void readCommands( tinyxml2::XMLElement * element, VkData & vkData ); +void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData); void readComment(tinyxml2::XMLElement * element, std::string & header); -void readEnums( tinyxml2::XMLElement * element, std::list & dependencies, std::map & enums, std::set const& tags, std::set & vkTypes ); +void readEnums( tinyxml2::XMLElement * element, VkData & vkData ); void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::string const& tag ); -void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& protect, std::string const& tag, std::map & commands, std::map & enums, std::map & flags, std::map & scalars, std::map & structs); -void readExtensions( tinyxml2::XMLElement * element, std::map & commands, std::map & enums, std::map & flags, std::map & scalars, std::map & structs, std::set const& tags ); -void readExtensionsExtension(tinyxml2::XMLElement * element, std::map & commands, std::map & enums, std::map & flags, std::map & scalars, std::map & structs, std::set const& tags); +void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag); +void readExtensions( tinyxml2::XMLElement * element, VkData & vkData ); +void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData); void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ); -void readTypeBitmask( tinyxml2::XMLElement * element, std::list & dependencies, std::map & flags, std::map & scalars, std::set & vkTypes, std::map & enums ); -void readTypeDefine( tinyxml2::XMLElement * element, std::string & version, std::string & typesafeCheck ); +void readTypeBitmask( tinyxml2::XMLElement * element, VkData & vkData); +void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ); void readTypeFuncpointer( tinyxml2::XMLElement * element, std::list & dependencies ); -void readTypeHandle(tinyxml2::XMLElement * element, std::list & dependencies, std::set & vkTypes, std::map & handles); -void readTypeStruct( tinyxml2::XMLElement * element, std::list & dependencies, std::map & structs, std::set & vkTypes ); +void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData); +void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ); void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); -void readTypeUnion( tinyxml2::XMLElement * element, std::list & dependencies, std::map & structs, std::set & vkTypes ); +void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ); void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ); void readTags(tinyxml2::XMLElement * element, std::set & tags); -void readTypes(tinyxml2::XMLElement * element, std::string & version, std::string & typesafeCheck, std::list & dependencies, std::map & flags, std::map & scalars, std::map & structs, std::set & vkTypes, std::map & handles, std::map & enums); -void sortDependencies( std::list & dependencies, std::vector & sortedDependencies ); +void readTypes(tinyxml2::XMLElement * element, VkData & vkData); +void sortDependencies( std::list & dependencies ); std::string reduceName(std::string const& name); std::string strip(std::string const& value, std::string const& prefix, std::string const& tag = std::string()); std::string stripCommand(std::string const& value); std::string toCamelCase(std::string const& value); std::string toUpperCase(std::string const& name); void writeCall(std::ofstream & ofs, std::string const& name, size_t templateIndex, CommandData const& commandData, std::set const& vkTypes, std::map const& vectorParameters, size_t returnIndex, bool firstCall); +void writeEnumsToString(std::ofstream & ofs, VkData const& vkData); void writeExceptionCheck(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::vector const& successCodes); void writeFunctionBody(std::ofstream & ofs, std::string const& indentation, std::string const& className, std::string const& functionName, std::string const& returnType, size_t templateIndex, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes, size_t returnIndex, std::map const& vectorParameters); void writeFunctionHeader(std::ofstream & ofs, std::string const& indentation, std::string const& returnType, std::string const& name, CommandData const& commandData, size_t returnIndex, size_t templateIndex, std::map const& vectorParameters); @@ -386,11 +403,11 @@ void writeTypeCommandEnhanced(std::ofstream & ofs, std::string const& indentatio void writeTypeCommandStandard(std::ofstream & ofs, std::string const& indentation, std::string const& functionName, DependencyData const& dependencyData, CommandData const& commandData, std::set const& vkTypes); void writeTypeEnum(std::ofstream & ofs, DependencyData const& dependencyData, EnumData const& enumData); void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, FlagData const& flagData ); -void writeTypeHandle(std::ofstream & ofs, DependencyData const& dependencyData, HandleData const& handle, std::map const& commands, std::vector const& dependencies, std::set const& vkTypes); +void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies); void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ); -void writeTypeStruct( std::ofstream & ofs, DependencyData const& dependencyData, std::set const& vkTypes, std::map const& structs, std::map const& defaultValues ); -void writeTypeUnion( std::ofstream & ofs, DependencyData const& dependencyData, StructData const& unionData, std::set const& vkTypes, std::map const& structs, std::map const& defaultValues ); -void writeTypes(std::ofstream & ofs, std::vector const& dependencies, std::map const& commands, std::map const& enums, std::map const& flags, std::map const& handles, std::map const& structs, std::map const& defaultValues, std::set const& vkTypes); +void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ); +void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ); +void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues); void writeVersionCheck(std::ofstream & ofs, std::string const& version); void writeTypesafeCheck(std::ofstream & ofs, std::string const& typesafeCheck); @@ -414,9 +431,9 @@ void EnumData::addEnum(std::string const & name, std::string const& tag) } } -void createDefaults( std::vector const& dependencies, std::map const& enums, std::map & defaultValues ) +void createDefaults( VkData const& vkData, std::map & defaultValues ) { - for ( std::vector::const_iterator it = dependencies.begin() ; it != dependencies.end() ; ++it ) + for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) { assert( defaultValues.find( it->name ) == defaultValues.end() ); switch( it->category ) @@ -425,11 +442,11 @@ void createDefaults( std::vector const& dependencies, std::mapname) != enums.end()); - EnumData const & enumData = enums.find(it->name)->second; + assert(vkData.enums.find(it->name) != vkData.enums.end()); + EnumData const & enumData = vkData.enums.find(it->name)->second; if (!enumData.members.empty()) { - defaultValues[it->name] = it->name + "::" + enums.find(it->name)->second.members.front().name; + defaultValues[it->name] = it->name + "::" + vkData.enums.find(it->name)->second.members.front().name; } else { @@ -754,7 +771,7 @@ bool readCommandParam( tinyxml2::XMLElement * element, DependencyData & typeData return element->Attribute("optional") && (strcmp(element->Attribute("optional"), "false,true") == 0); } -std::map::iterator readCommandProto(tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands) +std::map::iterator readCommandProto(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * typeElement = element->FirstChildElement(); assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) ); @@ -765,31 +782,31 @@ std::map::iterator readCommandProto(tinyxml2::XMLEleme std::string type = strip( typeElement->GetText(), "Vk" ); std::string name = stripCommand( nameElement->GetText() ); - dependencies.push_back( DependencyData( DependencyData::Category::COMMAND, name ) ); - assert( commands.find( name ) == commands.end() ); - std::map::iterator it = commands.insert( std::make_pair( name, CommandData() ) ).first; + vkData.dependencies.push_back( DependencyData( DependencyData::Category::COMMAND, name ) ); + assert( vkData.commands.find( name ) == vkData.commands.end() ); + std::map::iterator it = vkData.commands.insert( std::make_pair( name, CommandData() ) ).first; it->second.returnType = type; return it; } -void readCommands(tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands, std::map & handles, std::set const& tags) +void readCommands(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * child = element->FirstChildElement(); assert( child ); do { assert( strcmp( child->Value(), "command" ) == 0 ); - readCommandsCommand( child, dependencies, commands, handles, tags ); + readCommandsCommand( child, vkData ); } while ( child = child->NextSiblingElement() ); } -void readCommandsCommand(tinyxml2::XMLElement * element, std::list & dependencies, std::map & commands, std::map & handles, std::set const& tags) +void readCommandsCommand(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * child = element->FirstChildElement(); assert( child && ( strcmp( child->Value(), "proto" ) == 0 ) ); - std::map::iterator it = readCommandProto(child, dependencies, commands); + std::map::iterator it = readCommandProto(child, vkData); if (element->Attribute("successcodes")) { @@ -799,7 +816,7 @@ void readCommandsCommand(tinyxml2::XMLElement * element, std::listsecond.successCodes.push_back("e" + toCamelCase(strip(code, "VK_", tag)) + tag); start = end + 1; } while (end != std::string::npos); @@ -817,7 +834,7 @@ void readCommandsCommand(tinyxml2::XMLElement * element, std::listValue(); if ( value == "param" ) { - it->second.twoStep |= readCommandParam(child, dependencies.back(), it->second.arguments); + it->second.twoStep |= readCommandParam(child, vkData.dependencies.back(), it->second.arguments); } else { @@ -832,13 +849,13 @@ void readCommandsCommand(tinyxml2::XMLElement * element, std::listsecond.arguments.empty()); - std::map::iterator hit = handles.find(it->second.arguments[0].pureType); - if (hit != handles.end()) + std::map::iterator hit = vkData.handles.find(it->second.arguments[0].pureType); + if (hit != vkData.handles.end()) { hit->second.commands.push_back(it->first); it->second.handleCommand = true; - DependencyData const& dep = dependencies.back(); - std::list::iterator dit = std::find_if(dependencies.begin(), dependencies.end(), [hit](DependencyData const& dd) { return dd.name == hit->first; }); + DependencyData const& dep = vkData.dependencies.back(); + std::list::iterator dit = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [hit](DependencyData const& dd) { return dd.name == hit->first; }); for (std::set::const_iterator depit = dep.dependencies.begin(); depit != dep.dependencies.end(); ++depit) { if (*depit != hit->first) @@ -868,14 +885,14 @@ void readComment(tinyxml2::XMLElement * element, std::string & header) header += "\n\n// This header is generated from the Khronos Vulkan XML API Registry."; } -void readEnums( tinyxml2::XMLElement * element, std::list & dependencies, std::map & enums, std::set const& tags, std::set & vkTypes ) +void readEnums( tinyxml2::XMLElement * element, VkData & vkData ) { assert( element->Attribute( "name" ) ); std::string name = getEnumName(element->Attribute("name")); if ( name != "API Constants" ) { - dependencies.push_back( DependencyData( DependencyData::Category::ENUM, name ) ); - std::map::iterator it = enums.insert( std::make_pair( name, EnumData() ) ).first; + vkData.dependencies.push_back( DependencyData( DependencyData::Category::ENUM, name ) ); + std::map::iterator it = vkData.enums.insert( std::make_pair( name, EnumData() ) ).first; std::string tag; if (name == "Result") @@ -903,7 +920,7 @@ void readEnums( tinyxml2::XMLElement * element, std::list & depe } // if the enum name contains a tag remove it from the prefix to generate correct enum value names. - for (std::set::const_iterator tit = tags.begin(); tit != tags.end(); ++tit) + for (std::set::const_iterator tit = vkData.tags.begin(); tit != vkData.tags.end(); ++tit) { size_t pos = it->second.prefix.find(*tit); if ((pos != std::string::npos) && (pos == it->second.prefix.length() - tit->length() - 1)) @@ -917,8 +934,8 @@ void readEnums( tinyxml2::XMLElement * element, std::list & depe readEnumsEnum( element, it->second, tag ); - assert( vkTypes.find( name ) == vkTypes.end() ); - vkTypes.insert( name ); + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); } } @@ -934,7 +951,7 @@ void readEnumsEnum( tinyxml2::XMLElement * element, EnumData & enumData, std::st } while ( child = child->NextSiblingElement() ); } -void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& protect, std::string const& tag, std::map & commands, std::map & enums, std::map & flags, std::map & scalars, std::map & structs) +void readExtensionRequire(tinyxml2::XMLElement * element, VkData & vkData, std::string const& protect, std::string const& tag) { tinyxml2::XMLElement * child = element->FirstChildElement(); do @@ -945,29 +962,29 @@ void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& pro if ( value == "command" ) { std::string name = stripCommand(child->Attribute("name")); - std::map::iterator cit = commands.find(name); - assert(cit != commands.end()); + std::map::iterator cit = vkData.commands.find(name); + assert(cit != vkData.commands.end()); cit->second.protect = protect; } else if (value == "type") { std::string name = strip(child->Attribute("name"), "Vk"); - std::map::iterator eit = enums.find(name); - if (eit != enums.end()) + std::map::iterator eit = vkData.enums.find(name); + if (eit != vkData.enums.end()) { eit->second.protect = protect; } else { - std::map::iterator fit = flags.find(name); - if (fit != flags.end()) + std::map::iterator fit = vkData.flags.find(name); + if (fit != vkData.flags.end()) { fit->second.protect = protect; // if the enum of this flags is auto-generated, protect it as well std::string enumName = generateEnumNameForFlags(name); - std::map::iterator eit = enums.find(enumName); - assert(eit != enums.end()); + std::map::iterator eit = vkData.enums.find(enumName); + assert(eit != vkData.enums.end()); if (eit->second.members.empty()) { eit->second.protect = protect; @@ -975,15 +992,15 @@ void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& pro } else { - std::map::iterator scit = scalars.find(name); - if (scit != scalars.end()) + std::map::iterator scit = vkData.scalars.find(name); + if (scit != vkData.scalars.end()) { scit->second.protect = protect; } else { - std::map::iterator stit = structs.find(name); - assert(stit != structs.end() && stit->second.protect.empty()); + std::map::iterator stit = vkData.structs.find(name); + assert(stit != vkData.structs.end() && stit->second.protect.empty()); stit->second.protect = protect; } } @@ -994,9 +1011,9 @@ void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& pro // TODO process enums which don't extend existing enums if (child->Attribute("extends")) { - assert(enums.find(getEnumName(child->Attribute("extends"))) != enums.end()); + assert(vkData.enums.find(getEnumName(child->Attribute("extends"))) != vkData.enums.end()); assert(!!child->Attribute("offset") ^ !!child->Attribute("value")); // either offset or value has to be defined; no both of them! - enums[getEnumName(child->Attribute("extends"))].addEnum(child->Attribute("name"), child->Attribute("offset") ? tag : "" ); + vkData.enums[getEnumName(child->Attribute("extends"))].addEnum(child->Attribute("name"), child->Attribute("offset") ? tag : "" ); } } else @@ -1006,22 +1023,22 @@ void readExtensionRequire(tinyxml2::XMLElement * element, std::string const& pro } while ( child = child->NextSiblingElement() ); } -void readExtensions(tinyxml2::XMLElement * element, std::map & commands, std::map &enums, std::map & flags, std::map & scalars, std::map & structs, std::set const& tags) +void readExtensions(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * child = element->FirstChildElement(); assert( child ); do { assert( strcmp( child->Value(), "extension" ) == 0 ); - readExtensionsExtension( child, commands, enums, flags, scalars, structs, tags ); + readExtensionsExtension( child, vkData ); } while ( child = child->NextSiblingElement() ); } -void readExtensionsExtension(tinyxml2::XMLElement * element, std::map & commands, std::map & enums, std::map & flags, std::map & scalars, std::map & structs, std::set const& tags) +void readExtensionsExtension(tinyxml2::XMLElement * element, VkData & vkData) { assert( element->Attribute( "name" ) ); std::string tag = extractTag(element->Attribute("name")); - assert(tags.find(tag) != tags.end()); + assert(vkData.tags.find(tag) != vkData.tags.end()); // don't parse disabled extensions if (strcmp(element->Attribute("supported"), "disabled") == 0) @@ -1037,7 +1054,7 @@ void readExtensionsExtension(tinyxml2::XMLElement * element, std::mapFirstChildElement(); assert( child && ( strcmp( child->Value(), "require" ) == 0 ) && !child->NextSiblingElement() ); - readExtensionRequire( child, protect, tag, commands, enums, flags, scalars, structs ); + readExtensionRequire( child, vkData, protect, tag ); } void readTypeBasetype( tinyxml2::XMLElement * element, std::list & dependencies ) @@ -1063,7 +1080,7 @@ void readTypeBasetype( tinyxml2::XMLElement * element, std::list } } -void readTypeBitmask(tinyxml2::XMLElement * element, std::list & dependencies, std::map & flags, std::map & scalars, std::set & vkTypes, std::map & enums) +void readTypeBitmask(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * typeElement = element->FirstChildElement(); assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() && ( strcmp( typeElement->GetText(), "VkFlags" ) == 0 ) ); @@ -1083,33 +1100,33 @@ void readTypeBitmask(tinyxml2::XMLElement * element, std::list & else { // Generate FlagBits name requires = generateEnumNameForFlags(name); - dependencies.push_back(DependencyData(DependencyData::Category::ENUM, requires)); - std::map::iterator it = enums.insert(std::make_pair(requires, EnumData())).first; + vkData.dependencies.push_back(DependencyData(DependencyData::Category::ENUM, requires)); + std::map::iterator it = vkData.enums.insert(std::make_pair(requires, EnumData())).first; it->second.bitmask = true; - vkTypes.insert(requires); + vkData.vkTypes.insert(requires); } - dependencies.push_back( DependencyData( DependencyData::Category::FLAGS, name ) ); - dependencies.back().dependencies.insert( requires ); - flags.insert(std::make_pair(name, FlagData())); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::FLAGS, name ) ); + vkData.dependencies.back().dependencies.insert( requires ); + vkData.flags.insert(std::make_pair(name, FlagData())); - assert( vkTypes.find( name ) == vkTypes.end() ); - vkTypes.insert( name ); + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); } -void readTypeDefine( tinyxml2::XMLElement * element, std::string & version, std::string & typedefCheck ) +void readTypeDefine( tinyxml2::XMLElement * element, VkData & vkData ) { tinyxml2::XMLElement * child = element->FirstChildElement(); if (child && (strcmp(child->GetText(), "VK_API_VERSION") == 0)) { - version = element->LastChild()->ToText()->Value(); + vkData.version = element->LastChild()->ToText()->Value(); } else if (element->Attribute("name") && strcmp(element->Attribute("name"), "VK_DEFINE_NON_DISPATCHABLE_HANDLE") == 0) { std::string text = element->LastChild()->ToText()->Value(); size_t start = text.find('#'); size_t end = text.find_first_of("\r\n", start + 1); - typedefCheck = text.substr(start, end - start); + vkData.typesafeCheck = text.substr(start, end - start); } } @@ -1120,7 +1137,7 @@ void readTypeFuncpointer( tinyxml2::XMLElement * element, std::listGetText() ) ); } -void readTypeHandle(tinyxml2::XMLElement * element, std::list & dependencies, std::set & vkTypes, std::map & handles) +void readTypeHandle(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * typeElement = element->FirstChildElement(); assert( typeElement && ( strcmp( typeElement->Value(), "type" ) == 0 ) && typeElement->GetText() ); @@ -1133,12 +1150,12 @@ void readTypeHandle(tinyxml2::XMLElement * element, std::list & assert( nameElement && ( strcmp( nameElement->Value(), "name" ) == 0 ) && nameElement->GetText() ); std::string name = strip( nameElement->GetText(), "Vk" ); - dependencies.push_back( DependencyData( DependencyData::Category::HANDLE, name ) ); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::HANDLE, name ) ); - assert(vkTypes.find(name) == vkTypes.end()); - vkTypes.insert(name); - assert(handles.find(name) == handles.end()); - handles[name]; // add this to the handles map + assert(vkData.vkTypes.find(name) == vkData.vkTypes.end()); + vkData.vkTypes.insert(name); + assert(vkData.handles.find(name) == vkData.handles.end()); + vkData.handles[name]; // add this to the handles map } void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) @@ -1215,7 +1232,7 @@ void readTypeStructMember( tinyxml2::XMLElement * element, std::vector & dependencies, std::map & structs, std::set & vkTypes ) +void readTypeStruct( tinyxml2::XMLElement * element, VkData & vkData ) { assert( !element->Attribute( "returnedonly" ) || ( strcmp( element->Attribute( "returnedonly" ), "true" ) == 0 ) ); @@ -1227,10 +1244,10 @@ void readTypeStruct( tinyxml2::XMLElement * element, std::list & return; } - dependencies.push_back( DependencyData( DependencyData::Category::STRUCT, name ) ); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::STRUCT, name ) ); - assert( structs.find( name ) == structs.end() ); - std::map::iterator it = structs.insert( std::make_pair( name, StructData() ) ).first; + assert( vkData.structs.find( name ) == vkData.structs.end() ); + std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; it->second.returnedOnly = !!element->Attribute( "returnedonly" ); tinyxml2::XMLElement * child = element->FirstChildElement(); @@ -1240,7 +1257,7 @@ void readTypeStruct( tinyxml2::XMLElement * element, std::list & std::string value = child->Value(); if ( value == "member" ) { - readTypeStructMember( child, it->second.members, dependencies.back().dependencies ); + readTypeStructMember( child, it->second.members, vkData.dependencies.back().dependencies ); } else { @@ -1248,8 +1265,8 @@ void readTypeStruct( tinyxml2::XMLElement * element, std::list & } } while ( child = child->NextSiblingElement() ); - assert( vkTypes.find( name ) == vkTypes.end() ); - vkTypes.insert( name ); + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); } void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & members, std::set & dependencies ) @@ -1324,25 +1341,25 @@ void readTypeUnionMember( tinyxml2::XMLElement * element, std::vector & dependencies, std::map & structs, std::set & vkTypes ) +void readTypeUnion( tinyxml2::XMLElement * element, VkData & vkData ) { assert( element->Attribute( "name" ) ); std::string name = strip( element->Attribute( "name" ), "Vk" ); - dependencies.push_back( DependencyData( DependencyData::Category::UNION, name ) ); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::UNION, name ) ); - assert( structs.find( name ) == structs.end() ); - std::map::iterator it = structs.insert( std::make_pair( name, StructData() ) ).first; + assert( vkData.structs.find( name ) == vkData.structs.end() ); + std::map::iterator it = vkData.structs.insert( std::make_pair( name, StructData() ) ).first; tinyxml2::XMLElement * child = element->FirstChildElement(); do { assert( strcmp( child->Value(), "member" ) == 0 ); - readTypeUnionMember( child, it->second.members, dependencies.back().dependencies ); + readTypeUnionMember( child, it->second.members, vkData.dependencies.back().dependencies ); } while ( child = child->NextSiblingElement() ); - assert( vkTypes.find( name ) == vkTypes.end() ); - vkTypes.insert( name ); + assert( vkData.vkTypes.find( name ) == vkData.vkTypes.end() ); + vkData.vkTypes.insert( name ); } void readTags(tinyxml2::XMLElement * element, std::set & tags) @@ -1357,7 +1374,7 @@ void readTags(tinyxml2::XMLElement * element, std::set & tags) } while (child = child->NextSiblingElement()); } -void readTypes(tinyxml2::XMLElement * element, std::string & version, std::string & typedefCheck, std::list & dependencies, std::map & flags, std::map & scalars, std::map & structs, std::set & vkTypes, std::map & handles, std::map & enums) +void readTypes(tinyxml2::XMLElement * element, VkData & vkData) { tinyxml2::XMLElement * child = element->FirstChildElement(); do @@ -1370,31 +1387,31 @@ void readTypes(tinyxml2::XMLElement * element, std::string & version, std::strin std::string category = child->Attribute( "category" ); if ( category == "basetype" ) { - readTypeBasetype( child, dependencies ); + readTypeBasetype( child, vkData.dependencies ); } else if ( category == "bitmask" ) { - readTypeBitmask( child, dependencies, flags, scalars, vkTypes, enums ); + readTypeBitmask( child, vkData); } else if ( category == "define" ) { - readTypeDefine( child, version, typedefCheck ); + readTypeDefine( child, vkData ); } else if ( category == "funcpointer" ) { - readTypeFuncpointer( child, dependencies ); + readTypeFuncpointer( child, vkData.dependencies ); } else if ( category == "handle" ) { - readTypeHandle( child, dependencies, vkTypes, handles ); + readTypeHandle( child, vkData ); } else if ( category == "struct" ) { - readTypeStruct( child, dependencies, structs, vkTypes ); + readTypeStruct( child, vkData ); } else if ( category == "union" ) { - readTypeUnion( child, dependencies, structs, vkTypes ); + readTypeUnion( child, vkData ); } else { @@ -1404,16 +1421,15 @@ void readTypes(tinyxml2::XMLElement * element, std::string & version, std::strin else { assert( child->Attribute( "requires" ) && child->Attribute( "name" ) ); - dependencies.push_back( DependencyData( DependencyData::Category::REQUIRED, child->Attribute( "name" ) ) ); + vkData.dependencies.push_back( DependencyData( DependencyData::Category::REQUIRED, child->Attribute( "name" ) ) ); } } while ( child = child->NextSiblingElement() ); } -void sortDependencies( std::list & dependencies, std::vector & sortedDependencies ) +void sortDependencies( std::list & dependencies ) { std::set listedTypes = { "VkFlags" }; - - sortedDependencies.reserve( dependencies.size() ); + std::list sortedDependencies; while ( !dependencies.empty() ) { @@ -1435,6 +1451,8 @@ void sortDependencies( std::list & dependencies, std::vector const& dependencyData, std::map const& enums) +void writeEnumsToString(std::ofstream & ofs, VkData const& vkData) { - for (auto it = dependencyData.begin(); it != dependencyData.end(); ++it) + for (auto it = vkData.dependencies.begin(); it != vkData.dependencies.end(); ++it) { switch (it->category) { case DependencyData::Category::ENUM: - assert(enums.find(it->name) != enums.end()); - writeEnumGetString(ofs, *it, enums.find(it->name)->second); + assert(vkData.enums.find(it->name) != vkData.enums.end()); + writeEnumGetString(ofs, *it, vkData.enums.find(it->name)->second); break; case DependencyData::Category::FLAGS: - writeFlagsGetString(ofs, *it, enums.find(*it->dependencies.begin())->second); + writeFlagsGetString(ofs, *it, vkData.enums.find(*it->dependencies.begin())->second); break; } } @@ -2372,7 +2390,7 @@ void writeTypeFlags( std::ofstream & ofs, DependencyData const& dependencyData, ofs << std::endl; } -void writeTypeHandle(std::ofstream & ofs, DependencyData const& dependencyData, HandleData const& handle, std::map const& commands, std::vector const& dependencies, std::set const& vkTypes) +void writeTypeHandle(std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, HandleData const& handle, std::list const& dependencies) { std::string memberName = dependencyData.name; assert(isupper(memberName[0])); @@ -2404,9 +2422,9 @@ void writeTypeHandle(std::ofstream & ofs, DependencyData const& dependencyData, for (size_t i = 0; i < handle.commands.size(); i++) { std::string commandName = handle.commands[i]; - std::map::const_iterator cit = commands.find(commandName); - assert((cit != commands.end()) && cit->second.handleCommand); - std::vector::const_iterator dep = std::find_if(dependencies.begin(), dependencies.end(), [commandName](DependencyData const& dd) { return dd.name == commandName; }); + std::map::const_iterator cit = vkData.commands.find(commandName); + assert((cit != vkData.commands.end()) && cit->second.handleCommand); + std::list::const_iterator dep = std::find_if(dependencies.begin(), dependencies.end(), [commandName](DependencyData const& dd) { return dd.name == commandName; }); assert(dep != dependencies.end()); std::string className = dependencyData.name; std::string functionName = determineFunctionName(dep->name, cit->second); @@ -2416,7 +2434,7 @@ void writeTypeHandle(std::ofstream & ofs, DependencyData const& dependencyData, { ofs << "#ifndef VKCPP_ENHANCED_MODE" << std::endl; } - writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkTypes); + writeTypeCommandStandard(ofs, " ", functionName, *dep, cit->second, vkData.vkTypes); if (!hasPointers) { ofs << "#endif /*!VKCPP_ENHANCED_MODE*/" << std::endl; @@ -2424,7 +2442,7 @@ void writeTypeHandle(std::ofstream & ofs, DependencyData const& dependencyData, ofs << std::endl << "#ifdef VKCPP_ENHANCED_MODE" << std::endl; - writeTypeCommandEnhanced(ofs, " ", className, functionName, *dep, cit->second, vkTypes); + writeTypeCommandEnhanced(ofs, " ", className, functionName, *dep, cit->second, vkData.vkTypes); ofs << "#endif /*VKCPP_ENHANCED_MODE*/" << std::endl; if (i < handle.commands.size() - 1) @@ -2467,10 +2485,10 @@ void writeTypeScalar( std::ofstream & ofs, DependencyData const& dependencyData ofs << " typedef " << *dependencyData.dependencies.begin() << " " << dependencyData.name << ";" << std::endl; } -void writeTypeStruct( std::ofstream & ofs, DependencyData const& dependencyData, std::set const& vkTypes, std::map const& structs, std::map const& defaultValues ) +void writeTypeStruct( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, std::map const& defaultValues ) { - std::map::const_iterator it = structs.find( dependencyData.name ); - assert( it != structs.end() ); + std::map::const_iterator it = vkData.structs.find( dependencyData.name ); + assert( it != vkData.structs.end() ); enterProtect(ofs, it->second.protect); ofs << " class " << dependencyData.name << std::endl @@ -2485,17 +2503,17 @@ void writeTypeStruct( std::ofstream & ofs, DependencyData const& dependencyData, // only structs that are not returnedOnly get a constructor! if ( !it->second.returnedOnly ) { - writeStructConstructor( ofs, dependencyData.name, memberName, it->second, vkTypes, defaultValues ); + writeStructConstructor( ofs, dependencyData.name, memberName, it->second, vkData.vkTypes, defaultValues ); } // create the getters and setters for ( size_t i=0 ; isecond.members.size() ; i++ ) { - writeStructGetter(ofs, it->second.members[i], memberName, vkTypes, true); + writeStructGetter(ofs, it->second.members[i], memberName, vkData.vkTypes, true); if (!it->second.returnedOnly) { - writeStructGetter(ofs, it->second.members[i], memberName, vkTypes, false); - writeStructSetter( ofs, dependencyData.name, it->second.members[i], memberName, vkTypes ); + writeStructGetter(ofs, it->second.members[i], memberName, vkData.vkTypes, false); + writeStructSetter( ofs, dependencyData.name, it->second.members[i], memberName, vkData.vkTypes ); } } @@ -2522,7 +2540,7 @@ void writeTypeStruct( std::ofstream & ofs, DependencyData const& dependencyData, ofs << std::endl; } -void writeTypeUnion( std::ofstream & ofs, DependencyData const& dependencyData, StructData const& unionData, std::set const& vkTypes, std::map const& structs, std::map const& defaultValues ) +void writeTypeUnion( std::ofstream & ofs, VkData const& vkData, DependencyData const& dependencyData, StructData const& unionData, std::map const& defaultValues ) { std::ostringstream oss; ofs << " class " << dependencyData.name << std::endl @@ -2578,11 +2596,11 @@ void writeTypeUnion( std::ofstream & ofs, DependencyData const& dependencyData, << std::endl; // one getter/setter per union element - writeStructGetter(ofs, unionData.members[i], memberName, vkTypes, true); + writeStructGetter(ofs, unionData.members[i], memberName, vkData.vkTypes, true); assert(!unionData.returnedOnly); - writeStructGetter(ofs, unionData.members[i], memberName, vkTypes, false); - writeStructSetter(ofs, dependencyData.name, unionData.members[i], memberName, vkTypes); + writeStructGetter(ofs, unionData.members[i], memberName, vkData.vkTypes, false); + writeStructSetter(ofs, dependencyData.name, unionData.members[i], memberName, vkData.vkTypes); } ofs << " operator Vk" << dependencyData.name << " const& () const" << std::endl << " {" << std::endl @@ -2595,41 +2613,41 @@ void writeTypeUnion( std::ofstream & ofs, DependencyData const& dependencyData, << std::endl; } -void writeTypes(std::ofstream & ofs, std::vector const& dependencies, std::map const& commands, std::map const& enums, std::map const& flags, std::map const& handles, std::map const& structs, std::map const& defaultValues, std::set const& vkTypes) +void writeTypes(std::ofstream & ofs, VkData const& vkData, std::map const& defaultValues) { - for ( std::vector::const_iterator it = dependencies.begin() ; it != dependencies.end() ; ++it ) + for ( std::list::const_iterator it = vkData.dependencies.begin() ; it != vkData.dependencies.end() ; ++it ) { switch( it->category ) { case DependencyData::Category::COMMAND : - assert( commands.find( it->name ) != commands.end() ); - writeTypeCommand( ofs, *it, commands.find( it->name )->second, vkTypes ); + assert( vkData.commands.find( it->name ) != vkData.commands.end() ); + writeTypeCommand( ofs, *it, vkData.commands.find( it->name )->second, vkData.vkTypes ); break; case DependencyData::Category::ENUM : - assert( enums.find( it->name ) != enums.end() ); - writeTypeEnum( ofs, *it, enums.find( it->name )->second ); + assert( vkData.enums.find( it->name ) != vkData.enums.end() ); + writeTypeEnum( ofs, *it, vkData.enums.find( it->name )->second ); break; case DependencyData::Category::FLAGS : - assert(flags.find(it->name) != flags.end()); - writeTypeFlags( ofs, *it, flags.find( it->name)->second ); + assert(vkData.flags.find(it->name) != vkData.flags.end()); + writeTypeFlags( ofs, *it, vkData.flags.find( it->name)->second ); break; case DependencyData::Category::FUNC_POINTER : case DependencyData::Category::REQUIRED : // skip FUNC_POINTER and REQUIRED, they just needed to be in the dependencies list to resolve dependencies break; case DependencyData::Category::HANDLE : - assert(handles.find(it->name) != handles.end()); - writeTypeHandle( ofs, *it, handles.find( it->name )->second, commands, dependencies, vkTypes ); + assert(vkData.handles.find(it->name) != vkData.handles.end()); + writeTypeHandle(ofs, vkData, *it, vkData.handles.find(it->name)->second, vkData.dependencies); break; case DependencyData::Category::SCALAR : writeTypeScalar( ofs, *it ); break; case DependencyData::Category::STRUCT : - writeTypeStruct( ofs, *it, vkTypes, structs, defaultValues ); + writeTypeStruct( ofs, vkData, *it, defaultValues ); break; case DependencyData::Category::UNION : - assert( structs.find( it->name ) != structs.end() ); - writeTypeUnion( ofs, *it, structs.find( it->name )->second, vkTypes, structs, defaultValues ); + assert( vkData.structs.find( it->name ) != vkData.structs.end() ); + writeTypeUnion( ofs, vkData, *it, vkData.structs.find( it->name )->second, defaultValues ); break; default : assert( false ); @@ -2669,18 +2687,7 @@ int main( int argc, char **argv ) assert( strcmp( registryElement->Value(), "registry" ) == 0 ); assert( !registryElement->NextSiblingElement() ); - std::string version; - std::string typesafeCheck; - std::list dependencies; - std::map commands; - std::map enums; - std::map flags; - std::map handles; - std::map scalars; - std::map structs; - std::set tags; - std::set vkTypes; - std::string vulkanLicenseHeader; + VkData vkData; tinyxml2::XMLElement * child = registryElement->FirstChildElement(); do @@ -2689,27 +2696,27 @@ int main( int argc, char **argv ) const std::string value = child->Value(); if ( value == "commands" ) { - readCommands( child, dependencies, commands, handles, tags ); + readCommands( child, vkData ); } else if (value == "comment") { - readComment(child, vulkanLicenseHeader); + readComment(child, vkData.vulkanLicenseHeader); } else if ( value == "enums" ) { - readEnums( child, dependencies, enums, tags, vkTypes ); + readEnums( child, vkData ); } else if ( value == "extensions" ) { - readExtensions( child, commands, enums, flags, scalars, structs, tags ); + readExtensions( child, vkData ); } else if (value == "tags") { - readTags(child, tags); + readTags(child, vkData.tags); } else if ( value == "types" ) { - readTypes( child, version, typesafeCheck, dependencies, flags, scalars, structs, vkTypes, handles, enums ); + readTypes( child, vkData ); } else { @@ -2717,15 +2724,14 @@ int main( int argc, char **argv ) } } while ( child = child->NextSiblingElement() ); - std::vector sortedDependencies; - sortDependencies( dependencies, sortedDependencies ); + sortDependencies( vkData.dependencies ); std::map defaultValues; - createDefaults( sortedDependencies, enums, defaultValues ); + createDefaults( vkData, defaultValues ); std::ofstream ofs( "vk_cpp.h" ); ofs << nvidiaLicenseHeader << std::endl - << vulkanLicenseHeader << std::endl + << vkData.vulkanLicenseHeader << std::endl << std::endl << std::endl << "#ifndef VK_CPP_H_" << std::endl @@ -2743,19 +2749,19 @@ int main( int argc, char **argv ) << "#endif /*VKCPP_ENHANCED_MODE*/" << std::endl << std::endl; - writeVersionCheck( ofs, version ); - writeTypesafeCheck(ofs, typesafeCheck ); + writeVersionCheck( ofs, vkData.version ); + writeTypesafeCheck(ofs, vkData.typesafeCheck ); ofs << "namespace vk" << std::endl << "{" << std::endl << flagsHeader << optionalClassHeader; // first of all, write out vk::Result and the exception handling stuff - std::vector::const_iterator it = std::find_if(sortedDependencies.begin(), sortedDependencies.end(), [](DependencyData const& dp) { return dp.name == "Result"; }); - assert(it != sortedDependencies.end()); - writeTypeEnum(ofs, *it, enums.find(it->name)->second); - writeEnumGetString(ofs, *it, enums.find(it->name)->second); - sortedDependencies.erase(it); + std::list::const_iterator it = std::find_if(vkData.dependencies.begin(), vkData.dependencies.end(), [](DependencyData const& dp) { return dp.name == "Result"; }); + assert(it != vkData.dependencies.end()); + writeTypeEnum(ofs, *it, vkData.enums.find(it->name)->second); + writeEnumGetString(ofs, *it, vkData.enums.find(it->name)->second); + vkData.dependencies.erase(it); ofs << exceptionHeader; ofs << "} // namespace vk" << std::endl @@ -2770,8 +2776,8 @@ int main( int argc, char **argv ) << "namespace vk" << std::endl << "{" << std::endl; - writeTypes( ofs, sortedDependencies, commands, enums, flags, handles, structs, defaultValues, vkTypes ); - writeEnumsToString(ofs, sortedDependencies, enums); + writeTypes( ofs, vkData, defaultValues ); + writeEnumsToString(ofs, vkData); ofs << "} // namespace vk" << std::endl << std::endl