Ejemplo n.º 1
0
 public void GetEntered(ref HashSet <int> entered)
 {
     foreach (var d in destinations)
     {
         entered.UnionWith(statechart.GetSuperstates(d, GetScope()));
     }
 }
Ejemplo n.º 2
0
    bool Step()
    {
#if SC_PROFILE_SINGLE
        stopwatch.Start();
#endif
        // Preparations

        CTs.Clear();
        entered.Clear();
        exited.Clear();
        active.Clear();
        foreach (var s in status.b_configuration)
        {
            active.UnionWith(machine.GetSuperstates(s));
        }

#if SC_PROFILE_SINGLE
        stopwatch.Stop();
        prepare.Accumulate(stopwatch);
        stopwatch.Reset();
        stopwatch.Start();
#endif
        // Search Paths

        foreach (var s in status.b_configuration)
        {
            var next = machine.TryExit(s, status);
            if (next != (null, null))
            {
                CTs.Add(new CT(machine, s, next.waypoints, next.destinations));
            }
        }

#if SC_PROFILE_SINGLE
        stopwatch.Stop();
        search.Accumulate(stopwatch);
        stopwatch.Reset();
        stopwatch.Start();
#endif
        // Validate Paths

        // Sort by scope high to low
        CTs.Sort();

        // Remove conflicting paths by priority
        for (int i = 0; i < CTs.Count; i++)
        {
            if (active.IsSupersetOf(machine.GetSuperstates(CTs[i].GetSource())))
            {
                generic.Clear();
                CTs[i].GetExited(ref generic);
                active.ExceptWith(generic);
                exited.UnionWith(generic);

                generic.Clear();
                CTs[i].GetEntered(ref generic);
                entered.UnionWith(generic);
            }
            else
            {
                CTs[i] = null;
            }
        }
        // Remove any so far untouched parallel regions which have been implicitly exited
        generic.Clear();
        foreach (var act in active)
        {
            var ancestors = machine.GetSuperstates(act);
            ancestors.Reverse();
            foreach (var a in ancestors)
            {
                if (!active.Contains(a))
                {
                    generic.UnionWith(machine.GetSuperstates(act, a));
                    break;
                }
            }
        }

        active.ExceptWith(generic);
        exited.UnionWith(generic);
        // Implicitly enter all so far untouched parallel regions
        generic.Clear();
        foreach (var e in entered)
        {
            if (machine.GetNodeType(e) == Node.Type.Parallel)
            {
                generic.UnionWith(machine.GetNodeComponents(e));
            }
        }

        generic.ExceptWith(active);
        generic.ExceptWith(entered);

        foreach (var r in generic)
        {
            var next = machine.TryEnter(r, status);
            if (next != (null, null))
            {
                entered.UnionWith(next.destinations);
            }
            // else: ERROR (Limitation)
        }
        // Cleanup
        entered.ExceptWith(active);

#if SC_PROFILE_SINGLE
        stopwatch.Stop();
        validate.Accumulate(stopwatch);
        stopwatch.Reset();
        stopwatch.Start();
#endif
        // Execute Step

        // Update configuration
        status.b_configuration.ExceptWith(ExtractAtomic(exited));
        status.b_configuration.UnionWith(ExtractAtomic(entered));
        // Execute actions
        DoActions(exited, Action.Type.EXIT);
        DoActions(active, Action.Type.STAY);
        foreach (var p in CTs)
        {
            if (p != null)
            {
                DoActions(p.GetWaypoints());
            }
        }
        DoActions(entered, Action.Type.ENTRY);
        // Clear and add events for next step
        status.events.Clear();
        foreach (var s in exited)
        {
            status.events.Add(new SCEvent("exit." + machine.GetNodeName(s)));
        }
        foreach (var s in entered)
        {
            status.events.Add(new SCEvent("enter." + machine.GetNodeName(s)));
        }

#if SC_PROFILE_SINGLE
        stopwatch.Stop();
        execute.Accumulate(stopwatch);
        stopwatch.Reset();
        if (prepare.SampleCount % 1000 == 0) // Reduce clutter
        {
            Debug.Log(
                "Prepare: " + prepare.GetStatistics(AccumulatedTime.TimeUnit.µs) +
                "\nSearch: " + search.GetStatistics(AccumulatedTime.TimeUnit.µs) +
                "\nValidate: " + validate.GetStatistics(AccumulatedTime.TimeUnit.µs) +
                "\nExecute: " + execute.GetStatistics(AccumulatedTime.TimeUnit.µs));
        }
#endif

#if SC_LOG_FUNCTIONALITY
        StringBuilder builder = new StringBuilder(this.ToString());
        builder.Append(" is now in\n");
        builder.Append(status.ToString());
        builder.Append("\nafter executing\n");
        foreach (var ct in CTs)
        {
            if (ct != null)
            {
                builder.Append(ct);
                builder.Append("\n\t");
            }
        }
        Debug.Log(builder.ToString());
#endif

#if SC_DEBUG
        if (!machine.IsValid(status))
        {
            StringBuilder sb = new StringBuilder("Invalid configuration in instance ");
            sb.Append(this);
            sb.Append(":\n\t");
            sb.Append(status.ToString());
            sb.Append("\nIt occured while executing:");
            foreach (var ct in CTs)
            {
                if (ct != null)
                {
                    sb.Append(ct);
                    sb.Append("\n\t");
                }
            }
            Debug.LogError(sb.ToString());
        }
#endif

        return(exited.Count > 0 || entered.Count > 0);
    }