-
Notifications
You must be signed in to change notification settings - Fork 0
/
Shadinclude.hpp
127 lines (102 loc) · 4.28 KB
/
Shadinclude.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#pragma once
#include <string>
#include <fstream>
#include <iostream>
// ===========
// Shadinclude
// ===========
/*
LICENCE
MIT License
Copyright (c) [2018] [Tahar Meijs]
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
INTRODUCTION
The sole purpose of this class is to load a file and extract the text that is in it.
In theory, this class could be used for a variety of text-processing purposes, but
it was initially designed to be used to load shader source code.
USING THIS CLASS
Since the entire class is a static class, you only have to add this single line of
code to your project:
--------------------------------------------------------------------------------------
std::string shaderSource = Shadinclude::load("./path/to/shader.extension");
--------------------------------------------------------------------------------------
This will (recursively) extract the source code from the first shader file.
Now, you might be wondering, what is the point of using your code for something
so trivial as to loading a file and calling the "std::getline()" function on it?
Well, besides loading the shader source code from a single file, the loader also
supports custom keywords that allow you to include external files inside your
shader source code!
PARAMETERS OF THE LOAD FUNCTION
- std::string path path to the "main" shader file
- std::string includeIdentifier keyword to look for when scanning for files
MISCELLANEOUS
- Author : Tahar Meijs
- Date : 10th - 12th of April 2018
- Language : C++ (can easily be converted into other languages)
*/
class Shadinclude
{
public:
// Return the source code of the complete shader
static std::string load(std::string path, std::string includeIndentifier = "#include")
{
includeIndentifier += ' ';
static bool isRecursiveCall = false;
std::string fullSourceCode = "";
std::ifstream file(path);
if (!file.is_open())
{
std::cerr << "ERROR: could not open the shader at: " << path << "\n" << std::endl;
return fullSourceCode;
}
std::string lineBuffer;
while (std::getline(file, lineBuffer))
{
// Look for the new shader include identifier
if (lineBuffer.find(includeIndentifier) != lineBuffer.npos)
{
// Remove the include identifier, this will cause the path to remain
lineBuffer.erase(0, includeIndentifier.size());
// The include path is relative to the current shader file path
std::string pathOfThisFile;
getFilePath(path, pathOfThisFile);
lineBuffer.insert(0, pathOfThisFile);
// By using recursion, the new include file can be extracted
// and inserted at this location in the shader source code
isRecursiveCall = true;
fullSourceCode += load(lineBuffer);
// Do not add this line to the shader source code, as the include
// path would generate a compilation issue in the final source code
continue;
}
fullSourceCode += lineBuffer + '\n';
}
// Only add the null terminator at the end of the complete file,
// essentially skipping recursive function calls this way
if (!isRecursiveCall)
fullSourceCode += '\0';
file.close();
return fullSourceCode;
}
private:
static void getFilePath(const std::string & fullPath, std::string & pathWithoutFileName)
{
// Remove the file name and store the path to this folder
size_t found = fullPath.find_last_of("/\\");
pathWithoutFileName = fullPath.substr(0, found + 1);
}
};