private ExpressionContainer AddIfDefExpressionContainer(IfDefReference ifdef) { var expr = new FlatExpression(new Operands(ifdef.Node.Value), new FlatExpressionLine(ifdef.Defined ? 1ul : 0ul)); if (ifdef.Node.Extra.Define.IfDefs?.Count > 0) { var parentIfDefs = ifdef.Node.Extra.Define.IfDefs; var listContainers = new List <ExpressionContainer>(parentIfDefs.Count); foreach (var ifDef in parentIfDefs) { listContainers.Add(GetOrAddExpressionContainer(new IfDefSet(ifDef))); } var operands = new Operands(listContainers .Select(_ => _.FlatExpression.Operands.Concat(expr.Operands)) .SelectMany(_ => _) .Distinct() .OrderBy(_ => _) .ToArray()); var flatExpr = new FlatExpression(operands); foreach (var c in listContainers) { flatExpr = flatExpr.Or(c.FlatExpression); } expr = flatExpr.And(expr); } if (ifdef.Defined) { ifdef.Node.Extra.Define.IfDefExpression = expr.AsTreeExpression().ToString(); } else { ifdef.Node.Extra.Define.IfNotDefExpression = expr.AsTreeExpression().ToString(); } var container = new ExpressionContainer { FlatExpression = expr }; _knownReferences.Add(new IfDefSet(ifdef), container); return(container); }
public void OrIfDef(IfDefReference reference) { (IfDefs ?? (IfDefs = new List <IfDefReference>())).Add(reference); }
public void Apply() { var leafs = new List <NodeHelper>(); var ifdefs = new List <NodeHelper>(); foreach (var scriptNode in _script.Nodes) { if (scriptNode.Extra == null) { scriptNode.Extra = new TranslatedMaterialGraph.NodeInfo(); } var container = new Container { IsIfDef = NodeTypes.IsIfDefType(scriptNode.Type) }; scriptNode.Extra.Define = container; if (container.IsIfDef) { ifdefs.Add(scriptNode); } if (scriptNode.OutputPins.Count == 0) { leafs.Add(scriptNode); scriptNode.Extra.Define.IsAlways = true; } } // Mark all nodes connected to output as always present. These nodes don't need any defines. foreach (var nodeHelper in leafs) { EnumerateConnectedNodes(nodeHelper, _ => { _.Extra.Define.IsAlways = true; return(!_.Extra.Define.IsIfDef); }); } // For each node connected to a ifdef node collect all ifdefs it is connected to. foreach (var nodeHelper in ifdefs) { var ref0 = new IfDefReference { Defined = true, Node = nodeHelper }; var ref1 = new IfDefReference { Defined = false, Node = nodeHelper }; GetOrAddExpressionContainer(new IfDefSet(ref0)); GetOrAddExpressionContainer(new IfDefSet(ref1)); EnumerateConnectedNodes(nodeHelper.InputPins[0], _ => { if (_.Extra.Define.IsAlways) { return(false); } _.Extra.Define.OrIfDef(ref0); return(!_.Extra.Define.IsIfDef); }); EnumerateConnectedNodes(nodeHelper.InputPins[1], _ => { if (_.Extra.Define.IsAlways) { return(false); } _.Extra.Define.OrIfDef(ref1); return(!_.Extra.Define.IsIfDef); }); } foreach (var node in _script.Nodes) { var expression = BuildExpression(node); if (expression == PreprocessorExpression.True) { expression = null; } if (expression == null) { node.Extra.Define.IsAlways = true; } node.Extra.Define.Expression = expression; } }
public IfDefSet(IfDefReference reference) : this(new[] { reference }) { }