示例#1
0
    // public static async Task<GameScript> LoadAsync(
    //     IEnumerable<ScriptFile> sources,
    //     IScriptCompiler compiler)
    // {
    //     // TODO Dispose ScriptRunner
    //     using var scriptRunner = compiler.Compile<Game>(sources);

    //     EventQueue eventQueue = new();

    //     var game = new Game(eventQueue);

    //     await scriptRunner.RunAsync(game);

    //     return new GameScript(game, eventQueue);
    // }

    public Task RunAsync(IMediator mediator, GameState?gameState = null)
    {
        // Filter event queue while setting up the game. Only ProtagonistChanged
        // and RoomEntered should be sent to the UI when the game starts.
        _eventQueue.IgnoreAll();

        // Runs the OnGameStart callback in the game script.
        _game.Start();

        // From this point on, allow all events to go to the UI.
        _eventQueue.AllowAll();

        // We do need to make sure that the startup script has at least set
        // a protagonist and room.
        if (_game.Protagonist is null)
        {
            throw new InvalidOperationException(
                      "Startup script must set a protagonist.");
        }
        if (_game.CurrentRoom is null)
        {
            throw new InvalidOperationException(
                      "Startup script must enter a room.");
        }

        // Save the initial state so we've got something to compare to when
        // saving the game.
        _initialState = _game.Save();

        if (gameState is not null)
        {
            _game.Load(gameState);
        }

        _eventQueue.Enqueue(new GameStarted(_game));
        _eventQueue.Enqueue(new ProtagonistChanged(_game.Protagonist !));
        _eventQueue.Enqueue(new RoomEntered(_game.CurrentRoom !));

        return(_eventQueue.FlushAsync(mediator));
    }