public static bool TryParseEffect(string shaderName, Dictionary <string, ShaderViewModel> shaders, out ParsedShader result) { result = null; var resultRef = new ParsedShaderRef(); var success = TryParseEffect(shaderName, shaders, resultRef); Debug.Assert(resultRef.ParentShaders.Count == 0); if (success) { result = resultRef.ParsedShader; } return(success); }
private static bool TryParseEffect(string shaderName, Dictionary <string, ShaderViewModel> shaders, ParsedShaderRef resultRef) { lock (parserCacheLock) { if (parserCache.TryGetValue(shaderName, out var localResult)) { if (resultRef.ParsedShader == null) { resultRef.ParsedShader = localResult; } else { foreach (var parentShader in resultRef.ParentShaders) { parentShader.AddBaseShader(localResult); // also add all base shaders of this base shader foreach (var baseShader in localResult.BaseShaders) { parentShader.AddBaseShader(baseShader); } } } return(true); } try { // SDSL var macros = new[] { new ShaderMacro("class", "shader") }; // get source code var code = File.ReadAllText(shaders[shaderName].Path); var inputFileName = shaderName + ".sdsl"; var parsingResult = StrideShaderParser.TryPreProcessAndParse(code, inputFileName, macros); if (parsingResult.HasErrors || parsingResult.Shader.GetFirstClassDecl() == null) { return(false); } else //success { localResult = new ParsedShader(parsingResult.Shader); foreach (var parentShader in resultRef.ParentShaders) { parentShader.AddBaseShader(localResult); } // original shader if (resultRef.ParsedShader == null) { resultRef.ParsedShader = localResult; } resultRef.ParentShaders.Push(localResult); try { // base shaders var baseShaders = localResult.ShaderClass?.BaseClasses ?? Enumerable.Empty <TypeName>(); foreach (var baseClass in baseShaders) { var baseShaderName = baseClass.Name.Text; TryParseEffect(baseShaderName, shaders, resultRef); } } finally { resultRef.ParentShaders.Pop(); } parserCache[shaderName] = localResult; return(true); } } catch (Exception) { return(false); } } }