Skip to content

Instantly share code, notes, and snippets.

@maierfelix
Created March 21, 2020 09:51
Show Gist options
  • Save maierfelix/21738a65b3cea4b609e2436cb1e07da2 to your computer and use it in GitHub Desktop.
Save maierfelix/21738a65b3cea4b609e2436cb1e07da2 to your computer and use it in GitHub Desktop.
import fs from "fs";
function findIncludedFile(filePath, includes) {
let matches = [];
for (let ii = 0; ii < includes.length; ++ii) {
let incl = includes[ii];
let stats = fs.lstatSync(incl);
if (!stats.isDirectory()) {
throw new SyntaxError(`Include path '${incl}' is not a directory`);
}
let includeFilePath = path.join(incl, filePath);
if (fs.existsSync(includeFilePath) && fs.lstatSync(includeFilePath).isFile()) {
try {
matches.push(fs.readFileSync(includeFilePath, "utf-8"));
} catch (e) {
throw new ReferenceError(`Cannot read included file from '${includeFilePath}'`);
}
} else {
throw new ReferenceError(`Failed to resolve file include path for '${filePath}': '${includeFilePath}' is not a valid file path`);
}
};
if (matches.length <= 0) {
throw new ReferenceError(`Cannot inline included file '${filePath}'`);
}
if (matches.length > 1) {
throw new ReferenceError(`Ambigious include directive for '${filePath}'. More than one match was found`);
}
return matches[0];
};
function flattenShaderIncludes(source, includeDirectories) {
let rx = /#include ((<[^>]+>)|("[^"]+"))/g;
let match = null;
while (match = rx.exec(source)) {
let filePath = match[1].slice(1, -1);
let start = match.index;
let length = match[0].length;
let includedFile = flattenShaderIncludes(
findIncludedFile(filePath, includeDirectories),
includeDirectories
);
source = source.substr(0, start) + includedFile + source.substr(start + length);
};
return source;
};
export function loadShaderFile(srcPath) {
let src = fs.readFileSync(srcPath, "utf-8");
let flattened = flattenShaderIncludes(src, [path.dirname(srcPath)]);
return flattened;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment