示例#1
0
    public bool IsChannelUsed(Channel channel)
    {
        if (isDirectlyUsed[channel.Index])
        {
            return(true);
        }
        if (channel.ParentChannel != null)
        {
            return(true);
        }

        var dependencyGatheringVisitor = new DependencyGatheringVisitor();

        foreach (var formula in channel.SumFormulas)
        {
            formula.Accept(dependencyGatheringVisitor);
        }
        foreach (var formula in channel.MultiplyFormulas)
        {
            formula.Accept(dependencyGatheringVisitor);
        }
        foreach (var dependency in dependencyGatheringVisitor.Dependencies)
        {
            if (IsChannelUsed(dependency))
            {
                return(true);
            }
        }

        return(false);
    }
    private void GenerateFor(Channel channel)
    {
        if (visitedChannels.Contains(channel))
        {
            return;
        }

        visitedChannels.Add(channel);

        //visit dependencies
        var dependencyGatheringVisitor = new DependencyGatheringVisitor();

        foreach (var formula in channel.SumFormulas)
        {
            formula.Accept(dependencyGatheringVisitor);
        }
        foreach (var formula in channel.MultiplyFormulas)
        {
            formula.Accept(dependencyGatheringVisitor);
        }
        foreach (var dependency in dependencyGatheringVisitor.Dependencies)
        {
            GenerateFor(dependency);
        }

        //setup stack for store
        ilGenerator.Emit(OpCodes.Ldarg_2);
        ilGenerator.Emit(OpCodes.Ldc_I4, channel.Index);

        //load raw value
        ilGenerator.Emit(OpCodes.Ldarg_1);
        ilGenerator.Emit(OpCodes.Ldc_I4, channel.Index);
        ilGenerator.Emit(OpCodes.Ldelem_R8);

        //add parent value
        if (channel.ParentChannel != null)
        {
            ilGenerator.Emit(OpCodes.Ldarg_0);
            ilGenerator.Emit(OpCodes.Ldc_I4, channel.ParentChannel.Index);
            ilGenerator.Emit(OpCodes.Ldelem_R8);
            ilGenerator.Emit(OpCodes.Add);
        }

        foreach (var formula in channel.SumFormulas)
        {
            formula.Accept(this);
            ilGenerator.Emit(OpCodes.Add);
        }

        foreach (var formula in channel.MultiplyFormulas)
        {
            formula.Accept(this);
            ilGenerator.Emit(OpCodes.Mul);
        }

        //apply clamp
        if (channel.Clamped)
        {
            ilGenerator.Emit(OpCodes.Ldc_R8, channel.Min);
            ilGenerator.Emit(OpCodes.Ldc_R8, channel.Max);
            ilGenerator.Emit(OpCodes.Call, EvaluatorHelperMethods.ClampMethodInfo);
        }

        //store result
        ilGenerator.Emit(OpCodes.Stelem_R8);
    }