| 26 | { |
| 27 | |
| 28 | static string GetExpandedShaderCode(const wchar* path, vector<wstring>& filePaths) |
| 29 | { |
| 30 | for(uint64 i = 0; i < filePaths.size(); ++i) |
| 31 | if(filePaths[i] == path) |
| 32 | throw Exception(L"File \"" + wstring(path) + L" is recursively included"); |
| 33 | |
| 34 | filePaths.push_back(path); |
| 35 | |
| 36 | string fileContents = ReadFileAsString(path); |
| 37 | wstring fileDirectory = GetDirectoryFromFilePath(path); |
| 38 | |
| 39 | // Look for includes |
| 40 | size_t lineStart = 0; |
| 41 | size_t lineEnd = std::string::npos; |
| 42 | while(true) |
| 43 | { |
| 44 | size_t lineEnd = fileContents.find('\n', lineStart); |
| 45 | size_t lineLength = 0; |
| 46 | if(lineEnd == string::npos) |
| 47 | lineLength = string::npos; |
| 48 | else |
| 49 | lineLength = lineEnd - lineStart; |
| 50 | |
| 51 | string line = fileContents.substr(lineStart, lineLength); |
| 52 | if(line.find("#include") == 0) |
| 53 | { |
| 54 | size_t startQuote = line.find('\"'); |
| 55 | size_t endQuote = line.find('\"', startQuote + 1); |
| 56 | string includePath = line.substr(startQuote + 1, endQuote - startQuote - 1); |
| 57 | wstring fullIncludePath = fileDirectory + AnsiToWString(includePath.c_str()); |
| 58 | if(FileExists(fullIncludePath.c_str()) == false) |
| 59 | throw Exception(L"Couldn't find #included file \"" + fullIncludePath + L"\""); |
| 60 | |
| 61 | string includeCode = GetExpandedShaderCode(fullIncludePath.c_str(), filePaths); |
| 62 | fileContents.insert(lineEnd + 1, includeCode); |
| 63 | lineEnd += includeCode.length(); |
| 64 | } |
| 65 | |
| 66 | if(lineEnd == string::npos) |
| 67 | break; |
| 68 | |
| 69 | lineStart = lineEnd + 1; |
| 70 | } |
| 71 | |
| 72 | return fileContents; |
| 73 | } |
| 74 | |
| 75 | static const wstring baseCacheDir = L"ShaderCache\\"; |
| 76 |
no test coverage detected