private string InsertShad(StringBuilder properties, StringBuilder cgProperties,
StringBuilder body, bool addDefines)
{
PreProcess();
if (addDefines)
{
cgProperties.AppendLine(ShaderDefs.Functions);
}
//Emit properties in no particular order.
foreach (Node n in nodes)
{
n.EmitProperties(properties);
n.EmitDefs(cgProperties);
}
//Emit code for all nodes in proper order.
List <Node> toProcess = new List <Node>();
HashSet <Node> processedAlready = new HashSet <GPUGraph.Node>();
Dictionary <int, bool> uidDoneYet = new Dictionary <int, bool>();
if (!Output.IsAConstant)
{
toProcess.Add(GetNode(Output.NodeID));
uidDoneYet.Add(Output.NodeID, false);
}
while (toProcess.Count > 0)
{
Node n = toProcess[toProcess.Count - 1];
//If the next node hasn't been processed yet, add its inputs to the stack.
if (!uidDoneYet[n.UID])
{
foreach (NodeInput ni in n.Inputs)
{
if (!ni.IsAConstant)
{
if (uidDoneYet.ContainsKey(ni.NodeID))
{
//Move the node up to the top of the stack.
Node n2 = GetNode(ni.NodeID);
toProcess.Remove(n2);
toProcess.Add(n2);
}
else
{
toProcess.Add(GetNode(ni.NodeID));
uidDoneYet.Add(ni.NodeID, false);
}
}
}
uidDoneYet[n.UID] = true;
}
//Otherwise, let the node emit its code and then remove it from the stack.
else
{
toProcess.RemoveAt(toProcess.Count - 1);
if (!processedAlready.Contains(n))
{
processedAlready.Add(n);
n.EmitCode(body);
}
}
}
return(Output.GetExpression(this));
}