public static void Start(string[] args, GameControllerOptions options, bool contentStart = false, IMainArgs?loaderArgs = null)
        {
            if (_hasStarted)
            {
                throw new InvalidOperationException("Cannot start twice!");
            }

            _hasStarted = true;

            if (CommandLineArgs.TryParse(args, out var parsed))
            {
                ParsedMain(parsed, contentStart, loaderArgs, options);
            }
        }
        public void Run(DisplayMode mode, GameControllerOptions options, Func <ILogHandler>?logHandlerFactory = null)
        {
            if (!StartupSystemSplash(options, logHandlerFactory))
            {
                Logger.Fatal("Failed to start game controller!");
                return;
            }

            if (_clyde.SeparateWindowThread)
            {
                var stackSize = _configurationManager.GetCVar(CVars.SysGameThreadStackSize);
                var priority  = (ThreadPriority)_configurationManager.GetCVar(CVars.SysGameThreadPriority);

                _gameThread = new Thread(() => GameThreadMain(mode), stackSize)
                {
                    IsBackground = false,
                    Priority     = priority,
                    Name         = "Game thread",
                };

                _gameThread.Start();

                // Will block until game exit
                _clyde.EnterWindowLoop();

                if (_gameThread.IsAlive)
                {
                    Logger.Debug("Window loop exited; waiting for game thread to exit");
                    _gameThread.Join();
                }
            }
            else
            {
                ContinueStartupAndLoop(mode);
            }

            Cleanup();

            Logger.Debug("Goodbye");
            IoCManager.Clear();
        }
        private static void ParsedMain(CommandLineArgs args, bool contentStart, IMainArgs?loaderArgs, GameControllerOptions options)
        {
            IoCManager.InitThread();

            var mode = args.Headless ? DisplayMode.Headless : DisplayMode.Clyde;

            InitIoC(mode);

            var gc = IoCManager.Resolve <GameController>();

            gc.SetCommandLineArgs(args);
            gc._loaderArgs = loaderArgs;

            // When the game is ran with the startup executable being content,
            // we have to disable the separate load context.
            // Otherwise the content assemblies will be loaded twice which causes *many* fun bugs.
            gc.ContentStart = contentStart;

            gc.Run(mode, options);
        }