Example #1
0
        public StateVariable AddStateVariable(string name, VariableValueType type, string description = "")
        {
            StateVariable item = new StateVariable()
            {
                Name        = name,
                Type        = type,
                Description = description,
            };

            StateVariables.Add(item);

            return(item);
        }
Example #2
0
        private static string GetStateVariableType(StateVariable stateVariable)
        {
            switch (stateVariable.Type)
            {
            case VariableValueType.Boolean:
                return("bool");

            case VariableValueType.Integer:
                return("int");

            case VariableValueType.Double:
                return("double");

            case VariableValueType.String:
                return("string");

            default:
                return("object");
            }
        }
Example #3
0
 public StateVariableException(StateVariable stateVariable) : base()
 {
     StateVariable = stateVariable;
 }
Example #4
0
        private static void WriteGraphCode(StringBuilder sb, Graph graph, IEnumerable <string> traceExpressions, ref int indent)
        {
            StartBlock(sb, "enum EventType", ref indent);

            var eventNames          = new Dictionary <Vertex, string>();
            var eventParameterTypes = new Dictionary <Vertex, string>();

            for (int i = 0; i < graph.Verticies.Count; i++)
            {
                Vertex vertex = graph.Verticies[i];

                int paramCount = vertex.ParameterNames.Count;
                if (paramCount > 0 && !eventParameterTypes.ContainsKey(vertex))
                {
                    StringBuilder tupleTypesSB = new StringBuilder();

                    tupleTypesSB.Append("Tuple<");

                    for (int j = 0; j < paramCount; j++)
                    {
                        if (j > 0)
                        {
                            tupleTypesSB.Append(", ");
                        }

                        tupleTypesSB.Append(GetStateVariableType(graph.GetStateVariable(vertex.ParameterNames[i])));
                    }

                    tupleTypesSB.Append('>');

                    eventParameterTypes[vertex] = tupleTypesSB.ToString();
                }

                if (!eventNames.TryGetValue(vertex, out string eventName))
                {
                    if (!ScriptingHost.TrySymbolify(vertex.Name, false, out string result))
                    {
                        result = i.ToString();
                    }
                    eventName          = $"{ EventNamePrefix }{ result }";
                    eventNames[vertex] = eventName;
                }

                WriteCode(sb, $"{ eventName } = { i },", ref indent);
            }

            EndBlock(sb, ref indent); // enum EventType

            sb.AppendLine();
            StartBlock(sb, "class Simulation : SimulationBase", ref indent);

            Vertex startingVertex = graph.StartingVertex;

            WriteCode(sb, $"protected override EventType StartingEventType => EventType.{ eventNames[startingVertex] };", ref indent);

            if (graph.StateVariables.Count > 0)
            {
                sb.AppendLine();
                WriteComment(sb, "State Variables", ref indent);

                for (int i = 0; i < graph.StateVariables.Count; i++)
                {
                    StateVariable stateVariable = graph.StateVariables[i];
                    WriteCode(sb, $"{ GetStateVariableType(stateVariable) } { RewriteExpression(graph, stateVariable.Name) } = default;", ref indent);
                }
            }

            sb.AppendLine();
            WriteCode(sb, "public Simulation() { }", ref indent);

            if (startingVertex.ParameterNames.Count > 0)
            {
                sb.AppendLine();

                StringBuilder tupleValuesSB = new StringBuilder();

                for (int i = 0; i < startingVertex.ParameterNames.Count; i++)
                {
                    if (i > 0)
                    {
                        tupleValuesSB.Append(", ");
                    }

                    string type = GetStateVariableType(graph.GetStateVariable(startingVertex.ParameterNames[i]));

                    switch (type)
                    {
                    case "bool":
                    case "int":
                    case "double":
                        tupleValuesSB.Append($"{ type }.Parse(startParameters[{ i }])");
                        break;

                    default:
                        tupleValuesSB.Append($"startParameters[{ i }]");
                        break;
                    }
                }

                WriteCode(sb, $"protected override object ParseStartParameters(string[] startParameters) => Tuple.Create({ tupleValuesSB});", ref indent);
            }

            sb.AppendLine();
            StartBlock(sb, "protected override void ProcessEvent(EventType eventType, object parameterValues)", ref indent);

            StartBlock(sb, "switch (eventType)", ref indent);

            for (int i = 0; i < graph.Verticies.Count; i++)
            {
                Vertex vertex = graph.Verticies[i];

                StartBlock(sb, $"case EventType.{ eventNames[vertex] }:", ref indent, false);

                WriteCode(sb, $"{ eventNames[vertex] }({ (vertex.ParameterNames.Count > 0 ? $"({ eventParameterTypes[vertex] })parameterValues" : "") });", ref indent);

                WriteCode(sb, "break;", ref indent);

                EndBlock(sb, ref indent, false); // case
            }

            EndBlock(sb, ref indent); // switch

            EndBlock(sb, ref indent); // protected override void ProcessEvent

            for (int i = 0; i < graph.Verticies.Count; i++)
            {
                Vertex vertex = graph.Verticies[i];

                sb.AppendLine();

                WriteComment(sb, $"Event #{ i }: { vertex.Name }", ref indent);
                if (!string.IsNullOrWhiteSpace(vertex.Description))
                {
                    WriteComment(sb, $"Description: { vertex.Description }", ref indent);
                }

                int paramCount = vertex.ParameterNames.Count;

                StartBlock(sb, $"private void { eventNames[vertex] }({ (paramCount > 0 ? $"{ eventParameterTypes[vertex] } parameterValues" : "") })", ref indent);

                bool addSpacing = false;

                if (paramCount > 0)
                {
                    WriteComment(sb, "Parameters", ref indent);
                    for (int j = 0; j < paramCount; j++)
                    {
                        WriteCode(sb, $"{ RewriteExpression(graph, vertex.ParameterNames[j]) } = parameterValues.Item{ j + 1 };", ref indent);
                    }

                    addSpacing = true;
                }

                string[] code = vertex.Code;
                if (code is not null && code.Length > 0)
                {
                    if (addSpacing)
                    {
                        sb.AppendLine();
                    }

                    WriteComment(sb, "Event Code", ref indent);
                    for (int j = 0; j < code.Length; j++)
                    {
                        WriteCode(sb, $"{ RewriteExpression(graph, code[j]) };", ref indent);
                    }

                    addSpacing = true;
                }

                for (int j = 0; j < graph.Edges.Count; j++)
                {
                    Edge edge = graph.Edges[j];

                    if (vertex == edge.Source)
                    {
                        if (addSpacing)
                        {
                            sb.AppendLine();

                            WriteComment(sb, $"Edge #{ j }: { edge.Action} { edge.Source.Name } to { edge.Target.Name }", ref indent);

                            if (!string.IsNullOrWhiteSpace(edge.Description))
                            {
                                WriteComment(sb, $"Description: { edge.Description }", ref indent);
                            }
                        }

                        bool hasCondition = !string.IsNullOrEmpty(edge.Condition);
                        if (hasCondition)
                        {
                            StartBlock(sb, $"if ({ RewriteExpression(graph, edge.Condition) })", ref indent);
                        }

                        StringBuilder parameterValuesSB = new StringBuilder();

                        if (edge.ParameterExpressions.Count == 0)
                        {
                            parameterValuesSB.Append("null");
                        }
                        else
                        {
                            parameterValuesSB.Append($"new { eventParameterTypes[vertex] }(");
                            for (int k = 0; k < edge.ParameterExpressions.Count; k++)
                            {
                                if (k > 0)
                                {
                                    parameterValuesSB.Append(", ");
                                }

                                parameterValuesSB.Append(RewriteExpression(graph, edge.ParameterExpressions[k]));
                            }
                            parameterValuesSB.Append(')');
                        }

                        switch (edge.Action)
                        {
                        case EdgeAction.Schedule:
                            WriteCode(sb, $"ScheduleEvent(EventType.{ eventNames[edge.Target] }, { (string.IsNullOrEmpty(edge.Delay) ? "0" : RewriteExpression(graph, edge.Delay)) }, { (string.IsNullOrEmpty(edge.Priority) ? "0" : RewriteExpression(graph, edge.Priority)) }, { parameterValuesSB});", ref indent);
                            break;

                        case EdgeAction.CancelNext:
                            WriteCode(sb, $"CancelNextEvent(EventType.{ eventNames[edge.Target] }, { parameterValuesSB});", ref indent);
                            break;

                        case EdgeAction.CancelAll:
                            WriteCode(sb, $"CancelAllEvents(EventType.{ eventNames[edge.Target] }, { parameterValuesSB});", ref indent);
                            break;
                        }

                        if (hasCondition)
                        {
                            EndBlock(sb, ref indent); // if condition
                        }

                        addSpacing = true;
                    }
                }

                EndBlock(sb, ref indent); // private void Event
            }

            sb.AppendLine();
            StartBlock(sb, "protected override string GetEventName(EventType eventType)", ref indent);

            StartBlock(sb, "switch (eventType)", ref indent);

            for (int i = 0; i < graph.Verticies.Count; i++)
            {
                Vertex vertex = graph.Verticies[i];

                StartBlock(sb, $"case EventType.{ eventNames[vertex] }:", ref indent, false);

                WriteCode(sb, $"return \"{ eventNames[vertex].Substring(EventNamePrefix.Length) }\";", ref indent);

                EndBlock(sb, ref indent, false); // case
            }

            EndBlock(sb, ref indent); // switch

            WriteCode(sb, $"return \"\";", ref indent);

            EndBlock(sb, ref indent); // protected override string GetEventName

            sb.AppendLine();
            StartBlock(sb, "protected override void TraceExpressionHeaders(bool traceToConsole, StreamWriter outputWriter)", ref indent);

            if (traceExpressions is not null)
            {
                foreach (string traceExpression in traceExpressions)
                {
                    WriteCode(sb, $"Trace(traceToConsole, outputWriter, \"\\t{ RewriteExpression(graph, traceExpression, false) }\");", ref indent);
                }
            }

            EndBlock(sb, ref indent); // protected override void TraceExpressionHeaders

            sb.AppendLine();
            StartBlock(sb, "protected override void TraceExpressionValues(bool traceToConsole, StreamWriter outputWriter)", ref indent);

            if (traceExpressions is not null)
            {
                foreach (string traceExpression in traceExpressions)
                {
                    WriteCode(sb, $"Trace(traceToConsole, outputWriter, $\"\\t{{ { RewriteExpression(graph, traceExpression) } }}\");", ref indent);
                }
            }

            EndBlock(sb, ref indent); // protected override void TraceExpressionValues

            EndBlock(sb, ref indent); // class Simulation
        }
Example #5
0
 public StateVariableTraceExpression(StateVariable stateVariable) : base(stateVariable.Name, stateVariable.Type)
 {
     StateVariable = stateVariable ?? throw new ArgumentNullException(nameof(stateVariable));
 }
Example #6
0
 public ReservedKeywordStateVariableValidationError(Graph graph, StateVariable stateVariable) : base(graph, stateVariable)
 {
 }
Example #7
0
 public InvalidStateVariableNameValidationError(Graph graph, StateVariable stateVariable) : base(graph, stateVariable)
 {
 }
Example #8
0
 public StateVariableValidationError(Graph graph, StateVariable stateVariable) : base(graph)
 {
     StateVariable = stateVariable ?? throw new ArgumentNullException(nameof(stateVariable));
 }