fix assert, working on loading
parent
19baf8b048
commit
3d7abd2765
|
@ -14,18 +14,45 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <blt/std/string.h>
|
#include <blt/std/string.h>
|
||||||
#include <blt/std/logging.h>
|
#include <blt/std/logging.h>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
|
namespace blt::fs
|
||||||
|
{
|
||||||
|
struct include_guard
|
||||||
|
{
|
||||||
|
char open = '<';
|
||||||
|
char close = '>';
|
||||||
|
};
|
||||||
|
|
||||||
namespace blt::fs {
|
|
||||||
std::vector<std::string> getLinesFromFile(const std::string& path);
|
std::vector<std::string> getLinesFromFile(const std::string& path);
|
||||||
|
|
||||||
std::vector<std::string> recursiveShaderInclude(const std::string& path, const std::string& include_header = "#include");
|
/**
|
||||||
|
* Recursively include files
|
||||||
|
* @param path initial file to load
|
||||||
|
* @param include_header the beginning of the line that should be used to recognize when a line is to be treated as an include
|
||||||
|
* @param guards characters used to identify the parts that specify the file path. if empty it will assume everything after the include header
|
||||||
|
* @return a list of lines in all files. added together in order.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> recursiveInclude(const std::string& path, const std::string& include_header = "#include",
|
||||||
|
const std::vector<include_guard>& guards = {{'<', '>'}, {'"', '"'}});
|
||||||
|
|
||||||
static inline std::string loadShaderFile(const std::string& path) {
|
static inline std::string loadBrainFuckFile(const std::string& path)
|
||||||
|
{
|
||||||
|
std::string buffer;
|
||||||
|
|
||||||
|
auto lines = recursiveInclude(path, "~");
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string loadShaderFile(const std::string& path)
|
||||||
|
{
|
||||||
std::stringstream stringStream;
|
std::stringstream stringStream;
|
||||||
|
|
||||||
auto lines = recursiveShaderInclude(path);
|
auto lines = recursiveInclude(path);
|
||||||
|
|
||||||
for (const auto& line : lines) {
|
for (const auto& line : lines)
|
||||||
|
{
|
||||||
// now process the defines, if they exist
|
// now process the defines, if they exist
|
||||||
// if (line.starts_with("#define")) {
|
// if (line.starts_with("#define")) {
|
||||||
// auto defineParts = String::split(line, " ");
|
// auto defineParts = String::split(line, " ");
|
||||||
|
|
|
@ -4,15 +4,18 @@
|
||||||
* See LICENSE file for license detail
|
* See LICENSE file for license detail
|
||||||
*/
|
*/
|
||||||
#include <blt/std/loader.h>
|
#include <blt/std/loader.h>
|
||||||
|
#include <blt/std/assert.h>
|
||||||
|
|
||||||
std::vector<std::string> blt::fs::getLinesFromFile(const std::string& path) {
|
std::vector<std::string> blt::fs::getLinesFromFile(const std::string& path)
|
||||||
|
{
|
||||||
std::string shaderSource;
|
std::string shaderSource;
|
||||||
std::ifstream shaderFile;
|
std::ifstream shaderFile;
|
||||||
if (!shaderFile.good())
|
if (!shaderFile.good())
|
||||||
BLT_ERROR("Input stream not good!\n");
|
BLT_ERROR("Input stream not good!\n");
|
||||||
// ensure ifstream objects can throw exceptions:
|
// ensure ifstream objects can throw exceptions:
|
||||||
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
shaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
// open file
|
// open file
|
||||||
shaderFile.open(path);
|
shaderFile.open(path);
|
||||||
std::stringstream shaderStream;
|
std::stringstream shaderStream;
|
||||||
|
@ -22,7 +25,8 @@ std::vector<std::string> blt::fs::getLinesFromFile(const std::string& path) {
|
||||||
shaderFile.close();
|
shaderFile.close();
|
||||||
// convert stream into std::string
|
// convert stream into std::string
|
||||||
shaderSource = shaderStream.str();
|
shaderSource = shaderStream.str();
|
||||||
} catch (std::ifstream::failure& e) {
|
} catch (std::ifstream::failure& e)
|
||||||
|
{
|
||||||
BLT_WARN("Unable to read file '%s'!\n", path.c_str());
|
BLT_WARN("Unable to read file '%s'!\n", path.c_str());
|
||||||
BLT_WARN("Exception: %s", e.what());
|
BLT_WARN("Exception: %s", e.what());
|
||||||
throw std::runtime_error("Failed to read file!\n");
|
throw std::runtime_error("Failed to read file!\n");
|
||||||
|
@ -32,55 +36,74 @@ std::vector<std::string> blt::fs::getLinesFromFile(const std::string& path) {
|
||||||
return string::split(shaderSource, "\n");
|
return string::split(shaderSource, "\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> blt::fs::recursiveShaderInclude(const std::string& path, const std::string& include_header) {
|
std::vector<std::string> blt::fs::recursiveInclude(const std::string& path, const std::string& include_header,
|
||||||
|
const std::vector<include_guard>& guards)
|
||||||
|
{
|
||||||
std::string pathOnly = path.substr(0, path.find_last_of('/'));
|
std::string pathOnly = path.substr(0, path.find_last_of('/'));
|
||||||
|
|
||||||
auto mainLines = getLinesFromFile(path);
|
auto mainLines = getLinesFromFile(path);
|
||||||
std::unordered_map<int, std::vector<std::string>> includes;
|
std::vector<std::string> return_lines;
|
||||||
|
|
||||||
for (unsigned int i = 0; i < mainLines.size(); i++) {
|
for (auto& line : mainLines)
|
||||||
auto& line = mainLines[i];
|
{
|
||||||
// if the line is an include statement then we want to add lines recursively.
|
// if the line is an include statement then we want to add lines recursively.
|
||||||
if (string::starts_with(line, include_header)) {
|
auto include_pos = line.find(include_header);
|
||||||
std::vector<std::string> include_statement = string::split(line, "<");
|
if (include_pos != std::string::npos)
|
||||||
|
{
|
||||||
|
auto past_include = include_pos + include_header.size();
|
||||||
|
BLT_TRACE(past_include);
|
||||||
|
BLT_TRACE("%c", (char)line[past_include]);
|
||||||
|
std::string file_to_include;
|
||||||
|
|
||||||
if (include_statement.size() <= 1)
|
if (guards.empty())
|
||||||
include_statement = string::split(line, "\"");
|
{
|
||||||
|
file_to_include = line.substr(line.find(include_header));
|
||||||
string::trim(line);
|
|
||||||
if (!(string::ends_with(line, ">") || string::ends_with(line, "\""))) {
|
|
||||||
BLT_FATAL("Shader file contains an invalid #include statement. (Missing terminator)\n");
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
// filter out the > or " at the end of the include statement.
|
|
||||||
std::string file;
|
|
||||||
file = include_statement[1];
|
|
||||||
if (string::ends_with(include_statement[1], ">"))
|
|
||||||
file = file.substr(0, file.size() - 1);
|
|
||||||
|
|
||||||
BLT_TRACE("Recusing into %s/%s\n", pathOnly.c_str(), file.c_str());
|
|
||||||
|
|
||||||
includes.insert({i, recursiveShaderInclude(pathOnly + "/" + file, include_header)});
|
|
||||||
} catch (std::exception& e) {
|
|
||||||
BLT_FATAL("Shader file contains an invalid #include statement. (Missing < or \")\n");
|
|
||||||
BLT_FATAL("Exception: %s", e.what());
|
|
||||||
std::abort();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<std::string> returnLines;
|
|
||||||
|
|
||||||
// now combine all the loaded files while respecting the include's position in the file.
|
|
||||||
for (unsigned int i = 0; i < mainLines.size(); i++) {
|
|
||||||
if (!includes[i].empty()) {
|
|
||||||
auto includedFileLines = includes[i];
|
|
||||||
|
|
||||||
for (const auto& line : includedFileLines)
|
|
||||||
returnLines.push_back(line);
|
|
||||||
} else
|
} else
|
||||||
returnLines.push_back(mainLines[i]);
|
{
|
||||||
|
size_t index = past_include;
|
||||||
|
while (std::find_if(guards.begin(), guards.end(), [&](const include_guard& item) {
|
||||||
|
return line[index] == item.open;
|
||||||
|
}) == guards.end())
|
||||||
|
index++;
|
||||||
|
index++;
|
||||||
|
BLT_ASSERT(index < line.size() && "Include found but no file was provided!");
|
||||||
|
|
||||||
|
std::cout << line.substr(index) << std::endl;
|
||||||
}
|
}
|
||||||
return returnLines;
|
|
||||||
|
// size_t index = 0;
|
||||||
|
//
|
||||||
|
// std::vector<std::string> include_statement = string::split(line, "<");
|
||||||
|
//
|
||||||
|
// if (include_statement.size() <= 1)
|
||||||
|
// include_statement = string::split(line, "\"");
|
||||||
|
//
|
||||||
|
// string::trim(line);
|
||||||
|
// if (!(string::ends_with(line, ">") || string::ends_with(line, "\"")))
|
||||||
|
// {
|
||||||
|
// BLT_FATAL("Shader file contains an invalid #include statement. (Missing terminator)\n");
|
||||||
|
// std::abort();
|
||||||
|
// }
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // filter out the > or " at the end of the include statement.
|
||||||
|
// std::string file;
|
||||||
|
// file = include_statement[1];
|
||||||
|
// if (string::ends_with(include_statement[1], ">"))
|
||||||
|
// file = file.substr(0, file.size() - 1);
|
||||||
|
//
|
||||||
|
// BLT_TRACE("Recusing into %s/%s\n", pathOnly.c_str(), file.c_str());
|
||||||
|
//
|
||||||
|
// includes.insert({i, recursiveInclude(pathOnly + "/" + file, include_header, guards)});
|
||||||
|
// } catch (std::exception& e)
|
||||||
|
// {
|
||||||
|
// BLT_FATAL("Shader file contains an invalid #include statement. (Missing < or \")\n");
|
||||||
|
// BLT_FATAL("Exception: %s", e.what());
|
||||||
|
// std::abort();
|
||||||
|
// }
|
||||||
|
} else
|
||||||
|
return_lines.push_back(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return return_lines;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue