/// <summary> /// Returns the code for a specific algorithm. /// </summary> /// <returns>The algorithm code.</returns> /// <param name="algorithmType">Algorithm type.</param> public static MethodDeclaration GetAlgorithmCode(Type algorithmType, out AstBuilder astBuilder) { // Load Tychaia.ProceduralGeneration into Mono.Cecil. var module = AssemblyDefinition.ReadAssembly("Tychaia.ProceduralGeneration.dll").MainModule; // Now we have a reference to the method we want to decompile. TypeDefinition cecilType; MethodDefinition processCell; DecompileUtil.FindProcessCell(module, algorithmType, out processCell, out cecilType); var decompilerSettings = new DecompilerSettings(); astBuilder = new AstBuilder(new DecompilerContext(module) { CurrentType = cecilType, Settings = decompilerSettings }); astBuilder.AddMethod(processCell); astBuilder.RunTransformations(); astBuilder.CompilationUnit.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); // Return. return(astBuilder.CompilationUnit.Members.Where(v => v is MethodDeclaration).Cast <MethodDeclaration>().First()); }
private static ProcessedResult CompileRuntimeLayer(RuntimeLayer layer, RangedLayer ranged, IAlgorithm parent) { // Create our own processed result; a copy of our own state plus // somewhere to accumulate code. var result = new ProcessedResult(); result.ProcessedCode = ""; // Get a reference to the algorithm that the runtime layer is using. var algorithm = layer.Algorithm; if (algorithm == null) { throw new InvalidOperationException("Attempted to compile null runtime layer!"); } var algorithmType = algorithm.GetType(); // If the runtime layer has inputs, we need to process them first. if (layer.Algorithm.InputTypes.Length > 0) { var inputs = layer.GetInputs(); result.InputVariableNames = new string[inputs.Length]; for (var i = 0; i < inputs.Length; i++) { var inputResult = CompileRuntimeLayer(inputs[i], ranged.Inputs[i], layer.Algorithm); result.ProcessedCode += inputResult.ProcessedCode; result.InputVariableNames[i] = inputResult.OutputVariableName; result.Declarations += inputResult.Declarations; } } // Create the storage array. result.OutputVariableName = GenerateRandomIdentifier(); result.OutputVariableType = algorithm.OutputType.FullName; result.Declarations += result.OutputVariableType + "[] " + result.OutputVariableName + " = new " + result.OutputVariableType + "[__cwidth * __cheight * __cdepth];\n"; Console.WriteLine(ranged.ToString()); // Add the conditional container. string code = "if (k >= (int)((" + ranged.Z.GetText(null) + ") - z) && i >= (int)((" + ranged.X.GetText(null) + ") - x) && j >= (int)((" + ranged.Y.GetText(null) + ") - y)" + " && k < " + ranged.OuterZ.GetText(null) + " && i < " + ranged.OuterX.GetText(null) + " && j < " + ranged.OuterY.GetText(null) + @") { "; /*result.Declarations += "Console.WriteLine(\"COMPILED: \" + " + * "" + ranged.X + " + \" \" + " + * "" + ranged.Y + " + \" \" + " + * "" + ranged.Z + " + \" \" + " + * "" + ranged.Width + " + \" \" + " + * "" + ranged.Height + " + \" \" + " + * "" + ranged.Depth + ");";*/ // Refactor the method. AstBuilder astBuilder; var method = DecompileUtil.GetAlgorithmCode(algorithmType, out astBuilder); AlgorithmRefactorer.InlineMethod(algorithm, method, result.OutputVariableName, result.InputVariableNames, "__cx", "__cy", "__cz", "__cwidth", "__cheight", "__cdepth"); AlgorithmRefactorer.RemoveUsingStatements(astBuilder.CompilationUnit, result.UsingStatements); code += method.Body.GetText(); // Terminate the conditional container and return. code += "computations += 1;"; code += "}\n"; result.ProcessedCode += code; return(result); }