2016-02-16 14:07:55 +00:00
// Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of NVIDIA CORPORATION nor the names of its
// contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2016-02-17 13:03:05 +00:00
# include <cassert>
# include <algorithm>
2016-02-16 14:07:55 +00:00
# include <fstream>
2016-02-17 13:03:05 +00:00
# include <functional>
2016-02-16 14:07:55 +00:00
# include <iostream>
# include <list>
# include <map>
# include <set>
# include <sstream>
# include <string>
# include <vector>
2016-02-17 13:03:05 +00:00
# include <tinyxml2.h>
2016-02-16 14:07:55 +00:00
const std : : string licenseHeader (
" // Copyright(c) 2015-2016, NVIDIA CORPORATION. All rights reserved. \n "
" // \n "
" // Redistribution and use in source and binary forms, with or without \n "
" // modification, are permitted provided that the following conditions \n "
" // are met: \n "
" // * Redistributions of source code must retain the above copyright \n "
" // notice, this list of conditions and the following disclaimer. \n "
" // * Redistributions in binary form must reproduce the above copyright \n "
" // notice, this list of conditions and the following disclaimer in the \n "
" // documentation and/or other materials provided with the distribution. \n "
" // * Neither the name of NVIDIA CORPORATION nor the names of its \n "
" // contributors may be used to endorse or promote products derived \n "
" // from this software without specific prior written permission. \n "
" // \n "
" // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY \n "
" // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE \n "
" // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR \n "
" // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR \n "
" // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, \n "
" // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, \n "
" // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR \n "
" // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY \n "
" // OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \n "
" // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \n "
" // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \n "
) ;
2016-02-22 14:27:08 +00:00
const std : : string exceptionHeader (
" enum class Result; \n "
" \n "
" class Exception : public std::runtime_error \n "
" { \n "
" public: \n "
" Exception(Result result, std::string const& what) \n "
" : std::runtime_error(what) \n "
" , m_error(result) \n "
" {} \n "
" \n "
" private: \n "
" Result m_error; \n "
" }; \n "
" \n "
) ;
2016-02-16 14:07:55 +00:00
const std : : string flagsHeader (
" template <typename BitType, typename MaskType = uint32_t> \n "
" class Flags \n "
" { \n "
" public: \n "
" Flags() \n "
" : m_mask(0) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags(BitType bit) \n "
" : m_mask(static_cast<uint32_t>(bit)) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags(Flags<BitType> const& rhs) \n "
" : m_mask(rhs.m_mask) \n "
" { \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask = rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator|=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask |= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator&=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask &= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> & operator^=(Flags<BitType> const& rhs) \n "
" { \n "
" m_mask ^= rhs.m_mask; \n "
" return *this; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator|(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result |= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator&(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result &= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" Flags<BitType> operator^(Flags<BitType> const& rhs) const \n "
" { \n "
" Flags<BitType> result(*this); \n "
" result ^= rhs; \n "
" return result; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator!() const \n "
" { \n "
" return !m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator==(Flags<BitType> const& rhs) const \n "
" { \n "
" return m_mask == rhs.m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" bool operator!=(Flags<BitType> const& rhs) const \n "
" { \n "
" return m_mask != rhs.m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
2016-02-16 14:07:55 +00:00
" operator bool() const \n "
" { \n "
" return !!m_mask; \n "
" } \n "
2016-02-17 16:45:27 +00:00
" \n "
" explicit operator MaskType() const \n "
" { \n "
" return m_mask; \n "
" } \n "
" \n "
2016-02-16 14:07:55 +00:00
" private: \n "
" MaskType m_mask; \n "
" }; \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator|(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags | bit; \n "
" } \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator&(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags & bit; \n "
" } \n "
" \n "
" template <typename BitType> \n "
" Flags<BitType> operator^(BitType bit, Flags<BitType> const& flags) \n "
" { \n "
" return flags ^ bit; \n "
" } \n "
" \n "
) ;
2016-02-17 13:03:05 +00:00
// trim from end
std : : string trimEnd ( std : : string const & input )
{
std : : string result = input ;
result . erase ( std : : find_if ( result . rbegin ( ) , result . rend ( ) , std : : not1 ( std : : ptr_fun < int , int > ( std : : isspace ) ) ) . base ( ) , result . end ( ) ) ;
return result ;
}
2016-02-16 14:07:55 +00:00
struct MemberData
{
std : : string type ;
std : : string name ;
std : : string arraySize ;
std : : string pureType ;
std : : string len ;
} ;
struct StructData
{
bool returnedOnly ;
std : : vector < MemberData > members ;
2016-02-22 14:27:08 +00:00
std : : string protect ;
2016-02-16 14:07:55 +00:00
} ;
struct NameValue
{
std : : string name ;
std : : string value ;
} ;
struct EnumData
{
bool bitmask ;
2016-02-18 08:45:18 +00:00
std : : string prefix ;
std : : string postfix ;
2016-02-16 14:07:55 +00:00
std : : vector < NameValue > members ;
2016-02-22 14:27:08 +00:00
std : : string protect ;
2016-02-18 08:45:18 +00:00
void addEnum ( std : : string const & name ) ;
2016-02-16 14:07:55 +00:00
} ;
struct CommandData
{
2016-02-22 14:27:08 +00:00
CommandData ( )
: handleCommand ( false )
, twoStep ( false )
{ }
std : : string returnType ;
std : : vector < MemberData > arguments ;
std : : vector < std : : string > successCodes ;
std : : string protect ;
bool handleCommand ;
bool twoStep ;
2016-02-16 14:07:55 +00:00
} ;
2016-02-22 14:27:08 +00:00
struct HandleData
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : vector < std : : string > commands ;
} ;
struct FlagData
{
std : : string protect ;
} ;
struct ScalarData
{
std : : string protect ;
2016-02-16 14:07:55 +00:00
} ;
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 < std : : string > dependencies ;
} ;
void createDefaults ( std : : vector < DependencyData > const & dependencies , std : : map < std : : string , EnumData > const & enums , std : : map < std : : string , std : : string > & defaultValues ) ;
2016-02-22 14:27:08 +00:00
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 ) ;
size_t findComplexIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters ) ;
DependencyData const & findDependency ( std : : string const & name , std : : vector < DependencyData > const & dependencies ) ;
size_t findReturnIndex ( CommandData const & commandDatam , std : : map < size_t , size_t > const & vectorParameters ) ;
std : : string generateEnumNameForFlags ( std : : string const & name ) ;
std : : map < size_t , size_t > getVectorParameters ( CommandData const & commandData ) ;
bool hasPointerArguments ( CommandData const & commandData ) ;
bool isVectorSizeParameter ( std : : map < size_t , size_t > const & vectorParameters , size_t idx ) ;
void leaveProtect ( std : : ofstream & ofs , std : : string const & protect ) ;
2016-02-16 14:07:55 +00:00
bool noDependencies ( std : : set < std : : string > const & dependencies , std : : map < std : : string , std : : string > & listedTypes ) ;
2016-02-22 14:27:08 +00:00
bool readCommandParam ( tinyxml2 : : XMLElement * element , DependencyData & typeData , std : : vector < MemberData > & arguments ) ;
std : : map < std : : string , CommandData > : : iterator readCommandProto ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands ) ;
void readCommands ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , HandleData > & handles ) ;
void readCommandsCommand ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , HandleData > & handles ) ;
2016-02-17 13:03:05 +00:00
void readEnums ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , EnumData > & enums , std : : set < std : : string > & vkTypes ) ;
2016-02-18 08:45:18 +00:00
void readEnumsEnum ( tinyxml2 : : XMLElement * element , EnumData & enumData ) ;
2016-02-22 14:27:08 +00:00
void readExtensionRequire ( tinyxml2 : : XMLElement * element , std : : string const & protect , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs ) ;
void readExtensions ( tinyxml2 : : XMLElement * element , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs ) ;
void readExtensionsExtension ( tinyxml2 : : XMLElement * element , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs ) ;
2016-02-17 13:03:05 +00:00
void readTypeBasetype ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies ) ;
2016-02-22 14:27:08 +00:00
void readTypeBitmask ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : set < std : : string > & vkTypes , std : : map < std : : string , EnumData > & enums ) ;
2016-02-17 13:03:05 +00:00
void readTypeDefine ( tinyxml2 : : XMLElement * element , std : : string & version ) ;
void readTypeFuncpointer ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies ) ;
2016-02-22 14:27:08 +00:00
void readTypeHandle ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : set < std : : string > & vkTypes , std : : map < std : : string , HandleData > & handles ) ;
2016-02-17 13:03:05 +00:00
void readTypeStruct ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes ) ;
void readTypeStructMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies ) ;
void readTypeUnion ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes ) ;
void readTypeUnionMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies ) ;
2016-02-22 14:27:08 +00:00
void readTypes ( tinyxml2 : : XMLElement * element , std : : string & version , std : : list < DependencyData > & dependencies , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes , std : : map < std : : string , HandleData > & handles , std : : map < std : : string , EnumData > & enums ) ;
void sortDependencies ( std : : list < DependencyData > & dependencies , std : : vector < DependencyData > & sortedDependencies ) ;
2016-02-16 14:07:55 +00:00
std : : string reduceName ( std : : string const & name ) ;
2016-02-22 14:27:08 +00:00
std : : string strip ( std : : string const & value , std : : string const & prefix ) ;
std : : string stripCommand ( std : : string const & value ) ;
2016-02-16 14:07:55 +00:00
std : : string toCamelCase ( std : : string const & value ) ;
std : : string toUpperCase ( std : : string const & name ) ;
2016-02-22 14:27:08 +00:00
void writeCall ( std : : ofstream & ofs , std : : string const & name , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters = std : : map < size_t , size_t > ( ) , size_t specialIndex = ~ 0 , std : : string const & specialArgument = " " ) ;
void writeExceptionCheck ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : vector < std : : string > const & successCodes ) ;
void writeFunctionHeader ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & returnType , std : : string const & name , CommandData const & commandData , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-16 14:07:55 +00:00
void writeMemberData ( std : : ofstream & ofs , MemberData const & memberData , std : : set < std : : string > const & vkTypes ) ;
void writeStructConstructor ( std : : ofstream & ofs , std : : string const & name , std : : string const & memberName , StructData const & structData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , std : : string > const & defaultValues ) ;
void writeStructGetter ( std : : ofstream & ofs , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes ) ;
void writeStructSetter ( std : : ofstream & ofs , std : : string const & name , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs ) ;
void writeTypeCommand ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
2016-02-22 14:27:08 +00:00
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters ) ;
void writeTypeCommandEnhancedSingleStep ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
void writeTypeCommandEnhancedTwoStep ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
void writeTypeCommandEnhancedReplaceReturn ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters ) ;
2016-02-16 14:07:55 +00:00
void writeTypeCommandStandard ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes ) ;
2016-02-22 14:27:08 +00:00
void writeTypeCommandComplexBody ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : map < std : : string , std : : string > const & nameMap , std : : map < size_t , size_t > const & vectorParameters , std : : set < size_t > const & argIndices , size_t complexIndex , size_t returnIndex ) ;
void writeTypeCommandSimpleBody ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : map < std : : string , std : : string > const & nameMap , std : : map < size_t , size_t > const & vectorParameters , std : : set < size_t > const & argIndices , std : : map < size_t , std : : vector < size_t > > const & sizeIndices , size_t returnIndex ) ;
2016-02-16 14:07:55 +00:00
void writeTypeEnum ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData ) ;
2016-02-22 14:27:08 +00:00
void writeTypeFlags ( std : : ofstream & ofs , DependencyData const & dependencyData , FlagData const & flagData ) ;
void writeTypeHandle ( std : : ofstream & ofs , DependencyData const & dependencyData , HandleData const & handle , std : : map < std : : string , CommandData > const & commands , std : : vector < DependencyData > const & dependencies , std : : set < std : : string > const & vkTypes ) ;
2016-02-16 14:07:55 +00:00
void writeTypeScalar ( std : : ofstream & ofs , DependencyData const & dependencyData ) ;
void writeTypeStruct ( std : : ofstream & ofs , DependencyData const & dependencyData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues ) ;
void writeTypeUnion ( std : : ofstream & ofs , DependencyData const & dependencyData , StructData const & unionData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues ) ;
2016-02-22 14:27:08 +00:00
void writeTypes ( std : : ofstream & ofs , std : : vector < DependencyData > const & dependencies , std : : map < std : : string , CommandData > const & commands , std : : map < std : : string , EnumData > const & enums , std : : map < std : : string , FlagData > const & flags , std : : map < std : : string , HandleData > const & handles , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues , std : : set < std : : string > const & vkTypes ) ;
void writeVersionCheck ( std : : ofstream & ofs , std : : string const & version ) ;
2016-02-16 14:07:55 +00:00
2016-02-18 08:45:18 +00:00
void EnumData : : addEnum ( std : : string const & name )
{
members . push_back ( NameValue ( ) ) ;
members . back ( ) . name = " e " + toCamelCase ( strip ( name , prefix ) ) ;
members . back ( ) . value = name ;
if ( ! postfix . empty ( ) )
{
size_t pos = members . back ( ) . name . find ( postfix ) ;
if ( pos ! = std : : string : : npos )
{
members . back ( ) . name . erase ( pos ) ;
}
}
}
2016-02-16 14:07:55 +00:00
void createDefaults ( std : : vector < DependencyData > const & dependencies , std : : map < std : : string , EnumData > const & enums , std : : map < std : : string , std : : string > & defaultValues )
{
for ( std : : vector < DependencyData > : : const_iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) ; + + it )
{
assert ( defaultValues . find ( it - > name ) = = defaultValues . end ( ) ) ;
switch ( it - > category )
{
case DependencyData : : Category : : COMMAND : // commands should never be asked for defaults
break ;
case DependencyData : : Category : : ENUM :
2016-02-19 11:56:38 +00:00
{
assert ( enums . find ( it - > name ) ! = enums . end ( ) ) ;
EnumData const & enumData = enums . find ( it - > name ) - > second ;
if ( ! enumData . members . empty ( ) )
{
defaultValues [ it - > name ] = it - > name + " :: " + enums . find ( it - > name ) - > second . members . front ( ) . name ;
}
else
{
defaultValues [ it - > name ] = it - > name + " () " ;
}
}
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : FLAGS :
2016-02-22 14:27:08 +00:00
case DependencyData : : Category : : HANDLE :
case DependencyData : : Category : : STRUCT :
2016-02-16 14:07:55 +00:00
case DependencyData : : Category : : UNION : // just call the default constructor for flags, structs, and structs (which are mapped to classes)
defaultValues [ it - > name ] = it - > name + " () " ;
break ;
case DependencyData : : Category : : FUNC_POINTER : // func_pointers explicitly have no default!
defaultValues [ it - > name ] ;
break ;
case DependencyData : : Category : : REQUIRED : // all required default to "0"
case DependencyData : : Category : : SCALAR : // all scalars default to "0"
defaultValues [ it - > name ] = " 0 " ;
break ;
default :
assert ( false ) ;
break ;
}
}
}
2016-02-22 14:27:08 +00:00
std : : string determineFunctionName ( std : : string const & name , CommandData const & commandData )
{
if ( commandData . handleCommand )
{
std : : string strippedName = name ;
std : : string searchName = commandData . arguments [ 0 ] . pureType ;
size_t pos = name . find ( searchName ) ;
if ( pos = = std : : string : : npos )
{
assert ( isupper ( searchName [ 0 ] ) ) ;
searchName [ 0 ] = tolower ( searchName [ 0 ] ) ;
pos = name . find ( searchName ) ;
}
if ( pos ! = std : : string : : npos )
{
strippedName . erase ( pos , commandData . arguments [ 0 ] . pureType . length ( ) ) ;
}
else if ( ( commandData . arguments [ 0 ] . pureType = = " CommandBuffer " ) & & ( name . find ( " cmd " ) = = 0 ) )
{
strippedName . erase ( 0 , 3 ) ;
pos = 0 ;
}
if ( pos = = 0 )
{
assert ( isupper ( strippedName [ 0 ] ) ) ;
strippedName [ 0 ] = tolower ( strippedName [ 0 ] ) ;
}
return strippedName ;
}
return name ;
}
std : : string determineReturnType ( CommandData const & commandData , size_t returnIndex , bool isVector )
{
std : : string returnType ;
if ( returnIndex ! = ~ 0 )
{
if ( ( commandData . returnType = = " Result " ) & & ( 1 < commandData . successCodes . size ( ) ) )
{
return ( " Result " ) ;
}
else if ( isVector )
{
if ( commandData . arguments [ returnIndex ] . pureType = = " void " )
{
returnType = " std::vector<uint8_t> " ;
}
else
{
returnType = " std::vector< " + commandData . arguments [ returnIndex ] . pureType + " > " ;
}
}
else
{
assert ( commandData . arguments [ returnIndex ] . type . back ( ) = = ' * ' ) ;
assert ( commandData . arguments [ returnIndex ] . type . find ( " const " ) = = std : : string : : npos ) ;
returnType = commandData . arguments [ returnIndex ] . type ;
returnType . pop_back ( ) ;
}
}
else if ( ( commandData . returnType = = " Result " ) & & ( commandData . successCodes . size ( ) < 2 ) )
{
returnType = " void " ;
}
else
{
returnType = commandData . returnType ;
}
return std : : move ( returnType ) ;
}
void enterProtect ( std : : ofstream & ofs , std : : string const & protect )
{
if ( ! protect . empty ( ) )
{
ofs < < " #ifdef " < < protect < < std : : endl ;
}
}
size_t findComplexIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
if ( ( it - > second ! = ~ 0 ) & & ( commandData . arguments [ it - > second ] . type . find ( ' * ' ) ! = std : : string : : npos ) )
2016-02-16 14:07:55 +00:00
{
# if !defined(NDEBUG)
2016-02-22 14:27:08 +00:00
std : : map < size_t , size_t > : : const_iterator jt = it ;
for ( + + jt ; jt ! = vectorParameters . end ( ) ; + + jt )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
assert ( ( jt - > second = = ~ 0 ) | | ( commandData . arguments [ jt - > second ] . type . find ( ' * ' ) = = std : : string : : npos ) ) ;
2016-02-16 14:07:55 +00:00
}
# endif
2016-02-22 14:27:08 +00:00
return it - > first ;
2016-02-16 14:07:55 +00:00
}
}
return ~ 0 ;
}
2016-02-22 14:27:08 +00:00
DependencyData const & findDependency ( std : : string const & name , std : : vector < DependencyData > const & dependencies )
{
for ( std : : vector < DependencyData > : : const_iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) ; + + it )
{
if ( it - > name = = name )
{
return * it ;
}
}
assert ( false ) ;
return * dependencies . begin ( ) ;
}
size_t findReturnIndex ( CommandData const & commandData , std : : map < size_t , size_t > const & vectorParameters )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
if ( ( commandData . arguments [ i ] . type . find ( ' * ' ) ! = std : : string : : npos ) & & ( commandData . arguments [ i ] . type . find ( " const " ) = = std : : string : : npos ) & & ! isVectorSizeParameter ( vectorParameters , i ) )
2016-02-16 14:07:55 +00:00
{
# if !defined(NDEBUG)
2016-02-22 14:27:08 +00:00
for ( size_t j = i + 1 ; j < commandData . arguments . size ( ) ; j + + )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
assert ( ( commandData . arguments [ j ] . type . find ( ' * ' ) = = std : : string : : npos ) | | ( commandData . arguments [ j ] . type . find ( " const " ) ! = std : : string : : npos ) ) ;
2016-02-16 14:07:55 +00:00
}
# endif
return i ;
}
}
return ~ 0 ;
}
2016-02-18 08:45:18 +00:00
std : : string getEnumName ( std : : string const & name ) // get vkcpp enum name from vk enum name
{
return strip ( name , " Vk " ) ;
}
2016-02-22 14:27:08 +00:00
bool hasPointerArguments ( CommandData const & commandData )
{
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
size_t pos = commandData . arguments [ i ] . type . find ( ' * ' ) ;
if ( ( pos ! = std : : string : : npos ) & & ( commandData . arguments [ i ] . type . find ( ' * ' , pos + 1 ) = = std : : string : : npos ) )
{
return true ;
}
}
return false ;
}
std : : string generateEnumNameForFlags ( std : : string const & name )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : string generatedName = name ;
size_t pos = generatedName . rfind ( " Flags " ) ;
assert ( pos ! = std : : string : : npos ) ;
generatedName . replace ( pos , 5 , " FlagBits " ) ;
return generatedName ;
}
std : : map < size_t , size_t > getVectorParameters ( CommandData const & commandData )
{
std : : map < size_t , size_t > lenParameters ;
2016-02-16 14:07:55 +00:00
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( ! commandData . arguments [ i ] . len . empty ( ) )
{
2016-02-22 14:27:08 +00:00
lenParameters . insert ( std : : make_pair ( i , ~ 0 ) ) ;
2016-02-16 14:07:55 +00:00
for ( size_t j = 0 ; j < commandData . arguments . size ( ) ; j + + )
{
if ( commandData . arguments [ i ] . len = = commandData . arguments [ j ] . name )
{
2016-02-22 14:27:08 +00:00
lenParameters [ i ] = j ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-22 14:27:08 +00:00
assert ( ( lenParameters [ i ] ! = ~ 0 )
2016-02-16 14:07:55 +00:00
| | ( commandData . arguments [ i ] . len = = " dataSize/4 " )
| | ( commandData . arguments [ i ] . len = = " null-terminated " )
| | ( commandData . arguments [ i ] . len = = " pAllocateInfo->descriptorSetCount " )
| | ( commandData . arguments [ i ] . len = = " pAllocateInfo->commandBufferCount " ) ) ;
2016-02-22 14:27:08 +00:00
assert ( ( lenParameters [ i ] = = ~ 0 ) | | ( lenParameters [ i ] < i ) ) ;
2016-02-16 14:07:55 +00:00
}
}
return std : : move ( lenParameters ) ;
}
2016-02-22 14:27:08 +00:00
bool isVectorSizeParameter ( std : : map < size_t , size_t > const & vectorParameters , size_t idx )
{
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
{
if ( it - > second = = idx )
{
return true ;
}
}
return false ;
}
void leaveProtect ( std : : ofstream & ofs , std : : string const & protect )
{
if ( ! protect . empty ( ) )
{
ofs < < " #endif /* " < < protect < < " */ " < < std : : endl ;
}
}
2016-02-16 14:07:55 +00:00
bool noDependencies ( std : : set < std : : string > const & dependencies , std : : set < std : : string > & listedTypes )
{
bool ok = true ;
for ( std : : set < std : : string > : : const_iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) & & ok ; + + it )
{
ok = ( listedTypes . find ( * it ) ! = listedTypes . end ( ) ) ;
}
return ( ok ) ;
}
2016-02-22 14:27:08 +00:00
bool readCommandParam ( tinyxml2 : : XMLElement * element , DependencyData & typeData , std : : vector < MemberData > & arguments )
2016-02-16 14:07:55 +00:00
{
arguments . push_back ( MemberData ( ) ) ;
MemberData & arg = arguments . back ( ) ;
if ( element - > Attribute ( " len " ) )
{
arg . len = element - > Attribute ( " len " ) ;
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
assert ( ( value = = " const " ) | | ( value = = " struct " ) ) ;
arg . type = value + " " ;
2016-02-16 14:07:55 +00:00
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( strcmp ( child - > Value ( ) , " type " ) = = 0 ) & & child - > ToElement ( ) & & child - > ToElement ( ) - > GetText ( ) ) ;
std : : string type = strip ( child - > ToElement ( ) - > GetText ( ) , " Vk " ) ;
typeData . dependencies . insert ( type ) ;
arg . type + = type ;
arg . pureType = type ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
arg . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
arg . name = child - > ToElement ( ) - > GetText ( ) ;
if ( arg . name . back ( ) = = ' ] ' )
{
assert ( ! child - > NextSibling ( ) ) ;
size_t pos = arg . name . find ( ' [ ' ) ;
assert ( pos ! = std : : string : : npos ) ;
arg . arraySize = arg . name . substr ( pos + 1 , arg . name . length ( ) - 2 - pos ) ;
arg . name . erase ( pos ) ;
}
child = child - > NextSibling ( ) ;
if ( child )
{
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
arg . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( strcmp ( child - > Value ( ) , " ] " ) = = 0 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
else
{
assert ( ( value . front ( ) = = ' [ ' ) & & ( value . back ( ) = = ' ] ' ) ) ;
arg . arraySize = value . substr ( 1 , value . length ( ) - 2 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
}
}
2016-02-22 14:27:08 +00:00
return element - > Attribute ( " optional " ) & & ( strcmp ( element - > Attribute ( " optional " ) , " false,true " ) = = 0 ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
std : : map < std : : string , CommandData > : : iterator readCommandProto ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) ) ;
assert ( ! nameElement - > NextSiblingElement ( ) ) ;
std : : string type = strip ( typeElement - > GetText ( ) , " Vk " ) ;
2016-02-22 14:27:08 +00:00
std : : string name = stripCommand ( nameElement - > GetText ( ) ) ;
2016-02-16 14:07:55 +00:00
dependencies . push_back ( DependencyData ( DependencyData : : Category : : COMMAND , name ) ) ;
assert ( commands . find ( name ) = = commands . end ( ) ) ;
std : : map < std : : string , CommandData > : : iterator it = commands . insert ( std : : make_pair ( name , CommandData ( ) ) ) . first ;
it - > second . returnType = type ;
2016-02-22 14:27:08 +00:00
return it ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
void readCommands ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , HandleData > & handles )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
do
{
assert ( strcmp ( child - > Value ( ) , " command " ) = = 0 ) ;
2016-02-22 14:27:08 +00:00
readCommandsCommand ( child , dependencies , commands , handles ) ;
2016-02-16 14:07:55 +00:00
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-02-22 14:27:08 +00:00
void readCommandsCommand ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , HandleData > & handles )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " proto " ) = = 0 ) ) ;
2016-02-22 14:27:08 +00:00
std : : map < std : : string , CommandData > : : iterator it = readCommandProto ( child , dependencies , commands ) ;
if ( element - > Attribute ( " successcodes " ) )
{
std : : string successCodes = element - > Attribute ( " successcodes " ) ;
size_t start = 0 , end ;
do
{
end = successCodes . find ( ' , ' , start ) ;
it - > second . successCodes . push_back ( successCodes . substr ( start , end - start ) ) ;
start = end + 1 ;
} while ( end ! = std : : string : : npos ) ;
}
// HACK: the current vk.xml misses to specify successcodes on command vkCreateDebugReportCallbackEXT!
if ( it - > first = = " createDebugReportCallbackEXT " )
{
it - > second . successCodes . clear ( ) ;
it - > second . successCodes . push_back ( " VK_SUCCESS " ) ;
}
2016-02-16 14:07:55 +00:00
while ( child = child - > NextSiblingElement ( ) )
{
std : : string value = child - > Value ( ) ;
if ( value = = " param " )
{
2016-02-22 14:27:08 +00:00
it - > second . twoStep | = readCommandParam ( child , dependencies . back ( ) , it - > second . arguments ) ;
2016-02-16 14:07:55 +00:00
}
else
{
assert ( ( value = = " implicitexternsyncparams " ) | | ( value = = " validity " ) ) ;
}
}
2016-02-22 14:27:08 +00:00
// HACK: the current vk.xml misses to specify <optional="false,true"> on param pSparseMemoryRequirementCount on command vkGetImageSparseMemoryRequirements!
if ( it - > first = = " getImageSparseMemoryRequirements " )
{
it - > second . twoStep = true ;
}
assert ( ! it - > second . arguments . empty ( ) ) ;
std : : map < std : : string , HandleData > : : iterator hit = handles . find ( it - > second . arguments [ 0 ] . pureType ) ;
if ( hit ! = handles . end ( ) )
{
hit - > second . commands . push_back ( it - > first ) ;
it - > second . handleCommand = true ;
DependencyData const & dep = dependencies . back ( ) ;
std : : list < DependencyData > : : iterator dit = std : : find_if ( dependencies . begin ( ) , dependencies . end ( ) , [ hit ] ( DependencyData const & dd ) { return dd . name = = hit - > first ; } ) ;
for ( std : : set < std : : string > : : const_iterator depit = dep . dependencies . begin ( ) ; depit ! = dep . dependencies . end ( ) ; + + depit )
{
if ( * depit ! = hit - > first )
{
dit - > dependencies . insert ( * depit ) ;
}
}
}
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readEnums ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , EnumData > & enums , std : : set < std : : string > & vkTypes )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
2016-02-18 08:45:18 +00:00
std : : string name = getEnumName ( element - > Attribute ( " name " ) ) ;
2016-02-16 14:07:55 +00:00
if ( name ! = " API Constants " )
{
dependencies . push_back ( DependencyData ( DependencyData : : Category : : ENUM , name ) ) ;
std : : map < std : : string , EnumData > : : iterator it = enums . insert ( std : : make_pair ( name , EnumData ( ) ) ) . first ;
assert ( element - > Attribute ( " type " ) ) ;
std : : string type = element - > Attribute ( " type " ) ;
assert ( ( type = = " bitmask " ) | | ( type = = " enum " ) ) ;
it - > second . bitmask = ( type = = " bitmask " ) ;
std : : string prefix , postfix ;
if ( it - > second . bitmask )
{
size_t pos = name . find ( " FlagBits " ) ;
assert ( pos ! = std : : string : : npos ) ;
2016-02-18 08:45:18 +00:00
it - > second . prefix = " VK " + toUpperCase ( name . substr ( 0 , pos ) ) + " _ " ;
it - > second . postfix = " Bit " ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-02-18 08:45:18 +00:00
it - > second . prefix = " VK " + toUpperCase ( name ) + " _ " ;
2016-02-16 14:07:55 +00:00
}
2016-02-18 08:45:18 +00:00
readEnumsEnum ( element , it - > second ) ;
2016-02-16 14:07:55 +00:00
assert ( vkTypes . find ( name ) = = vkTypes . end ( ) ) ;
vkTypes . insert ( name ) ;
}
}
2016-02-18 08:45:18 +00:00
void readEnumsEnum ( tinyxml2 : : XMLElement * element , EnumData & enumData )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
if ( child - > Attribute ( " name " ) )
{
2016-02-18 08:45:18 +00:00
enumData . addEnum ( child - > Attribute ( " name " ) ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-02-22 14:27:08 +00:00
void readExtensionRequire ( tinyxml2 : : XMLElement * element , std : : string const & protect , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
std : : string value = child - > Value ( ) ;
assert ( child - > Attribute ( " name " ) ) ;
2016-02-18 08:45:18 +00:00
2016-02-16 14:07:55 +00:00
if ( value = = " command " )
{
2016-02-22 14:27:08 +00:00
std : : string name = stripCommand ( child - > Attribute ( " name " ) ) ;
std : : map < std : : string , CommandData > : : iterator cit = commands . find ( name ) ;
assert ( cit ! = commands . end ( ) ) ;
cit - > second . protect = protect ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
else if ( value = = " type " )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : string name = strip ( child - > Attribute ( " name " ) , " Vk " ) ;
std : : map < std : : string , EnumData > : : iterator eit = enums . find ( name ) ;
if ( eit ! = enums . end ( ) )
{
eit - > second . protect = protect ;
}
else
{
std : : map < std : : string , FlagData > : : iterator fit = flags . find ( name ) ;
if ( fit ! = 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 < std : : string , EnumData > : : iterator eit = enums . find ( enumName ) ;
assert ( eit ! = enums . end ( ) ) ;
if ( eit - > second . members . empty ( ) )
{
eit - > second . protect = protect ;
}
}
else
{
std : : map < std : : string , ScalarData > : : iterator scit = scalars . find ( name ) ;
if ( scit ! = scalars . end ( ) )
{
scit - > second . protect = protect ;
}
else
{
std : : map < std : : string , StructData > : : iterator stit = structs . find ( name ) ;
assert ( stit ! = structs . end ( ) & & stit - > second . protect . empty ( ) ) ;
stit - > second . protect = protect ;
}
}
}
2016-02-16 14:07:55 +00:00
}
2016-02-18 08:45:18 +00:00
else if ( value = = " enum " )
{
// TODO process enums which don't extend existing enums
if ( child - > Attribute ( " extends " ) )
{
assert ( enums . find ( getEnumName ( child - > Attribute ( " extends " ) ) ) ! = enums . end ( ) ) ;
enums [ getEnumName ( child - > Attribute ( " extends " ) ) ] . addEnum ( child - > Attribute ( " name " ) ) ;
}
}
2016-02-16 14:07:55 +00:00
else
{
2016-02-18 08:45:18 +00:00
assert ( " unknown attribute, check me " ) ;
2016-02-16 14:07:55 +00:00
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-02-22 14:27:08 +00:00
void readExtensions ( tinyxml2 : : XMLElement * element , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
do
{
assert ( strcmp ( child - > Value ( ) , " extension " ) = = 0 ) ;
2016-02-22 14:27:08 +00:00
readExtensionsExtension ( child , commands , enums , flags , scalars , structs ) ;
2016-02-16 14:07:55 +00:00
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-02-22 14:27:08 +00:00
void readExtensionsExtension ( tinyxml2 : : XMLElement * element , std : : map < std : : string , CommandData > & commands , std : : map < std : : string , EnumData > & enums , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
2016-02-18 08:45:18 +00:00
// don't parse disabled extensions
if ( strcmp ( element - > Attribute ( " supported " ) , " disabled " ) = = 0 )
{
return ;
}
2016-02-22 14:27:08 +00:00
std : : string protect ;
if ( element - > Attribute ( " protect " ) )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
protect = element - > Attribute ( " protect " ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " require " ) = = 0 ) & & ! child - > NextSiblingElement ( ) ) ;
2016-02-22 14:27:08 +00:00
readExtensionRequire ( child , protect , commands , enums , flags , scalars , structs ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeBasetype ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) ) ;
std : : string type = typeElement - > GetText ( ) ;
assert ( ( type = = " uint32_t " ) | | ( type = = " uint64_t " ) ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) & & nameElement - > GetText ( ) ) ;
std : : string name = strip ( nameElement - > GetText ( ) , " Vk " ) ;
// skip "Flags",
if ( name ! = " Flags " )
{
dependencies . push_back ( DependencyData ( DependencyData : : Category : : SCALAR , name ) ) ;
dependencies . back ( ) . dependencies . insert ( type ) ;
}
else
{
assert ( type = = " uint32_t " ) ;
}
}
2016-02-22 14:27:08 +00:00
void readTypeBitmask ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : set < std : : string > & vkTypes , std : : map < std : : string , EnumData > & enums )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) & & ( strcmp ( typeElement - > GetText ( ) , " VkFlags " ) = = 0 ) ) ;
std : : string type = typeElement - > GetText ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) & & nameElement - > GetText ( ) ) ;
std : : string name = strip ( nameElement - > GetText ( ) , " Vk " ) ;
assert ( ! nameElement - > NextSiblingElement ( ) ) ;
2016-02-19 11:56:38 +00:00
std : : string requires ;
if ( element - > Attribute ( " requires " ) )
2016-02-16 14:07:55 +00:00
{
2016-02-19 11:56:38 +00:00
requires = strip ( element - > Attribute ( " requires " ) , " Vk " ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-19 11:56:38 +00:00
else {
// Generate FlagBits name
2016-02-22 14:27:08 +00:00
requires = generateEnumNameForFlags ( name ) ;
2016-02-19 11:56:38 +00:00
dependencies . push_back ( DependencyData ( DependencyData : : Category : : ENUM , requires ) ) ;
std : : map < std : : string , EnumData > : : iterator it = enums . insert ( std : : make_pair ( requires , EnumData ( ) ) ) . first ;
it - > second . bitmask = true ;
vkTypes . insert ( requires ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-19 11:56:38 +00:00
dependencies . push_back ( DependencyData ( DependencyData : : Category : : FLAGS , name ) ) ;
dependencies . back ( ) . dependencies . insert ( requires ) ;
2016-02-22 14:27:08 +00:00
flags . insert ( std : : make_pair ( name , FlagData ( ) ) ) ;
2016-02-19 11:56:38 +00:00
assert ( vkTypes . find ( name ) = = vkTypes . end ( ) ) ;
vkTypes . insert ( name ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeDefine ( tinyxml2 : : XMLElement * element , std : : string & version )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
if ( child & & ( strcmp ( child - > GetText ( ) , " VK_API_VERSION " ) = = 0 ) )
{
version = element - > LastChild ( ) - > ToText ( ) - > Value ( ) ;
}
}
2016-02-17 13:03:05 +00:00
void readTypeFuncpointer ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) & & child - > GetText ( ) ) ;
dependencies . push_back ( DependencyData ( DependencyData : : Category : : FUNC_POINTER , child - > GetText ( ) ) ) ;
}
2016-02-22 14:27:08 +00:00
void readTypeHandle ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : set < std : : string > & vkTypes , std : : map < std : : string , HandleData > & handles )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * typeElement = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( typeElement & & ( strcmp ( typeElement - > Value ( ) , " type " ) = = 0 ) & & typeElement - > GetText ( ) ) ;
# if !defined(NDEBUG)
std : : string type = typeElement - > GetText ( ) ;
assert ( type . find ( " VK_DEFINE " ) = = 0 ) ;
# endif
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * nameElement = typeElement - > NextSiblingElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( nameElement & & ( strcmp ( nameElement - > Value ( ) , " name " ) = = 0 ) & & nameElement - > GetText ( ) ) ;
std : : string name = strip ( nameElement - > GetText ( ) , " Vk " ) ;
dependencies . push_back ( DependencyData ( DependencyData : : Category : : HANDLE , name ) ) ;
2016-02-22 14:27:08 +00:00
assert ( vkTypes . find ( name ) = = vkTypes . end ( ) ) ;
vkTypes . insert ( name ) ;
assert ( handles . find ( name ) = = handles . end ( ) ) ;
handles [ name ] ; // add this to the handles map
2016-02-16 14:07:55 +00:00
}
2016-02-17 13:03:05 +00:00
void readTypeStructMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies )
2016-02-16 14:07:55 +00:00
{
members . push_back ( MemberData ( ) ) ;
MemberData & member = members . back ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
assert ( ( value = = " const " ) | | ( value = = " struct " ) ) ;
member . type = value + " " ;
2016-02-16 14:07:55 +00:00
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( strcmp ( child - > Value ( ) , " type " ) = = 0 ) & & child - > ToElement ( ) & & child - > ToElement ( ) - > GetText ( ) ) ;
std : : string type = strip ( child - > ToElement ( ) - > GetText ( ) , " Vk " ) ;
dependencies . insert ( type ) ;
member . type + = type ;
member . pureType = type ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : string value = trimEnd ( child - > Value ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
member . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( ( child - > ToElement ( ) & & strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . name = child - > ToElement ( ) - > GetText ( ) ;
if ( member . name . back ( ) = = ' ] ' )
{
assert ( ! child - > NextSibling ( ) ) ;
size_t pos = member . name . find ( ' [ ' ) ;
assert ( pos ! = std : : string : : npos ) ;
member . arraySize = member . name . substr ( pos + 1 , member . name . length ( ) - 2 - pos ) ;
member . name . erase ( pos ) ;
}
child = child - > NextSibling ( ) ;
if ( child )
{
assert ( member . arraySize . empty ( ) ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( strcmp ( child - > Value ( ) , " ] " ) = = 0 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
else
{
assert ( ( value . front ( ) = = ' [ ' ) & & ( value . back ( ) = = ' ] ' ) ) ;
member . arraySize = value . substr ( 1 , value . length ( ) - 2 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
}
}
}
2016-02-17 13:03:05 +00:00
void readTypeStruct ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes )
2016-02-16 14:07:55 +00:00
{
assert ( ! element - > Attribute ( " returnedonly " ) | | ( strcmp ( element - > Attribute ( " returnedonly " ) , " true " ) = = 0 ) ) ;
assert ( element - > Attribute ( " name " ) ) ;
std : : string name = strip ( element - > Attribute ( " name " ) , " Vk " ) ;
if ( name = = " Rect3D " )
{
return ;
}
dependencies . push_back ( DependencyData ( DependencyData : : Category : : STRUCT , name ) ) ;
assert ( structs . find ( name ) = = structs . end ( ) ) ;
std : : map < std : : string , StructData > : : iterator it = structs . insert ( std : : make_pair ( name , StructData ( ) ) ) . first ;
it - > second . returnedOnly = ! ! element - > Attribute ( " returnedonly " ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( child - > Value ( ) ) ;
std : : string value = child - > Value ( ) ;
if ( value = = " member " )
{
readTypeStructMember ( child , it - > second . members , dependencies . back ( ) . dependencies ) ;
}
else
{
assert ( value = = " validity " ) ;
}
} while ( child = child - > NextSiblingElement ( ) ) ;
assert ( vkTypes . find ( name ) = = vkTypes . end ( ) ) ;
vkTypes . insert ( name ) ;
}
2016-02-17 13:03:05 +00:00
void readTypeUnionMember ( tinyxml2 : : XMLElement * element , std : : vector < MemberData > & members , std : : set < std : : string > & dependencies )
2016-02-16 14:07:55 +00:00
{
members . push_back ( MemberData ( ) ) ;
MemberData & member = members . back ( ) ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLNode * child = element - > FirstChild ( ) ;
2016-02-16 14:07:55 +00:00
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
assert ( ( strcmp ( child - > Value ( ) , " const " ) = = 0 ) | | ( strcmp ( child - > Value ( ) , " struct " ) = = 0 ) ) ;
member . type = std : : string ( child - > Value ( ) ) + " " ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( ( strcmp ( child - > Value ( ) , " type " ) = = 0 ) & & child - > ToElement ( ) & & child - > ToElement ( ) - > GetText ( ) ) ;
std : : string type = strip ( child - > ToElement ( ) - > GetText ( ) , " Vk " ) ;
dependencies . insert ( type ) ;
member . type + = type ;
member . pureType = type ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
assert ( ( value = = " * " ) | | ( value = = " ** " ) | | ( value = = " * const* " ) ) ;
member . type + = value ;
child = child - > NextSibling ( ) ;
}
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " name " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . name = child - > ToElement ( ) - > GetText ( ) ;
if ( member . name . back ( ) = = ' ] ' )
{
assert ( ! child - > NextSibling ( ) ) ;
size_t pos = member . name . find ( ' [ ' ) ;
assert ( pos ! = std : : string : : npos ) ;
member . arraySize = member . name . substr ( pos + 1 , member . name . length ( ) - 2 - pos ) ;
member . name . erase ( pos ) ;
}
child = child - > NextSibling ( ) ;
if ( child )
{
2016-02-17 13:03:05 +00:00
if ( child - > ToText ( ) )
2016-02-16 14:07:55 +00:00
{
std : : string value = child - > Value ( ) ;
if ( value = = " [ " )
{
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToElement ( ) & & ( strcmp ( child - > Value ( ) , " enum " ) = = 0 ) ) ;
2016-02-16 14:07:55 +00:00
member . arraySize = child - > ToElement ( ) - > GetText ( ) ;
child = child - > NextSibling ( ) ;
assert ( child ) ;
2016-02-17 13:03:05 +00:00
assert ( child - > ToText ( ) ) ;
2016-02-16 14:07:55 +00:00
assert ( strcmp ( child - > Value ( ) , " ] " ) = = 0 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
else
{
assert ( ( value . front ( ) = = ' [ ' ) & & ( value . back ( ) = = ' ] ' ) ) ;
member . arraySize = value . substr ( 1 , value . length ( ) - 2 ) ;
assert ( ! child - > NextSibling ( ) ) ;
}
}
}
}
2016-02-17 13:03:05 +00:00
void readTypeUnion ( tinyxml2 : : XMLElement * element , std : : list < DependencyData > & dependencies , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes )
2016-02-16 14:07:55 +00:00
{
assert ( element - > Attribute ( " name " ) ) ;
std : : string name = strip ( element - > Attribute ( " name " ) , " Vk " ) ;
dependencies . push_back ( DependencyData ( DependencyData : : Category : : UNION , name ) ) ;
assert ( structs . find ( name ) = = structs . end ( ) ) ;
std : : map < std : : string , StructData > : : iterator it = structs . insert ( std : : make_pair ( name , StructData ( ) ) ) . first ;
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( strcmp ( child - > Value ( ) , " member " ) = = 0 ) ;
readTypeUnionMember ( child , it - > second . members , dependencies . back ( ) . dependencies ) ;
} while ( child = child - > NextSiblingElement ( ) ) ;
assert ( vkTypes . find ( name ) = = vkTypes . end ( ) ) ;
vkTypes . insert ( name ) ;
}
2016-02-22 14:27:08 +00:00
void readTypes ( tinyxml2 : : XMLElement * element , std : : string & version , std : : list < DependencyData > & dependencies , std : : map < std : : string , FlagData > & flags , std : : map < std : : string , ScalarData > & scalars , std : : map < std : : string , StructData > & structs , std : : set < std : : string > & vkTypes , std : : map < std : : string , HandleData > & handles , std : : map < std : : string , EnumData > & enums )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = element - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( strcmp ( child - > Value ( ) , " type " ) = = 0 ) ;
std : : string type = child - > Value ( ) ;
assert ( type = = " type " ) ;
if ( child - > Attribute ( " category " ) )
{
std : : string category = child - > Attribute ( " category " ) ;
if ( category = = " basetype " )
{
readTypeBasetype ( child , dependencies ) ;
}
else if ( category = = " bitmask " )
{
2016-02-22 14:27:08 +00:00
readTypeBitmask ( child , dependencies , flags , scalars , vkTypes , enums ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " define " )
{
readTypeDefine ( child , version ) ;
}
else if ( category = = " funcpointer " )
{
readTypeFuncpointer ( child , dependencies ) ;
}
else if ( category = = " handle " )
{
2016-02-22 14:27:08 +00:00
readTypeHandle ( child , dependencies , vkTypes , handles ) ;
2016-02-16 14:07:55 +00:00
}
else if ( category = = " struct " )
{
readTypeStruct ( child , dependencies , structs , vkTypes ) ;
}
else if ( category = = " union " )
{
readTypeUnion ( child , dependencies , structs , vkTypes ) ;
}
else
{
assert ( ( category = = " enum " ) | | ( category = = " include " ) ) ;
}
}
else
{
assert ( child - > Attribute ( " requires " ) & & child - > Attribute ( " name " ) ) ;
dependencies . push_back ( DependencyData ( DependencyData : : Category : : REQUIRED , child - > Attribute ( " name " ) ) ) ;
}
} while ( child = child - > NextSiblingElement ( ) ) ;
}
2016-02-22 14:27:08 +00:00
void sortDependencies ( std : : list < DependencyData > & dependencies , std : : vector < DependencyData > & sortedDependencies )
2016-02-16 14:07:55 +00:00
{
std : : set < std : : string > listedTypes = { " VkFlags " } ;
2016-02-22 14:27:08 +00:00
sortedDependencies . reserve ( dependencies . size ( ) ) ;
2016-02-16 14:07:55 +00:00
while ( ! dependencies . empty ( ) )
{
# if !defined(NDEBUG)
bool ok = false ;
# endif
for ( std : : list < DependencyData > : : iterator it = dependencies . begin ( ) ; it ! = dependencies . end ( ) ; + + it )
{
if ( noDependencies ( it - > dependencies , listedTypes ) )
{
2016-02-22 14:27:08 +00:00
sortedDependencies . push_back ( * it ) ;
2016-02-16 14:07:55 +00:00
listedTypes . insert ( it - > name ) ;
dependencies . erase ( it ) ;
# if !defined(NDEBUG)
ok = true ;
# endif
break ;
}
}
assert ( ok ) ;
}
}
std : : string reduceName ( std : : string const & name )
{
2016-02-22 14:27:08 +00:00
assert ( 1 < name . length ( ) ) ;
if ( ( name [ 0 ] = = ' p ' ) & & ( isupper ( name [ 1 ] ) | | name [ 1 ] = = ' p ' ) )
{
std : : string reducedName = strip ( name , " p " ) ;
reducedName [ 0 ] = tolower ( reducedName [ 0 ] ) ;
return reducedName ;
}
return name ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
std : : string strip ( std : : string const & value , std : : string const & prefix )
2016-02-16 14:07:55 +00:00
{
if ( value . find ( prefix ) = = 0 )
{
return value . substr ( prefix . length ( ) ) ;
}
return value ;
}
2016-02-22 14:27:08 +00:00
std : : string stripCommand ( std : : string const & value )
{
std : : string stripped = strip ( value , " vk " ) ;
assert ( isupper ( stripped [ 0 ] ) ) ;
stripped [ 0 ] = tolower ( stripped [ 0 ] ) ;
return stripped ;
}
2016-02-16 14:07:55 +00:00
std : : string toCamelCase ( std : : string const & value )
{
assert ( ! value . empty ( ) & & ( isupper ( value [ 0 ] ) | | isdigit ( value [ 0 ] ) ) ) ;
std : : string result ;
result . reserve ( value . size ( ) ) ;
result . push_back ( value [ 0 ] ) ;
for ( size_t i = 1 ; i < value . size ( ) ; i + + )
{
if ( value [ i ] ! = ' _ ' )
{
if ( ( value [ i - 1 ] = = ' _ ' ) | | isdigit ( value [ i - 1 ] ) )
{
result . push_back ( value [ i ] ) ;
}
else
{
result . push_back ( tolower ( value [ i ] ) ) ;
}
}
}
return result ;
}
std : : string toUpperCase ( std : : string const & name )
{
assert ( isupper ( name . front ( ) ) ) ;
std : : string convertedName ;
for ( size_t i = 0 ; i < name . length ( ) ; i + + )
{
if ( isupper ( name [ i ] ) & & ( ( i = = 0 ) | | islower ( name [ i - 1 ] ) | | isdigit ( name [ i - 1 ] ) ) )
{
convertedName . push_back ( ' _ ' ) ;
}
convertedName . push_back ( toupper ( name [ i ] ) ) ;
}
return convertedName ;
}
2016-02-22 14:27:08 +00:00
void writeCall ( std : : ofstream & ofs , std : : string const & name , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters , size_t specialIndex , std : : string const & specialArgument )
{
std : : map < size_t , size_t > countIndices ;
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
{
countIndices . insert ( std : : make_pair ( it - > second , it - > first ) ) ;
}
if ( ( vectorParameters . size ( ) = = 1 ) & & ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " dataSize/4 " ) )
{
assert ( commandData . arguments [ 3 ] . name = = " dataSize " ) ;
countIndices . insert ( std : : make_pair ( 3 , vectorParameters . begin ( ) - > first ) ) ;
}
assert ( islower ( name [ 0 ] ) ) ;
ofs < < " vk " < < static_cast < char > ( toupper ( name [ 0 ] ) ) < < name . substr ( 1 ) < < " ( " ;
size_t i = 0 ;
if ( commandData . handleCommand )
{
ofs < < " m_ " < < commandData . arguments [ 0 ] . name ;
i + + ;
}
for ( ; i < commandData . arguments . size ( ) ; i + + )
{
if ( 0 < i )
{
ofs < < " , " ;
}
std : : map < size_t , size_t > : : const_iterator it = countIndices . find ( i ) ;
if ( it ! = countIndices . end ( ) )
{
if ( specialIndex = = it - > second )
{
ofs < < " & " < < reduceName ( commandData . arguments [ it - > first ] . name ) ;
}
else
{
ofs < < " static_cast< " < < commandData . arguments [ it - > first ] . pureType < < " >( " < < reduceName ( commandData . arguments [ it - > second ] . name ) < < " .size() ) " ;
if ( commandData . arguments [ it - > second ] . len = = " dataSize/4 " )
{
ofs < < " * 4 " ;
}
}
}
else
{
it = vectorParameters . find ( i ) ;
if ( it ! = vectorParameters . end ( ) )
{
assert ( commandData . arguments [ it - > first ] . type . back ( ) = = ' * ' ) ;
if ( vkTypes . find ( commandData . arguments [ it - > first ] . pureType ) ! = vkTypes . end ( ) )
{
if ( commandData . arguments [ it - > first ] . type . find ( " const " ) ! = std : : string : : npos )
{
ofs < < " reinterpret_cast<const Vk " < < commandData . arguments [ it - > first ] . pureType < < " *>( " < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .data() ) " ;
}
else
{
ofs < < " reinterpret_cast<Vk " < < commandData . arguments [ it - > first ] . pureType < < " *>( " < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .data() ) " ;
}
}
else
{
ofs < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .data() " ;
}
}
else if ( vkTypes . find ( commandData . arguments [ i ] . pureType ) ! = vkTypes . end ( ) )
{
if ( commandData . arguments [ i ] . type . back ( ) = = ' * ' )
{
if ( commandData . arguments [ i ] . type . find ( " const " ) ! = std : : string : : npos )
{
ofs < < " reinterpret_cast<const Vk " < < commandData . arguments [ i ] . pureType < < " *>( & " < < reduceName ( commandData . arguments [ i ] . name ) < < " ) " ;
}
else
{
ofs < < " reinterpret_cast<Vk " < < commandData . arguments [ i ] . pureType < < " *>( & " < < reduceName ( commandData . arguments [ i ] . name ) < < " ) " ;
}
}
else
{
ofs < < " static_cast<Vk " < < commandData . arguments [ i ] . pureType < < " >( " < < commandData . arguments [ i ] . name < < " ) " ;
}
}
else
{
if ( commandData . arguments [ i ] . type . back ( ) = = ' * ' )
{
if ( commandData . arguments [ i ] . type . find ( " const " ) ! = std : : string : : npos )
{
assert ( commandData . arguments [ i ] . type . find ( " char " ) ! = std : : string : : npos ) ;
ofs < < reduceName ( commandData . arguments [ i ] . name ) < < " .c_str() " ;
}
else
{
assert ( commandData . arguments [ i ] . type . find ( " char " ) = = std : : string : : npos ) ;
ofs < < " & " < < reduceName ( commandData . arguments [ i ] . name ) ;
}
}
else
{
ofs < < commandData . arguments [ i ] . name ;
}
}
}
}
ofs < < " ) " ;
}
void writeExceptionCheck ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : vector < std : : string > const & successCodes )
{
if ( successCodes . size ( ) = = 1 )
{
assert ( successCodes . front ( ) = = " VK_SUCCESS " ) ;
ofs < < indentation < < " if ( result != Result::eVkSuccess ) " < < std : : endl ;
}
else
{
assert ( successCodes . size ( ) = = 2 ) ;
ofs < < indentation < < " if ( ( result != Result::e " < < toCamelCase ( successCodes [ 0 ] ) < < " ) && ( result != Result::e " < < toCamelCase ( successCodes [ 1 ] ) < < " ) ) " < < std : : endl ;
}
ofs < < indentation < < " { " < < std : : endl
< < indentation < < " throw Exception( result, \" vk:: " ;
if ( ! className . empty ( ) )
{
ofs < < className < < " :: " ;
}
ofs < < functionName < < " \" ); " < < std : : endl
< < indentation < < " } " < < std : : endl ;
}
void writeFunctionHeader ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & returnType , std : : string const & name , CommandData const & commandData , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters )
{
std : : set < size_t > skippedArguments ;
for ( std : : map < size_t , size_t > : : const_iterator it = vectorParameters . begin ( ) ; it ! = vectorParameters . end ( ) ; + + it )
{
skippedArguments . insert ( it - > second ) ;
}
if ( ( vectorParameters . size ( ) = = 1 ) & & ( commandData . arguments [ vectorParameters . begin ( ) - > first ] . len = = " dataSize/4 " ) )
{
assert ( commandData . arguments [ 3 ] . name = = " dataSize " ) ;
skippedArguments . insert ( 3 ) ;
}
if ( commandData . successCodes . size ( ) < 2 )
{
skippedArguments . insert ( returnIndex ) ;
}
ofs < < indentation ;
if ( ! commandData . handleCommand )
{
ofs < < " inline " ;
}
ofs < < returnType < < " " < < name < < " ( " ;
bool argEncountered = false ;
for ( size_t i = commandData . handleCommand ? 1 : 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( skippedArguments . find ( i ) = = skippedArguments . end ( ) )
{
if ( argEncountered )
{
ofs < < " , " ;
}
if ( vectorParameters . find ( i ) = = vectorParameters . end ( ) )
{
size_t pos = commandData . arguments [ i ] . type . find ( ' * ' ) ;
if ( pos = = std : : string : : npos )
{
ofs < < commandData . arguments [ i ] . type < < " " < < commandData . arguments [ i ] . name ;
if ( ! commandData . arguments [ i ] . arraySize . empty ( ) )
{
ofs < < " [ " < < commandData . arguments [ i ] . arraySize < < " ] " ;
}
}
else
{
std : : string type = commandData . arguments [ i ] . type ;
if ( type . find ( " char " ) ! = std : : string : : npos )
{
type = " std::string const& " ;
}
else
{
assert ( type [ pos ] = = ' * ' ) ;
type [ pos ] = ' & ' ;
}
ofs < < type < < " " < < reduceName ( commandData . arguments [ i ] . name ) ;
}
}
else
{
if ( commandData . arguments [ i ] . pureType = = " char " )
{
ofs < < " std::string " ;
}
else if ( commandData . arguments [ i ] . pureType = = " void " )
{
ofs < < " std::vector<uint8_t> " ;
}
else
{
ofs < < " std::vector< " < < commandData . arguments [ i ] . pureType < < " > " ;
}
if ( commandData . arguments [ i ] . type . find ( " const " ) ! = std : : string : : npos )
{
ofs < < " const " ;
}
ofs < < " & " < < reduceName ( commandData . arguments [ i ] . name ) ;
}
argEncountered = true ;
}
}
ofs < < " ) " ;
if ( commandData . handleCommand )
{
ofs < < " const " ;
}
ofs < < std : : endl ;
}
2016-02-16 14:07:55 +00:00
void writeMemberData ( std : : ofstream & ofs , MemberData const & memberData , std : : set < std : : string > const & vkTypes )
{
if ( vkTypes . find ( memberData . pureType ) ! = vkTypes . end ( ) )
{
if ( memberData . type . back ( ) = = ' * ' )
{
ofs < < " reinterpret_cast< " ;
if ( memberData . type . find ( " const " ) = = 0 )
{
ofs < < " const " ;
}
2016-02-22 14:27:08 +00:00
ofs < < " Vk " < < memberData . pureType < < ' * ' ;
2016-02-16 14:07:55 +00:00
}
else
{
ofs < < " static_cast<Vk " < < memberData . pureType ;
}
ofs < < " >( " < < memberData . name < < " ) " ;
}
else
{
ofs < < memberData . name ;
}
}
void writeStructConstructor ( std : : ofstream & ofs , std : : string const & name , std : : string const & memberName , StructData const & structData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , std : : string > const & defaultValues )
{
// check if there is a member element with no default available
bool noDefault = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) & & ! noDefault ; i + + )
{
std : : map < std : : string , std : : string > : : const_iterator it = defaultValues . find ( structData . members [ i ] . pureType ) ;
assert ( it ! = defaultValues . end ( ) ) ;
noDefault = it - > second . empty ( ) ;
}
if ( ! noDefault )
{
// if there's a default for all memeber, provide a default constructor
ofs < < " " < < name < < " () " < < std : : endl
< < " : " < < name < < " ( " ;
bool listedArgument = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( listedArgument )
{
ofs < < " , " ;
}
if ( ( structData . members [ i ] . name ! = " pNext " ) & & ( structData . members [ i ] . name ! = " sType " ) )
{
if ( structData . members [ i ] . type . back ( ) = = ' * ' )
{
ofs < < " nullptr " ;
}
else
{
std : : map < std : : string , std : : string > : : const_iterator it = defaultValues . find ( structData . members [ i ] . pureType ) ;
assert ( ( it ! = defaultValues . end ( ) ) & & ! it - > second . empty ( ) ) ;
if ( structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < it - > second ;
}
else
{
ofs < < " { " < < it - > second < < " } " ;
}
}
listedArgument = true ;
}
}
ofs < < " ) " < < std : : endl
< < " {} " < < std : : endl
< < std : : endl ;
}
// the constructor with all the elements as arguments
ofs < < " " < < name < < " ( " ;
std : : vector < std : : string > noDefaultArgs , defaultArgs ;
bool listedArgument = false ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( listedArgument )
{
ofs < < " , " ;
}
if ( ( structData . members [ i ] . name ! = " pNext " ) & & ( structData . members [ i ] . name ! = " sType " ) )
{
if ( structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < structData . members [ i ] . type + " " + structData . members [ i ] . name ;
}
else
{
ofs < < " std::array< " + structData . members [ i ] . type + " , " + structData . members [ i ] . arraySize + " > const& " + structData . members [ i ] . name ;
}
listedArgument = true ;
}
}
ofs < < " ) " < < std : : endl ;
// now the body of the constructor, copying over data from argument list into wrapped struct
ofs < < " { " < < std : : endl ;
for ( size_t i = 0 ; i < structData . members . size ( ) ; i + + )
{
if ( ! structData . members [ i ] . arraySize . empty ( ) )
{
ofs < < " memcpy( & " < < memberName < < " . " < < structData . members [ i ] . name < < " , " < < structData . members [ i ] . name < < " .data(), " < < structData . members [ i ] . arraySize < < " * sizeof( " < < structData . members [ i ] . type < < " ) ) " ;
}
else
{
ofs < < " " < < memberName < < " . " < < structData . members [ i ] . name < < " = " ;
if ( structData . members [ i ] . name = = " pNext " )
{
ofs < < " nullptr " ;
}
else if ( structData . members [ i ] . name = = " sType " )
{
2016-02-22 14:27:08 +00:00
// HACK: we need to read <enum extends="VkStructureType"> here for the correct name. In this case the 'generic' rule to create the enums doesn't work
2016-02-16 14:07:55 +00:00
if ( name = = " DebugReportCallbackCreateInfoEXT " )
{
ofs < < " VK_STRUCTURE_TYPE_DEBUG_REPORT_CREATE_INFO_EXT " ;
}
else
{
ofs < < " VK_STRUCTURE_TYPE " < < toUpperCase ( name ) ;
}
}
else
{
writeMemberData ( ofs , structData . members [ i ] , vkTypes ) ;
}
}
ofs < < " ; " < < std : : endl ;
}
ofs < < " } " < < std : : endl
< < std : : endl ;
}
void writeStructGetter ( std : : ofstream & ofs , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes )
{
ofs < < " " ;
if ( memberData . type . back ( ) = = ' * ' )
{
if ( memberData . type . find ( " const " ) ! = 0 )
{
ofs < < " const " ;
}
ofs < < memberData . type ;
}
else
{
2016-02-22 14:27:08 +00:00
ofs < < " const " < < memberData . type < < ( memberData . arraySize . empty ( ) ? ' & ' : ' * ' ) ;
2016-02-16 14:07:55 +00:00
}
ofs < < " " < < memberData . name < < " () const " < < std : : endl
< < " { " < < std : : endl
< < " return " ;
if ( ! memberData . arraySize . empty ( ) )
{
ofs < < " reinterpret_cast<const " < < memberData . type < < " *>( " < < memberName < < " . " < < memberData . name < < " ) " ;
}
else if ( memberData . type . back ( ) = = ' * ' )
{
ofs < < " reinterpret_cast< " < < memberData . type < < " >( " < < memberName < < " . " < < memberData . name < < " ) " ;
}
else if ( vkTypes . find ( memberData . pureType ) ! = vkTypes . end ( ) )
{
ofs < < " reinterpret_cast<const " < < memberData . pureType < < " &>( " < < memberName < < " . " < < memberData . name < < " ) " ;
}
else
{
ofs < < memberName < < " . " < < memberData . name ;
}
ofs < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
}
void writeStructSetter ( std : : ofstream & ofs , std : : string const & name , MemberData const & memberData , std : : string const & memberName , std : : set < std : : string > const & vkTypes )
{
ofs < < " " < < name < < " & " < < memberData . name < < " ( " ;
if ( memberData . arraySize . empty ( ) )
{
ofs < < memberData . type < < " " ;
}
else
{
ofs < < " std::array< " < < memberData . type < < " , " < < memberData . arraySize < < " > " ;
}
ofs < < memberData . name < < " ) " < < std : : endl
< < " { " < < std : : endl ;
if ( ! memberData . arraySize . empty ( ) )
{
ofs < < " memcpy( & " < < memberName < < " . " < < memberData . name < < " , " < < memberData . name < < " .data(), " < < memberData . arraySize < < " * sizeof( " < < memberData . type < < " ) ) " ;
}
else
{
ofs < < " " < < memberName < < " . " < < memberData . name < < " = " ;
writeMemberData ( ofs , memberData , vkTypes ) ;
}
ofs < < " ; " < < std : : endl
< < " return *this; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
}
void writeTypeCommand ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , commandData . protect ) ;
2016-02-16 14:07:55 +00:00
writeTypeCommandStandard ( ofs , dependencyData , commandData , vkTypes ) ;
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , commandData . protect ) ;
if ( ! commandData . handleCommand )
{
ofs < < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl ;
writeTypeCommandEnhanced ( ofs , " " , " " , dependencyData , commandData , vkTypes ) ;
ofs < < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl ;
}
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , commandData . protect ) ;
std : : map < size_t , size_t > vectorParameters = getVectorParameters ( commandData ) ;
size_t returnIndex = findReturnIndex ( commandData , vectorParameters ) ;
std : : map < size_t , size_t > : : const_iterator returnVector = vectorParameters . find ( returnIndex ) ;
std : : string returnType = determineReturnType ( commandData , returnIndex , returnVector ! = vectorParameters . end ( ) ) ;
std : : string functionName = determineFunctionName ( dependencyData . name , commandData ) ;
writeFunctionHeader ( ofs , indentation , returnType , functionName , commandData , returnIndex , vectorParameters ) ;
if ( commandData . twoStep )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
writeTypeCommandEnhancedTwoStep ( ofs , indentation , className , functionName , returnType , dependencyData , commandData , vkTypes , returnIndex , vectorParameters ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
else
{
writeTypeCommandEnhancedSingleStep ( ofs , indentation , className , functionName , returnType , dependencyData , commandData , vkTypes , returnIndex , vectorParameters ) ;
}
leaveProtect ( ofs , commandData . protect ) ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
void writeTypeCommandEnhanced ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , std : : map < size_t , size_t > const & vectorParameters )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < indentation < < " { " < < std : : endl ;
if ( vectorParameters . size ( ) = = 2 )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : map < size_t , size_t > : : const_iterator it1 = vectorParameters . begin ( ) ;
std : : map < size_t , size_t > : : const_iterator it0 = it1 + + ;
if ( it0 - > second = = it1 - > second )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < indentation < < " if ( " < < reduceName ( commandData . arguments [ it0 - > first ] . name ) < < " .size() != " < < reduceName ( commandData . arguments [ it1 - > first ] . name ) < < " .size() ) " < < std : : endl
< < indentation < < " { " < < std : : endl
< < indentation < < " throw std::logic_error( \" vk:: " < < className < < " :: " < < functionName < < " : " < < reduceName ( commandData . arguments [ it0 - > first ] . name ) < < " .size() != " < < reduceName ( commandData . arguments [ it1 - > first ] . name ) < < " .size() \" ); " < < std : : endl
< < indentation < < " } " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
}
ofs < < indentation < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " Result result = static_cast<Result>( " ;
}
else if ( commandData . returnType ! = " void " )
{
ofs < < " return " ;
}
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters ) ;
if ( commandData . returnType = = " Result " )
{
ofs < < " ); " < < std : : endl ;
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
if ( 1 < commandData . successCodes . size ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < indentation < < " return result; " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
}
else
{
ofs < < " ; " < < std : : endl ;
}
ofs < < indentation < < " } " < < std : : endl ;
}
2016-02-16 14:07:55 +00:00
2016-02-22 14:27:08 +00:00
void writeTypeCommandEnhancedSingleStep ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters )
{
if ( 1 < commandData . successCodes . size ( ) )
{
returnIndex = ~ 0 ;
}
if ( ( commandData . returnType = = " Result " ) | | ( commandData . returnType = = " void " ) )
{
// is allowed to return some input parameter
if ( returnIndex = = ~ 0 )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
//if ((commandData.returnType == "Result") || hasPointerArguments(commandData))
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
writeTypeCommandEnhanced ( ofs , indentation , className , functionName , dependencyData , commandData , vkTypes , vectorParameters ) ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-22 14:27:08 +00:00
else
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : map < size_t , size_t > : : const_iterator it = vectorParameters . find ( returnIndex ) ;
if ( it = = vectorParameters . end ( ) | | ( it - > second = = ~ 0 ) | | ( ( vectorParameters . size ( ) = = 2 ) & & ( vectorParameters . begin ( ) - > second = = ( + + vectorParameters . begin ( ) ) - > second ) ) )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
writeTypeCommandEnhancedReplaceReturn ( ofs , indentation , className , functionName , returnType , dependencyData , commandData , vkTypes , returnIndex , vectorParameters ) ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-02-22 14:27:08 +00:00
assert ( false ) ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-22 14:27:08 +00:00
}
else
{
writeTypeCommandEnhanced ( ofs , indentation , className , functionName , dependencyData , commandData , vkTypes , std : : map < size_t , size_t > ( ) ) ;
}
}
void writeTypeCommandEnhancedTwoStep ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters )
{
assert ( returnIndex ! = ~ 0 ) ;
std : : map < size_t , size_t > : : const_iterator it = vectorParameters . find ( returnIndex ) ;
assert ( ( it ! = vectorParameters . end ( ) ) & & ( it - > second ! = ~ 0 ) ) ;
2016-02-16 14:07:55 +00:00
2016-02-22 14:27:08 +00:00
ofs < < indentation < < " { " < < std : : endl ;
if ( commandData . successCodes . size ( ) < 2 )
{
ofs < < indentation < < " " < < returnType < < " " < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " ; " < < std : : endl ;
}
ofs < < indentation < < " " < < commandData . arguments [ it - > second ] . pureType < < " " < < reduceName ( commandData . arguments [ it - > second ] . name ) < < " ; " < < std : : endl
< < indentation < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " Result result = static_cast<Result>( " ;
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters , returnIndex , " nullptr " ) ;
ofs < < " ); " < < std : : endl ;
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
}
else
{
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters , returnIndex , " nullptr " ) ;
ofs < < " ; " < < std : : endl ;
}
ofs < < indentation < < " " < < reduceName ( commandData . arguments [ it - > first ] . name ) < < " .resize( " < < reduceName ( commandData . arguments [ it - > second ] . name ) < < " ); " < < std : : endl
< < indentation < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " result = static_cast<Result>( " ;
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters , returnIndex , reduceName ( commandData . arguments [ returnIndex ] . name ) + " .data() " ) ;
ofs < < " ); " < < std : : endl ;
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
}
else
{
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters , returnIndex , reduceName ( commandData . arguments [ returnIndex ] . name ) + " .data() " ) ;
ofs < < " ; " < < std : : endl ;
}
if ( commandData . successCodes . size ( ) < 2 )
{
ofs < < indentation < < " return std::move( " < < reduceName ( commandData . arguments [ returnIndex ] . name ) < < " ); " < < std : : endl ;
}
else if ( commandData . returnType = = " Result " )
{
ofs < < indentation < < " return result; " < < std : : endl ;
}
ofs < < indentation < < " } " < < std : : endl ;
}
void writeTypeCommandEnhancedReplaceReturn ( std : : ofstream & ofs , std : : string const & indentation , std : : string const & className , std : : string const & functionName , std : : string const & returnType , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes , size_t returnIndex , std : : map < size_t , size_t > const & vectorParameters )
{
assert ( returnIndex < commandData . arguments . size ( ) ) ;
ofs < < indentation < < " { " < < std : : endl
< < indentation < < " " < < returnType < < " " < < reduceName ( commandData . arguments [ returnIndex ] . name ) ;
std : : map < size_t , size_t > : : const_iterator it = vectorParameters . find ( returnIndex ) ;
if ( it ! = vectorParameters . end ( ) )
{
std : : string size ;
if ( ( it - > second = = ~ 0 ) & & ! commandData . arguments [ returnIndex ] . len . empty ( ) )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
size = reduceName ( commandData . arguments [ returnIndex ] . len ) ;
size_t pos = size . find ( " -> " ) ;
assert ( pos ! = std : : string : : npos ) ;
size . replace ( pos , 2 , " . " ) ;
size + = " () " ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-02-22 14:27:08 +00:00
for ( std : : map < size_t , size_t > : : const_iterator sit = vectorParameters . begin ( ) ; sit ! = vectorParameters . end ( ) ; + + sit )
{
if ( ( sit - > first ! = returnIndex ) & & ( sit - > second = = it - > second ) )
{
size = reduceName ( commandData . arguments [ sit - > first ] . name ) + " .size() " ;
break ;
}
}
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
assert ( ! size . empty ( ) ) ;
ofs < < " ( " < < size < < " ) " ;
}
ofs < < " ; " < < std : : endl
< < indentation < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " Result result = static_cast<Result>( " ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
writeCall ( ofs , dependencyData . name , commandData , vkTypes , vectorParameters ) ;
if ( commandData . returnType = = " Result " )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl ;
if ( commandData . returnType = = " Result " )
{
writeExceptionCheck ( ofs , indentation , className , functionName , commandData . successCodes ) ;
}
ofs < < indentation < < " return " ;
if ( it ! = vectorParameters . end ( ) )
{
ofs < < " std::move( " ;
}
ofs < < reduceName ( commandData . arguments [ returnIndex ] . name ) ;
if ( it ! = vectorParameters . end ( ) )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl
< < indentation < < " } " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
void writeTypeCommandStandard ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : set < std : : string > const & vkTypes )
{
ofs < < " inline " < < commandData . returnType < < " " < < dependencyData . name < < " ( " ;
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( 0 < i )
{
ofs < < " , " ;
}
ofs < < commandData . arguments [ i ] . type < < " " < < commandData . arguments [ i ] . name ;
if ( ! commandData . arguments [ i ] . arraySize . empty ( ) )
{
ofs < < " [ " < < commandData . arguments [ i ] . arraySize < < " ] " ;
}
}
ofs < < " ) " < < std : : endl
< < " { " < < std : : endl
< < " " ;
bool castReturn = false ;
if ( commandData . returnType ! = " void " )
{
ofs < < " return " ;
castReturn = ( vkTypes . find ( commandData . returnType ) ! = vkTypes . end ( ) ) ;
if ( castReturn )
{
ofs < < " static_cast< " < < commandData . returnType < < " >( " ;
}
}
std : : string callName ( dependencyData . name ) ;
assert ( islower ( callName [ 0 ] ) ) ;
callName [ 0 ] = toupper ( callName [ 0 ] ) ;
ofs < < " vk " < < callName < < " ( " ;
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
if ( 0 < i )
{
ofs < < " , " ;
}
writeMemberData ( ofs , commandData . arguments [ i ] , vkTypes ) ;
}
ofs < < " ) " ;
if ( castReturn )
{
ofs < < " ) " ;
}
ofs < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
}
2016-02-22 14:27:08 +00:00
void writeTypeCommandComplexBody ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : map < std : : string , std : : string > const & nameMap , std : : map < size_t , size_t > const & vectorParameters , std : : set < size_t > const & argIndices , size_t complexIndex , size_t returnIndex )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
if ( returnIndex ! = ~ 0 )
{
assert ( vectorParameters . find ( returnIndex ) ! = vectorParameters . end ( ) ) ;
ofs < < " std::vector< " < < commandData . arguments [ returnIndex ] . pureType < < " > " < < reduceName ( commandData . arguments [ returnIndex ] . name ) < < " ; " < < std : : endl ;
}
std : : map < size_t , size_t > : : const_iterator vpit = vectorParameters . find ( complexIndex ) ;
assert ( ( vpit ! = vectorParameters . end ( ) ) & & ( vpit - > second ! = ~ 0 ) ) ;
ofs < < " " < < commandData . arguments [ vpit - > second ] . pureType < < " " < < nameMap . find ( commandData . arguments [ vpit - > second ] . name ) - > second < < " = 0; " < < std : : endl ;
2016-02-16 14:07:55 +00:00
ofs < < " " ;
2016-02-22 14:27:08 +00:00
2016-02-16 14:07:55 +00:00
assert ( ( commandData . returnType = = " void " ) | | ( commandData . returnType = = " Result " ) ) ;
if ( commandData . returnType = = " Result " )
{
ofs < < commandData . returnType < < " result = " ;
}
ofs < < dependencyData . name < < " ( " ;
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
auto argit = nameMap . find ( commandData . arguments [ i ] . name ) ;
if ( 0 < i )
{
ofs < < " , " ;
}
2016-02-22 14:27:08 +00:00
if ( i = = vpit - > first )
2016-02-16 14:07:55 +00:00
{
ofs < < " nullptr " ;
}
2016-02-22 14:27:08 +00:00
else if ( i = = vpit - > second )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < ' & ' < < argit - > second ;
2016-02-16 14:07:55 +00:00
}
else if ( argIndices . find ( i ) ! = argIndices . end ( ) )
{
ofs < < argit - > second < < " .data() " ;
}
else
{
ofs < < argit - > second ;
}
}
ofs < < " ); " < < std : : endl ;
if ( commandData . returnType = = " Result " )
{
ofs < < " if ( result == Result::eVkSuccess ) " < < std : : endl
< < " { " < < std : : endl
< < " " ;
}
ofs < < " " ;
if ( returnIndex = = ~ 0 )
{
2016-02-22 14:27:08 +00:00
ofs < < nameMap . find ( commandData . arguments [ vpit - > first ] . name ) - > second < < " .resize( " < < nameMap . find ( commandData . arguments [ vpit - > second ] . name ) - > second < < " ); " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
else
{
2016-02-22 14:27:08 +00:00
ofs < < " std::vector< " < < commandData . arguments [ vpit - > first ] . pureType < < " > " < < nameMap . find ( commandData . arguments [ vpit - > first ] . name ) - > second < < " ( " < < nameMap . find ( commandData . arguments [ vpit - > second ] . name ) - > second < < " ); " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
ofs < < " " ;
if ( commandData . returnType = = " Result " )
{
ofs < < " result = " ;
}
ofs < < dependencyData . name < < " ( " ;
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
auto argit = nameMap . find ( commandData . arguments [ i ] . name ) ;
if ( 0 < i )
{
ofs < < " , " ;
}
2016-02-22 14:27:08 +00:00
if ( i = = vpit - > first )
2016-02-16 14:07:55 +00:00
{
ofs < < argit - > second < < " .data() " ;
}
2016-02-22 14:27:08 +00:00
else if ( i = = vpit - > second )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < ' & ' < < argit - > second ;
2016-02-16 14:07:55 +00:00
}
else if ( argIndices . find ( i ) ! = argIndices . end ( ) )
{
ofs < < argit - > second < < " .data() " ;
}
else
{
ofs < < argit - > second ;
}
}
ofs < < " ); " < < std : : endl ;
2016-02-22 14:27:08 +00:00
if ( returnIndex ! = ~ 0 )
2016-02-16 14:07:55 +00:00
{
ofs < < " } " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " return std::move( " < < nameMap . find ( commandData . arguments [ vpit - > first ] . name ) - > second < < " ); " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
else if ( commandData . returnType = = " Result " )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < " } " < < std : : endl
< < " return result; " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
}
2016-02-22 14:27:08 +00:00
void writeTypeCommandSimpleBody ( std : : ofstream & ofs , DependencyData const & dependencyData , CommandData const & commandData , std : : map < std : : string , std : : string > const & nameMap , std : : map < size_t , size_t > const & vectorParameters , std : : set < size_t > const & argIndices , std : : map < size_t , std : : vector < size_t > > const & sizeIndices , size_t returnIndex )
2016-02-16 14:07:55 +00:00
{
for ( std : : map < size_t , std : : vector < size_t > > : : const_iterator it = sizeIndices . begin ( ) ; it ! = sizeIndices . end ( ) ; + + it )
{
if ( 1 < it - > second . size ( ) )
{
assert ( it - > second . size ( ) = = 2 ) ;
ofs < < " assert( " < < nameMap . find ( commandData . arguments [ it - > second [ 0 ] ] . name ) - > second < < " .size() <= " < < nameMap . find ( commandData . arguments [ it - > second [ 1 ] ] . name ) - > second < < " .size() ); " < < std : : endl ;
}
}
2016-02-22 14:27:08 +00:00
if ( returnIndex ! = ~ 0 )
{
assert ( vectorParameters . find ( returnIndex ) = = vectorParameters . end ( ) ) ;
ofs < < " " < < commandData . arguments [ returnIndex ] . pureType < < " " < < reduceName ( commandData . arguments [ returnIndex ] . name ) < < " ; " < < std : : endl ;
}
2016-02-16 14:07:55 +00:00
ofs < < " " ;
if ( commandData . returnType ! = " void " )
{
ofs < < " return " ;
}
ofs < < dependencyData . name < < " ( " ;
for ( size_t i = 0 ; i < commandData . arguments . size ( ) ; i + + )
{
auto argit = nameMap . find ( commandData . arguments [ i ] . name ) ;
if ( 0 < i )
{
ofs < < " , " ;
}
if ( argIndices . find ( i ) ! = argIndices . end ( ) )
{
ofs < < argit - > second < < " .data() " ;
}
else
{
std : : map < size_t , std : : vector < size_t > > : : const_iterator it = sizeIndices . find ( i ) ;
if ( it ! = sizeIndices . end ( ) )
{
ofs < < " static_cast< " < < commandData . arguments [ i ] . type < < " >( " < < nameMap . find ( commandData . arguments [ it - > second . front ( ) ] . name ) - > second < < " .size() ) " ;
}
else if ( nameMap . find ( commandData . arguments [ i ] . name ) - > second ! = commandData . arguments [ i ] . name )
{
2016-02-22 14:27:08 +00:00
ofs < < ' & ' < < argit - > second ;
2016-02-16 14:07:55 +00:00
}
else
{
ofs < < argit - > second ;
}
}
}
ofs < < " ); " < < std : : endl ;
}
void writeTypeEnum ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-16 14:07:55 +00:00
ofs < < " enum class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl ;
for ( size_t i = 0 ; i < enumData . members . size ( ) ; i + + )
{
ofs < < " " < < enumData . members [ i ] . name < < " = " < < enumData . members [ i ] . value ;
if ( i < enumData . members . size ( ) - 1 )
{
ofs < < " , " ;
}
ofs < < std : : endl ;
}
2016-02-22 14:27:08 +00:00
ofs < < " }; " < < std : : endl ;
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-18 11:12:55 +00:00
void writeEnumToString ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-18 11:12:55 +00:00
ofs < < " static const char * getString( " < < dependencyData . name < < " value) " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " { " < < std : : endl ;
if ( enumData . members . empty ( ) )
2016-02-18 11:12:55 +00:00
{
2016-02-22 14:27:08 +00:00
ofs < < " return \" \" ; " < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
2016-02-22 14:27:08 +00:00
else
{
ofs < < " switch (value) " < < std : : endl
< < " { " < < std : : endl ;
for ( auto itMember = enumData . members . begin ( ) ; itMember ! = enumData . members . end ( ) ; + + itMember )
{
ofs < < " case " < < dependencyData . name < < " :: " < < itMember - > name < < " : return \" " < < itMember - > name . substr ( 1 ) < < " \" ; " < < std : : endl ;
}
ofs < < " default: return \" unknown \" ; " < < std : : endl
< < " } " < < std : : endl ;
}
ofs < < " } " < < std : : endl ;
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
void writeFlagsTostring ( std : : ofstream & ofs , DependencyData const & dependencyData , EnumData const & enumData )
{
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , enumData . protect ) ;
2016-02-18 11:12:55 +00:00
std : : string enumPrefix = " vk:: " + * dependencyData . dependencies . begin ( ) + " :: " ;
ofs < < " static std::string getString( " < < dependencyData . name < < " value) " < < std : : endl
< < " { " < < std : : endl
< < " if (!value) return std::string(); " < < std : : endl
< < " std::string result; " < < std : : endl ;
for ( auto itMember = enumData . members . begin ( ) ; itMember ! = enumData . members . end ( ) ; + + itMember )
{
ofs < < " if (value & " < < enumPrefix + itMember - > name < < " ) result += \" " < < itMember - > name . substr ( 1 ) < < " | \" ; " < < std : : endl ;
}
ofs < < " return result.substr(0, result.size() - 3); " < < std : : endl
< < " } " < < std : : endl ;
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , enumData . protect ) ;
ofs < < std : : endl ;
2016-02-18 11:12:55 +00:00
}
void writeEnumsToString ( std : : ofstream & ofs , std : : vector < DependencyData > const & dependencyData , std : : map < std : : string , EnumData > const & enums )
{
for ( auto it = dependencyData . begin ( ) ; it ! = dependencyData . end ( ) ; + + it )
{
switch ( it - > category )
{
case DependencyData : : Category : : ENUM :
assert ( enums . find ( it - > name ) ! = enums . end ( ) ) ;
writeEnumToString ( ofs , * it , enums . find ( it - > name ) - > second ) ;
break ;
case DependencyData : : Category : : FLAGS :
writeFlagsTostring ( ofs , * it , enums . find ( * it - > dependencies . begin ( ) ) - > second ) ;
break ;
}
}
}
2016-02-22 14:27:08 +00:00
void writeTypeFlags ( std : : ofstream & ofs , DependencyData const & dependencyData , FlagData const & flagData )
2016-02-16 14:07:55 +00:00
{
assert ( dependencyData . dependencies . size ( ) = = 1 ) ;
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , flagData . protect ) ;
2016-02-17 16:45:27 +00:00
ofs < < " typedef Flags< " < < * dependencyData . dependencies . begin ( ) < < " , Vk " < < dependencyData . name < < " > " < < dependencyData . name < < " ; " < < std : : endl
2016-02-16 14:07:55 +00:00
< < std : : endl
< < " inline " < < dependencyData . name < < " operator|( " < < * dependencyData . dependencies . begin ( ) < < " bit0, " < < * dependencyData . dependencies . begin ( ) < < " bit1 ) " < < std : : endl
< < " { " < < std : : endl
< < " return " < < dependencyData . name < < " ( bit0 ) | bit1; " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " } " < < std : : endl ;
leaveProtect ( ofs , flagData . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
2016-02-22 14:27:08 +00:00
void writeTypeHandle ( std : : ofstream & ofs , DependencyData const & dependencyData , HandleData const & handle , std : : map < std : : string , CommandData > const & commands , std : : vector < DependencyData > const & dependencies , std : : set < std : : string > const & vkTypes )
2016-02-16 14:07:55 +00:00
{
2016-02-22 14:27:08 +00:00
std : : string memberName = dependencyData . name ;
assert ( isupper ( memberName [ 0 ] ) ) ;
memberName [ 0 ] = tolower ( memberName [ 0 ] ) ;
ofs < < " class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl
< < " " < < dependencyData . name < < " () " < < std : : endl
< < " : m_ " < < memberName < < " (nullptr) " < < std : : endl
< < " {} " < < std : : endl
< < std : : endl ;
if ( ! handle . commands . empty ( ) )
{
ofs < < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl ;
for ( size_t i = 0 ; i < handle . commands . size ( ) ; i + + )
{
std : : string commandName = handle . commands [ i ] ;
std : : map < std : : string , CommandData > : : const_iterator cit = commands . find ( commandName ) ;
assert ( ( cit ! = commands . end ( ) ) & & cit - > second . handleCommand ) ;
std : : vector < DependencyData > : : const_iterator dep = std : : find_if ( dependencies . begin ( ) , dependencies . end ( ) , [ commandName ] ( DependencyData const & dd ) { return dd . name = = commandName ; } ) ;
assert ( dep ! = dependencies . end ( ) ) ;
writeTypeCommandEnhanced ( ofs , " " , dependencyData . name , * dep , cit - > second , vkTypes ) ;
if ( i < handle . commands . size ( ) - 1 )
{
ofs < < std : : endl ;
}
}
ofs < < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl
< < std : : endl ;
}
ofs < < " explicit operator Vk " < < dependencyData . name < < " () const " < < std : : endl
< < " { " < < std : : endl
< < " return m_ " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " private: " < < std : : endl
< < " Vk " < < dependencyData . name < < " m_ " < < memberName < < " ; " < < std : : endl
< < " }; " < < std : : endl
# if 1
< < " static_assert( sizeof( " < < dependencyData . name < < " ) == sizeof( Vk " < < dependencyData . name < < " ), \" handle and wrapper have different size! \" ); " < < std : : endl
# endif
< < std : : endl ;
2016-02-16 14:07:55 +00:00
}
void writeTypeScalar ( std : : ofstream & ofs , DependencyData const & dependencyData )
{
assert ( dependencyData . dependencies . size ( ) = = 1 ) ;
ofs < < " typedef " < < * dependencyData . dependencies . begin ( ) < < " " < < dependencyData . name < < " ; " < < std : : endl ;
}
void writeTypeStruct ( std : : ofstream & ofs , DependencyData const & dependencyData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues )
{
std : : map < std : : string , StructData > : : const_iterator it = structs . find ( dependencyData . name ) ;
assert ( it ! = structs . end ( ) ) ;
2016-02-22 14:27:08 +00:00
enterProtect ( ofs , it - > second . protect ) ;
2016-02-16 14:07:55 +00:00
ofs < < " class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl ;
std : : string memberName ( dependencyData . name ) ;
assert ( isupper ( memberName [ 0 ] ) ) ;
memberName [ 0 ] = tolower ( memberName [ 0 ] ) ;
memberName = " m_ " + memberName ;
// only structs that are not returnedOnly get a constructor!
if ( ! it - > second . returnedOnly )
{
writeStructConstructor ( ofs , dependencyData . name , memberName , it - > second , vkTypes , defaultValues ) ;
}
// create the getters and setters
for ( size_t i = 0 ; i < it - > second . members . size ( ) ; i + + )
{
writeStructGetter ( ofs , it - > second . members [ i ] , memberName , vkTypes ) ;
if ( ! it - > second . returnedOnly )
{
writeStructSetter ( ofs , dependencyData . name , it - > second . members [ i ] , memberName , vkTypes ) ;
}
}
// the cast-operator to the wrapped struct, and the struct itself as a private member variable
ofs < < " operator const Vk " < < dependencyData . name < < " &() const " < < std : : endl
< < " { " < < std : : endl
< < " return " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " private: " < < std : : endl
< < " Vk " < < dependencyData . name < < " " < < memberName < < " ; " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " }; " < < std : : endl ;
# if 1
ofs < < " static_assert( sizeof( " < < dependencyData . name < < " ) == sizeof( Vk " < < dependencyData . name < < " ), \" struct and wrapper have different size! \" ); " < < std : : endl ;
2016-02-16 14:07:55 +00:00
# endif
2016-02-22 14:27:08 +00:00
leaveProtect ( ofs , it - > second . protect ) ;
ofs < < std : : endl ;
2016-02-16 14:07:55 +00:00
}
void writeTypeUnion ( std : : ofstream & ofs , DependencyData const & dependencyData , StructData const & unionData , std : : set < std : : string > const & vkTypes , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues )
{
std : : ostringstream oss ;
ofs < < " class " < < dependencyData . name < < std : : endl
< < " { " < < std : : endl
< < " public: " < < std : : endl ;
std : : string memberName ( dependencyData . name ) ;
assert ( isupper ( memberName [ 0 ] ) ) ;
memberName [ 0 ] = tolower ( memberName [ 0 ] ) ;
memberName = " m_ " + memberName ;
for ( size_t i = 0 ; i < unionData . members . size ( ) ; i + + )
{
// one constructor per union element
ofs < < " " < < dependencyData . name < < " ( " ;
if ( unionData . members [ i ] . arraySize . empty ( ) )
{
ofs < < unionData . members [ i ] . type < < " " ;
}
else
{
ofs < < " const std::array< " < < unionData . members [ i ] . type < < " , " < < unionData . members [ i ] . arraySize < < " >& " ;
}
ofs < < unionData . members [ i ] . name ;
// just the very first constructor gets default arguments
if ( i = = 0 )
{
std : : map < std : : string , std : : string > : : const_iterator it = defaultValues . find ( unionData . members [ i ] . pureType ) ;
assert ( it ! = defaultValues . end ( ) ) ;
if ( unionData . members [ i ] . arraySize . empty ( ) )
{
ofs < < " = " < < it - > second ;
}
else
{
ofs < < " = { " < < it - > second < < " } " ;
}
}
ofs < < " ) " < < std : : endl
< < " { " < < std : : endl
< < " " ;
if ( unionData . members [ i ] . arraySize . empty ( ) )
{
ofs < < memberName < < " . " < < unionData . members [ i ] . name < < " = " < < unionData . members [ i ] . name ;
}
else
{
ofs < < " memcpy( & " < < memberName < < " . " < < unionData . members [ i ] . name < < " , " < < unionData . members [ i ] . name < < " .data(), " < < unionData . members [ i ] . arraySize < < " * sizeof( " < < unionData . members [ i ] . type < < " ) ) " ;
}
ofs < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl ;
// one getter/setter per union element
writeStructGetter ( ofs , unionData . members [ i ] , memberName , vkTypes ) ;
writeStructSetter ( ofs , dependencyData . name , unionData . members [ i ] , memberName , vkTypes ) ;
}
ofs < < " operator Vk " < < dependencyData . name < < " const& () const " < < std : : endl
< < " { " < < std : : endl
< < " return " < < memberName < < " ; " < < std : : endl
< < " } " < < std : : endl
< < std : : endl
< < " private: " < < std : : endl
< < " Vk " < < dependencyData . name < < " " < < memberName < < " ; " < < std : : endl
< < " }; " < < std : : endl
< < std : : endl ;
}
2016-02-22 14:27:08 +00:00
void writeTypes ( std : : ofstream & ofs , std : : vector < DependencyData > const & dependencies , std : : map < std : : string , CommandData > const & commands , std : : map < std : : string , EnumData > const & enums , std : : map < std : : string , FlagData > const & flags , std : : map < std : : string , HandleData > const & handles , std : : map < std : : string , StructData > const & structs , std : : map < std : : string , std : : string > const & defaultValues , std : : set < std : : string > const & vkTypes )
2016-02-16 14:07:55 +00:00
{
for ( std : : vector < DependencyData > : : const_iterator it = dependencies . begin ( ) ; it ! = 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 ) ;
break ;
case DependencyData : : Category : : ENUM :
assert ( enums . find ( it - > name ) ! = enums . end ( ) ) ;
writeTypeEnum ( ofs , * it , enums . find ( it - > name ) - > second ) ;
break ;
case DependencyData : : Category : : FLAGS :
2016-02-22 14:27:08 +00:00
assert ( flags . find ( it - > name ) ! = flags . end ( ) ) ;
writeTypeFlags ( ofs , * it , flags . find ( it - > name ) - > second ) ;
2016-02-16 14:07:55 +00:00
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 :
2016-02-22 14:27:08 +00:00
assert ( handles . find ( it - > name ) ! = handles . end ( ) ) ;
writeTypeHandle ( ofs , * it , handles . find ( it - > name ) - > second , commands , dependencies , vkTypes ) ;
2016-02-16 14:07:55 +00:00
break ;
case DependencyData : : Category : : SCALAR :
writeTypeScalar ( ofs , * it ) ;
break ;
case DependencyData : : Category : : STRUCT :
writeTypeStruct ( ofs , * it , vkTypes , structs , defaultValues ) ;
break ;
case DependencyData : : Category : : UNION :
assert ( structs . find ( it - > name ) ! = structs . end ( ) ) ;
writeTypeUnion ( ofs , * it , structs . find ( it - > name ) - > second , vkTypes , structs , defaultValues ) ;
break ;
default :
assert ( false ) ;
break ;
}
}
}
2016-02-22 14:27:08 +00:00
void writeVersionCheck ( std : : ofstream & ofs , std : : string const & version )
2016-02-16 14:07:55 +00:00
{
ofs < < " static_assert( VK_MAKE_VERSION " < < version < < " == VK_API_VERSION, \" Wrong VK_API_VERSION! \" ); " < < std : : endl
< < std : : endl ;
}
int main ( int argc , char * * argv )
{
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLDocument doc ;
2016-02-16 14:07:55 +00:00
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLError error = doc . LoadFile ( argv [ 1 ] ) ;
if ( error ! = tinyxml2 : : XML_SUCCESS )
2016-02-16 14:07:55 +00:00
{
2016-02-17 13:03:05 +00:00
std : : cout < < " VkGenerate: failed to load file " < < argv [ 1 ] < < " . Error code: " < < error < < std : : endl ;
2016-02-16 14:07:55 +00:00
return - 1 ;
}
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * registryElement = doc . FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
assert ( strcmp ( registryElement - > Value ( ) , " registry " ) = = 0 ) ;
assert ( ! registryElement - > NextSiblingElement ( ) ) ;
2016-02-22 14:27:08 +00:00
std : : string version ;
std : : list < DependencyData > dependencies ;
std : : map < std : : string , CommandData > commands ;
std : : map < std : : string , EnumData > enums ;
std : : map < std : : string , FlagData > flags ;
std : : map < std : : string , HandleData > handles ;
std : : map < std : : string , ScalarData > scalars ;
std : : map < std : : string , StructData > structs ;
std : : set < std : : string > vkTypes ;
2016-02-16 14:07:55 +00:00
2016-02-17 13:03:05 +00:00
tinyxml2 : : XMLElement * child = registryElement - > FirstChildElement ( ) ;
2016-02-16 14:07:55 +00:00
do
{
assert ( child - > Value ( ) ) ;
const std : : string value = child - > Value ( ) ;
if ( value = = " commands " )
{
2016-02-22 14:27:08 +00:00
readCommands ( child , dependencies , commands , handles ) ;
2016-02-16 14:07:55 +00:00
}
else if ( value = = " enums " )
{
readEnums ( child , dependencies , enums , vkTypes ) ;
}
else if ( value = = " extensions " )
{
2016-02-22 14:27:08 +00:00
readExtensions ( child , commands , enums , flags , scalars , structs ) ;
2016-02-16 14:07:55 +00:00
}
else if ( value = = " types " )
{
2016-02-22 14:27:08 +00:00
readTypes ( child , version , dependencies , flags , scalars , structs , vkTypes , handles , enums ) ;
2016-02-16 14:07:55 +00:00
}
else
{
assert ( ( value = = " comment " ) | | ( value = = " feature " ) | | ( value = = " tags " ) | | ( value = = " vendorids " ) ) ;
}
} while ( child = child - > NextSiblingElement ( ) ) ;
2016-02-22 14:27:08 +00:00
std : : vector < DependencyData > sortedDependencies ;
sortDependencies ( dependencies , sortedDependencies ) ;
2016-02-16 14:07:55 +00:00
std : : map < std : : string , std : : string > defaultValues ;
2016-02-22 14:27:08 +00:00
createDefaults ( sortedDependencies , enums , defaultValues ) ;
2016-02-16 14:07:55 +00:00
std : : ofstream ofs ( " vk_cpp.h " ) ;
ofs < < licenseHeader < < std : : endl ;
2016-02-17 15:17:23 +00:00
2016-02-22 14:27:08 +00:00
ofs < < std : : endl < < " #ifndef VK_CPP_H_ " < < std : : endl
< < " #define VK_CPP_H_ " < < std : : endl
< < std : : endl ;
2016-02-16 14:07:55 +00:00
ofs < < " #include <array> " < < std : : endl
2016-02-17 18:40:01 +00:00
< < " #include <cassert> " < < std : : endl
2016-02-16 14:07:55 +00:00
< < " #include <cstdint> " < < std : : endl
< < " #include <cstring> " < < std : : endl
< < " #include <vulkan/vulkan.h> " < < std : : endl
< < " #ifdef VKCPP_ENHANCED_MODE " < < std : : endl
< < " # include <vector> " < < std : : endl
2016-02-22 14:27:08 +00:00
< < " #endif /*VKCPP_ENHANCED_MODE*/ " < < std : : endl
2016-02-16 14:07:55 +00:00
< < std : : endl ;
writeVersionCheck ( ofs , version ) ;
ofs < < " namespace vk " < < std : : endl
< < " { " < < std : : endl ;
2016-02-22 14:27:08 +00:00
ofs < < exceptionHeader ;
2016-02-16 14:07:55 +00:00
ofs < < flagsHeader ;
2016-02-22 14:27:08 +00:00
writeTypes ( ofs , sortedDependencies , commands , enums , flags , handles , structs , defaultValues , vkTypes ) ;
writeEnumsToString ( ofs , sortedDependencies , enums ) ;
2016-02-16 14:07:55 +00:00
2016-02-22 14:27:08 +00:00
ofs < < " } // namespace vk " < < std : : endl
< < std : : endl
< < " #endif " < < std : : endl ;
2016-02-16 14:07:55 +00:00
}