public SimulationControllerBase(bool load = false, string path = "./model.json", Func <TGroup> generator = null,
                                        SimulationStrategy strategy = SimulationStrategy.Plane)
        {
            if (load)
            {
                switch (strategy)
                {
                case SimulationStrategy.None:
                {
                    Frames = new SimulationNoMemoryFrameController <State>();
                    break;
                }

                case SimulationStrategy.Plane:
                {
                    Frames = new SimulationPlaneFrameController <State>(path);
                    break;
                }

                case SimulationStrategy.Diffs:
                {
                    Frames = new SimulationDiffFrameController <State>(path);
                    break;
                }

                default: throw new ArgumentOutOfRangeException(nameof(strategy), strategy, null);
                }


                state = Load();
            }
            else
            {
                if (generator != null)
                {
                    state.TopGroup = generator();
                }
                else
                {
                    throw new Exception("Bad generator");
                }

                state.RefreshMarks();
                state.TimeStep = state.TopGroup.SetGlobatTransitionTimeScales();

                var fat = state.TopGroup.Descriptor.SubGroups.Values
                          .Traverse(g => g.Value.Descriptor.SubGroups.Values)
                          .SelectMany(g => g.Value.Descriptor.Transitions)
                          .Select(pair => pair.Value).ToList();
                fat.AddRange(state.TopGroup.Descriptor.Transitions.Values);

                Transitions = fat.OrderBy(
                    x =>
                {
                    if (x.Attributes.Any(a => a is PrioretyAttribute))
                    {
                        var pa = (PrioretyAttribute)x.Attributes.First(a => a is PrioretyAttribute);
                        return(pa.Priorety);
                    }

                    return(0);
                }
                    )
                              .ToList();

                if (Transitions
                    .Any(descriptor => !descriptor.Value.CheckActionFunctions()))
                {
                    throw new Exception("Bad Action routing detected");
                }

                switch (strategy)
                {
                case SimulationStrategy.None:
                {
                    Frames = new SimulationNoMemoryFrameController <State>();

                    break;
                }

                case SimulationStrategy.Plane:
                {
                    Frames = new SimulationPlaneFrameController <State>(path, false);

                    break;
                }

                case SimulationStrategy.Diffs:
                {
                    Frames = new SimulationDiffFrameController <State>(path, false);
                    break;
                }

                default: throw new ArgumentOutOfRangeException(nameof(strategy), strategy, null);
                }

                Frames.SaveState(state);
            }
        }
 public SimulationController(bool load = false, string path = "./model.json",
                             SimulationStrategy strategy = SimulationStrategy.Plane)
     : base(load, path, () => new TGroup())
 {
 }