From 7b7b753af613085af30476a8f9f4664176bbcbdf Mon Sep 17 00:00:00 2001 From: Alexandru Iuga Date: Mon, 15 Jan 2024 12:01:10 +0200 Subject: [PATCH] extracted a game hosting component --- sources/Directory.Build.props | 4 +- .../Dot.Application/Dot.Application.csproj | 1 + .../GameHostActions/ExitAction.cs | 71 +++++++++------ .../GameHostActions/LoadGameAction.cs | 71 +++++++++------ .../GameHostActions/MainMenuAction.cs | 71 +++++++++------ .../GameHostActions/NewGameAction.cs | 71 +++++++++------ .../GameHostActions/SaveGameAction.cs | 71 +++++++++------ .../UseCases/LoadGame/LoadGameUseCase.cs | 2 +- .../UseCases/NewGame/CreateNewGameUseCase.cs | 2 +- .../UseCases/ResumeGame/ResumeGameUseCase.cs | 2 +- sources/Dot.Bootstrapping/BootstrapperBase.cs | 10 +-- .../Dot.Bootstrapping.csproj | 1 + sources/Dot.Demo/Bootstrapper.cs | 39 ++++++--- sources/Dot.Demo/DemoGame.cs | 39 ++++++--- sources/Dot.Demo/Dot.Demo.csproj | 1 + sources/Dot.Demo/GameApplication.cs | 14 --- sources/Dot.Demo/ModuleHost.cs | 28 ++++++ sources/Dot.Demo/Objects/Acorn.cs | 63 +++++++++----- .../Dot.Demo/Objects/CrossroadsLocation.cs | 57 +++++++----- sources/Dot.Demo/Objects/NorthRoad.cs | 53 +++++++---- sources/Dot.Demo/Objects/Oak.cs | 53 +++++++---- sources/Dot.Demo/Objects/ParkLocation.cs | 87 +++++++++++-------- sources/Dot.Demo/Program.cs | 45 ++++++---- sources/Dot.Domain/IGameApplication.cs | 9 -- sources/Dot.Domain/ModuleModel/IModule.cs | 11 --- .../ModuleRunExceptionEventArgs.cs | 16 ---- sources/Dot.GameAccess/JActionStep.cs | 9 -- sources/Dot.GameAccess/JCondition.cs | 26 ++++++ .../Dot.GameHosting/Dot.GameHosting.csproj | 12 +++ sources/Dot.GameHosting/IModule.cs | 26 ++++++ sources/Dot.GameHosting/IModuleHost.cs | 24 +++++ .../ModuleEngine.cs | 6 +- .../ModuleNotFoundException.cs | 4 +- .../ModuleRunExceptionEventArgs.cs | 29 +++++++ .../NoModulesException.cs | 4 +- sources/Dot.GameHosting/StandardModuleHost.cs | 87 +++++++++++++++++++ .../Dot.Ports.PresentationAccess.csproj | 10 +++ .../IPresentation.cs | 32 +++++++ .../Dot.Presentation/Commands/ExitCommand.cs | 9 +- .../Dot.Presentation/Dot.Presentation.csproj | 2 + .../Dot.Presentation/Modules/GameModule.cs | 2 +- .../Dot.Presentation/Modules/MenuModule.cs | 2 +- .../Presenters/GamePresenter.cs | 8 +- .../StandardGameApplication.cs | 77 ---------------- .../Dot.Presentation/Views/ApplicationView.cs | 2 +- .../Dot.PresentationAccess.csproj | 16 ++++ .../Dot.PresentationAccess/Presentation.cs | 60 +++++++++++++ sources/Dot.sln | 20 +++++ 48 files changed, 893 insertions(+), 466 deletions(-) delete mode 100644 sources/Dot.Demo/GameApplication.cs create mode 100644 sources/Dot.Demo/ModuleHost.cs delete mode 100644 sources/Dot.Domain/IGameApplication.cs delete mode 100644 sources/Dot.Domain/ModuleModel/IModule.cs delete mode 100644 sources/Dot.Domain/ModuleModel/ModuleRunExceptionEventArgs.cs create mode 100644 sources/Dot.GameAccess/JCondition.cs create mode 100644 sources/Dot.GameHosting/Dot.GameHosting.csproj create mode 100644 sources/Dot.GameHosting/IModule.cs create mode 100644 sources/Dot.GameHosting/IModuleHost.cs rename sources/{Dot.Domain/ModuleModel => Dot.GameHosting}/ModuleEngine.cs (96%) rename sources/{Dot.Domain/ModuleModel => Dot.GameHosting}/ModuleNotFoundException.cs (93%) create mode 100644 sources/Dot.GameHosting/ModuleRunExceptionEventArgs.cs rename sources/{Dot.Domain/ModuleModel => Dot.GameHosting}/NoModulesException.cs (93%) create mode 100644 sources/Dot.GameHosting/StandardModuleHost.cs create mode 100644 sources/Dot.Ports.PresentationAccess/Dot.Ports.PresentationAccess.csproj create mode 100644 sources/Dot.Ports.PresentationAccess/IPresentation.cs delete mode 100644 sources/Dot.Presentation/StandardGameApplication.cs create mode 100644 sources/Dot.PresentationAccess/Dot.PresentationAccess.csproj create mode 100644 sources/Dot.PresentationAccess/Presentation.cs diff --git a/sources/Directory.Build.props b/sources/Directory.Build.props index 894f35d..f38fe9c 100644 --- a/sources/Directory.Build.props +++ b/sources/Directory.Build.props @@ -3,8 +3,8 @@ Dust in the Wind Dust in the Wind - Copyright © 2020 Dust in the wind - 1.0.0.0 + Copyright © 2020-2024 Dust in the wind + 2.0.0.0 Dot diff --git a/sources/Dot.Application/Dot.Application.csproj b/sources/Dot.Application/Dot.Application.csproj index c84d9d6..4012d53 100644 --- a/sources/Dot.Application/Dot.Application.csproj +++ b/sources/Dot.Application/Dot.Application.csproj @@ -9,6 +9,7 @@ + diff --git a/sources/Dot.Application/GameHostActions/ExitAction.cs b/sources/Dot.Application/GameHostActions/ExitAction.cs index 7622951..d0ecb67 100644 --- a/sources/Dot.Application/GameHostActions/ExitAction.cs +++ b/sources/Dot.Application/GameHostActions/ExitAction.cs @@ -1,46 +1,61 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; +using Dot.GameHosting; using DustInTheWind.Dot.AdventureGame.ActionModel; -using DustInTheWind.Dot.Domain; -namespace DustInTheWind.Dot.Application.GameHostActions +namespace DustInTheWind.Dot.Application.GameHostActions; + +public class ExitAction : ActionBase { - public class ExitAction : ActionBase - { - private readonly IGameApplication gameApplication; + private readonly IModuleHost moduleHost; - public ExitAction(IGameApplication gameApplication) - : base("exit", "quit", "x") - { - this.gameApplication = gameApplication ?? throw new ArgumentNullException(nameof(gameApplication)); - } + public ExitAction(IModuleHost moduleHost) + : base("exit", "quit", "x") + { + this.moduleHost = moduleHost ?? throw new ArgumentNullException(nameof(moduleHost)); + } - public override string Description => "Exits the game."; + public override string Description => "Exits the game."; - public override List Usage => new List { "<<:exit>>", "<<:quit>>", "<<:x>>" }; + public override List Usage => new() { "<<:exit>>", "<<:quit>>", "<<:x>>" }; - public override ActionType ActionType => ActionType.EnvironmentCommand; + public override ActionType ActionType => ActionType.EnvironmentCommand; - protected override List CreateMatchers() + protected override List CreateMatchers() + { + return new List { - return new List - { - new Regex(@"^\s*(:exit|:quit|:x)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) - }; - } + new(@"^\s*(:exit|:quit|:x)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) + }; + } - protected override string[] ExtractParameters(Match match) - { - return new string[0]; - } + protected override string[] ExtractParameters(Match match) + { + return Array.Empty(); + } - public override IEnumerable Execute(params object[] parameters) - { - gameApplication.Close(); + public override IEnumerable Execute(params object[] parameters) + { + moduleHost.Close(); - yield break; - } + yield break; } } \ No newline at end of file diff --git a/sources/Dot.Application/GameHostActions/LoadGameAction.cs b/sources/Dot.Application/GameHostActions/LoadGameAction.cs index 1d0b129..bdd11e5 100644 --- a/sources/Dot.Application/GameHostActions/LoadGameAction.cs +++ b/sources/Dot.Application/GameHostActions/LoadGameAction.cs @@ -1,3 +1,19 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System; using System.Collections; using System.Collections.Generic; @@ -5,43 +21,42 @@ using DustInTheWind.Dot.AdventureGame.ActionModel; using DustInTheWind.Dot.Application.UseCases.LoadGame; -namespace DustInTheWind.Dot.Application.GameHostActions +namespace DustInTheWind.Dot.Application.GameHostActions; + +public class LoadGameAction : ActionBase { - public class LoadGameAction : ActionBase - { - private readonly IUseCaseFactory useCaseFactory; + private readonly IUseCaseFactory useCaseFactory; - public LoadGameAction(IUseCaseFactory useCaseFactory) - : base("load") - { - this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); - } + public LoadGameAction(IUseCaseFactory useCaseFactory) + : base("load") + { + this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); + } - public override string Description => "Loads a previously saved game."; + public override string Description => "Loads a previously saved game."; - public override List Usage => new List { "<<:load>>" }; + public override List Usage => new() { "<<:load>>" }; - public override ActionType ActionType => ActionType.EnvironmentCommand; + public override ActionType ActionType => ActionType.EnvironmentCommand; - protected override List CreateMatchers() + protected override List CreateMatchers() + { + return new List { - return new List - { - new Regex(@"^\s*:load\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) - }; - } + new(@"^\s*:load\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) + }; + } - protected override string[] ExtractParameters(Match match) - { - return new string[0]; - } + protected override string[] ExtractParameters(Match match) + { + return Array.Empty(); + } - public override IEnumerable Execute(params object[] parameters) - { - LoadGameUseCase useCase = useCaseFactory.Create(); - useCase.Execute(); + public override IEnumerable Execute(params object[] parameters) + { + LoadGameUseCase useCase = useCaseFactory.Create(); + useCase.Execute(); - yield break; - } + yield break; } } \ No newline at end of file diff --git a/sources/Dot.Application/GameHostActions/MainMenuAction.cs b/sources/Dot.Application/GameHostActions/MainMenuAction.cs index 04fa478..cb5ab24 100644 --- a/sources/Dot.Application/GameHostActions/MainMenuAction.cs +++ b/sources/Dot.Application/GameHostActions/MainMenuAction.cs @@ -1,46 +1,61 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System; using System.Collections; using System.Collections.Generic; using System.Text.RegularExpressions; +using Dot.GameHosting; using DustInTheWind.Dot.AdventureGame.ActionModel; -using DustInTheWind.Dot.Domain.ModuleModel; -namespace DustInTheWind.Dot.Application.GameHostActions +namespace DustInTheWind.Dot.Application.GameHostActions; + +public class MainMenuAction : ActionBase { - public class MainMenuAction : ActionBase - { - private readonly ModuleEngine moduleEngine; + private readonly ModuleEngine moduleEngine; - public MainMenuAction(ModuleEngine moduleEngine) - : base("menu", "m") - { - this.moduleEngine = moduleEngine ?? throw new ArgumentNullException(nameof(moduleEngine)); - } + public MainMenuAction(ModuleEngine moduleEngine) + : base("menu", "m") + { + this.moduleEngine = moduleEngine ?? throw new ArgumentNullException(nameof(moduleEngine)); + } - public override string Description => "Displays the main menu of the game."; + public override string Description => "Displays the main menu of the game."; - public override List Usage => new List { "<<:menu>>", "<<:m>>" }; + public override List Usage => new() { "<<:menu>>", "<<:m>>" }; - public override ActionType ActionType => ActionType.EnvironmentCommand; + public override ActionType ActionType => ActionType.EnvironmentCommand; - protected override List CreateMatchers() + protected override List CreateMatchers() + { + return new List { - return new List - { - new Regex(@"^\s*(:menu|:m)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) - }; - } + new(@"^\s*(:menu|:m)\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) + }; + } - protected override string[] ExtractParameters(Match match) - { - return new string[0]; - } + protected override string[] ExtractParameters(Match match) + { + return Array.Empty(); + } - public override IEnumerable Execute(params object[] parameters) - { - moduleEngine.RequestToChangeModule("main-menu"); + public override IEnumerable Execute(params object[] parameters) + { + moduleEngine.RequestToChangeModule("main-menu"); - yield break; - } + yield break; } } \ No newline at end of file diff --git a/sources/Dot.Application/GameHostActions/NewGameAction.cs b/sources/Dot.Application/GameHostActions/NewGameAction.cs index 913fbe4..57b206e 100644 --- a/sources/Dot.Application/GameHostActions/NewGameAction.cs +++ b/sources/Dot.Application/GameHostActions/NewGameAction.cs @@ -1,3 +1,19 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System; using System.Collections; using System.Collections.Generic; @@ -5,43 +21,42 @@ using DustInTheWind.Dot.AdventureGame.ActionModel; using DustInTheWind.Dot.Application.UseCases.NewGame; -namespace DustInTheWind.Dot.Application.GameHostActions +namespace DustInTheWind.Dot.Application.GameHostActions; + +public class NewGameAction : ActionBase { - public class NewGameAction : ActionBase - { - private readonly IUseCaseFactory useCaseFactory; + private readonly IUseCaseFactory useCaseFactory; - public NewGameAction(IUseCaseFactory useCaseFactory) - : base("new") - { - this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); - } + public NewGameAction(IUseCaseFactory useCaseFactory) + : base("new") + { + this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); + } - public override string Description => "Starts a new game."; + public override string Description => "Starts a new game."; - public override List Usage => new List { "<<:new>>" }; + public override List Usage => new() { "<<:new>>" }; - public override ActionType ActionType => ActionType.EnvironmentCommand; + public override ActionType ActionType => ActionType.EnvironmentCommand; - protected override List CreateMatchers() + protected override List CreateMatchers() + { + return new List { - return new List - { - new Regex(@"^\s*:new\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) - }; - } + new(@"^\s*:new\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) + }; + } - protected override string[] ExtractParameters(Match match) - { - return new string[0]; - } + protected override string[] ExtractParameters(Match match) + { + return Array.Empty(); + } - public override IEnumerable Execute(params object[] parameters) - { - CreateNewGameUseCase useCase = useCaseFactory.Create(); - useCase.Execute(); + public override IEnumerable Execute(params object[] parameters) + { + CreateNewGameUseCase useCase = useCaseFactory.Create(); + useCase.Execute(); - yield break; - } + yield break; } } \ No newline at end of file diff --git a/sources/Dot.Application/GameHostActions/SaveGameAction.cs b/sources/Dot.Application/GameHostActions/SaveGameAction.cs index 571174d..f833bdc 100644 --- a/sources/Dot.Application/GameHostActions/SaveGameAction.cs +++ b/sources/Dot.Application/GameHostActions/SaveGameAction.cs @@ -1,3 +1,19 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + using System; using System.Collections; using System.Collections.Generic; @@ -5,43 +21,42 @@ using DustInTheWind.Dot.AdventureGame.ActionModel; using DustInTheWind.Dot.Application.UseCases.SaveGame; -namespace DustInTheWind.Dot.Application.GameHostActions +namespace DustInTheWind.Dot.Application.GameHostActions; + +public class SaveGameAction : ActionBase { - public class SaveGameAction : ActionBase - { - private readonly IUseCaseFactory useCaseFactory; + private readonly IUseCaseFactory useCaseFactory; - public SaveGameAction(IUseCaseFactory useCaseFactory) - : base("save") - { - this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); - } + public SaveGameAction(IUseCaseFactory useCaseFactory) + : base("save") + { + this.useCaseFactory = useCaseFactory ?? throw new ArgumentNullException(nameof(useCaseFactory)); + } - public override string Description => "Saves the current game."; + public override string Description => "Saves the current game."; - public override List Usage => new List { "<<:save>>" }; + public override List Usage => new() { "<<:save>>" }; - public override ActionType ActionType => ActionType.EnvironmentCommand; + public override ActionType ActionType => ActionType.EnvironmentCommand; - protected override List CreateMatchers() + protected override List CreateMatchers() + { + return new List { - return new List - { - new Regex(@"^\s*:save\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) - }; - } + new(@"^\s*:save\s*$", RegexOptions.IgnoreCase | RegexOptions.Singleline) + }; + } - protected override string[] ExtractParameters(Match match) - { - return new string[0]; - } + protected override string[] ExtractParameters(Match match) + { + return Array.Empty(); + } - public override IEnumerable Execute(params object[] parameters) - { - SaveGameUseCase useCase = useCaseFactory.Create(); - useCase.Execute(); + public override IEnumerable Execute(params object[] parameters) + { + SaveGameUseCase useCase = useCaseFactory.Create(); + useCase.Execute(); - yield break; - } + yield break; } } \ No newline at end of file diff --git a/sources/Dot.Application/UseCases/LoadGame/LoadGameUseCase.cs b/sources/Dot.Application/UseCases/LoadGame/LoadGameUseCase.cs index 9410010..aaf4750 100644 --- a/sources/Dot.Application/UseCases/LoadGame/LoadGameUseCase.cs +++ b/sources/Dot.Application/UseCases/LoadGame/LoadGameUseCase.cs @@ -1,9 +1,9 @@ using System; using System.Collections.Generic; +using Dot.GameHosting; using DustInTheWind.Dot.Application.UseCases.SaveGame; using DustInTheWind.Dot.Domain.DataAccess; using DustInTheWind.Dot.Domain.GameModel; -using DustInTheWind.Dot.Domain.ModuleModel; using DustInTheWind.Dot.Ports.GameSavesAccess; namespace DustInTheWind.Dot.Application.UseCases.LoadGame diff --git a/sources/Dot.Application/UseCases/NewGame/CreateNewGameUseCase.cs b/sources/Dot.Application/UseCases/NewGame/CreateNewGameUseCase.cs index d0d955b..4e43a8c 100644 --- a/sources/Dot.Application/UseCases/NewGame/CreateNewGameUseCase.cs +++ b/sources/Dot.Application/UseCases/NewGame/CreateNewGameUseCase.cs @@ -1,7 +1,7 @@ using System; +using Dot.GameHosting; using DustInTheWind.Dot.Domain.DataAccess; using DustInTheWind.Dot.Domain.GameModel; -using DustInTheWind.Dot.Domain.ModuleModel; namespace DustInTheWind.Dot.Application.UseCases.NewGame { diff --git a/sources/Dot.Application/UseCases/ResumeGame/ResumeGameUseCase.cs b/sources/Dot.Application/UseCases/ResumeGame/ResumeGameUseCase.cs index dd7fd1b..6e8ac98 100644 --- a/sources/Dot.Application/UseCases/ResumeGame/ResumeGameUseCase.cs +++ b/sources/Dot.Application/UseCases/ResumeGame/ResumeGameUseCase.cs @@ -1,5 +1,5 @@ using System; -using DustInTheWind.Dot.Domain.ModuleModel; +using Dot.GameHosting; namespace DustInTheWind.Dot.Application.UseCases.ResumeGame { diff --git a/sources/Dot.Bootstrapping/BootstrapperBase.cs b/sources/Dot.Bootstrapping/BootstrapperBase.cs index 2dfacf0..18c413e 100644 --- a/sources/Dot.Bootstrapping/BootstrapperBase.cs +++ b/sources/Dot.Bootstrapping/BootstrapperBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Dot.GameHosting; using DustInTheWind.Dot.AdventureGame; using DustInTheWind.Dot.AdventureGame.ActionModel; using DustInTheWind.Dot.Application.UseCases.LoadGame; @@ -9,7 +10,6 @@ using DustInTheWind.Dot.Domain; using DustInTheWind.Dot.Domain.DataAccess; using DustInTheWind.Dot.Domain.GameModel; -using DustInTheWind.Dot.Domain.ModuleModel; using DustInTheWind.Dot.GameSavesAccess; using DustInTheWind.Dot.Ports.GameSavesAccess; using DustInTheWind.Dot.Presentation; @@ -27,8 +27,8 @@ public void Run() IServiceProvider serviceProvider = servicesContainer.BuildServiceProvider(); - IGameApplication application = serviceProvider.GetService(); - application.Run(); + IModuleHost host = serviceProvider.GetService(); + host.Run(); } protected abstract IServicesContainer CreateServicesContainer(); @@ -54,7 +54,7 @@ protected virtual void ConfigureServices(IServicesContainer servicesContainer) Type applicationType = RetrieveApplicationType(); if (applicationType != null) - servicesContainer.AddSingleton(typeof(IGameApplication), applicationType); + servicesContainer.AddSingleton(typeof(IModuleHost), applicationType); Type gameType = RetrieveGameType(); if (gameType != null) @@ -64,7 +64,7 @@ protected virtual void ConfigureServices(IServicesContainer servicesContainer) private static Type RetrieveApplicationType() { return GetAllClientTypes() - .FirstOrDefault(x => typeof(IGameApplication).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract); + .FirstOrDefault(x => typeof(IModuleHost).IsAssignableFrom(x) && x.IsClass && !x.IsAbstract); } private static Type RetrieveGameType() diff --git a/sources/Dot.Bootstrapping/Dot.Bootstrapping.csproj b/sources/Dot.Bootstrapping/Dot.Bootstrapping.csproj index fa79200..23547d1 100644 --- a/sources/Dot.Bootstrapping/Dot.Bootstrapping.csproj +++ b/sources/Dot.Bootstrapping/Dot.Bootstrapping.csproj @@ -7,6 +7,7 @@ + diff --git a/sources/Dot.Demo/Bootstrapper.cs b/sources/Dot.Demo/Bootstrapper.cs index bed4177..a99c247 100644 --- a/sources/Dot.Demo/Bootstrapper.cs +++ b/sources/Dot.Demo/Bootstrapper.cs @@ -1,20 +1,35 @@ -using DustInTheWind.Dot.Bootstrapping; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using DustInTheWind.Dot.Bootstrapping; using DustInTheWind.Dot.Ninject; -namespace DustInTheWind.Dot.Demo +namespace DustInTheWind.Dot.Demo; + +internal class Bootstrapper : BootstrapperBase { - internal class Bootstrapper : BootstrapperBase + protected override IServicesContainer CreateServicesContainer() { - protected override IServicesContainer CreateServicesContainer() - { - return new NinjectServicesContainer(); - } + return new NinjectServicesContainer(); + } - protected override void ConfigureServices(IServicesContainer servicesContainer) - { - base.ConfigureServices(servicesContainer); + protected override void ConfigureServices(IServicesContainer servicesContainer) + { + base.ConfigureServices(servicesContainer); - servicesContainer.ConfigureFactories(); - } + servicesContainer.ConfigureFactories(); } } \ No newline at end of file diff --git a/sources/Dot.Demo/DemoGame.cs b/sources/Dot.Demo/DemoGame.cs index 51e8d3b..b398683 100644 --- a/sources/Dot.Demo/DemoGame.cs +++ b/sources/Dot.Demo/DemoGame.cs @@ -1,19 +1,34 @@ -using DustInTheWind.Dot.AdventureGame.GameModel; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using DustInTheWind.Dot.AdventureGame.GameModel; using DustInTheWind.Dot.Demo.Objects; -namespace DustInTheWind.Dot.Demo +namespace DustInTheWind.Dot.Demo; + +internal sealed class DemoGame : StandardGame { - internal sealed class DemoGame : StandardGame + public override void InitializeNew() { - public override void InitializeNew() - { - ParkLocation parkLocation = new ParkLocation(); - parkLocation.InitializeNew(); - AddLocation(parkLocation); + ParkLocation parkLocation = new(); + parkLocation.InitializeNew(); + AddLocation(parkLocation); - CrossroadsLocation crossroadsLocation = new CrossroadsLocation(); - crossroadsLocation.InitializeNew(); - AddLocation(crossroadsLocation); - } + CrossroadsLocation crossroadsLocation = new(); + crossroadsLocation.InitializeNew(); + AddLocation(crossroadsLocation); } } \ No newline at end of file diff --git a/sources/Dot.Demo/Dot.Demo.csproj b/sources/Dot.Demo/Dot.Demo.csproj index 6e09398..8fc91e9 100644 --- a/sources/Dot.Demo/Dot.Demo.csproj +++ b/sources/Dot.Demo/Dot.Demo.csproj @@ -27,6 +27,7 @@ + diff --git a/sources/Dot.Demo/GameApplication.cs b/sources/Dot.Demo/GameApplication.cs deleted file mode 100644 index 0c88652..0000000 --- a/sources/Dot.Demo/GameApplication.cs +++ /dev/null @@ -1,14 +0,0 @@ -using DustInTheWind.Dot.Domain.ModuleModel; -using DustInTheWind.Dot.Presentation; -using DustInTheWind.Dot.Presentation.Views; - -namespace DustInTheWind.Dot.Demo -{ - internal class GameApplication : StandardGameApplication - { - public GameApplication(ApplicationView view, ModuleEngine moduleEngine) - : base(view, moduleEngine) - { - } - } -} \ No newline at end of file diff --git a/sources/Dot.Demo/ModuleHost.cs b/sources/Dot.Demo/ModuleHost.cs new file mode 100644 index 0000000..2d23c5b --- /dev/null +++ b/sources/Dot.Demo/ModuleHost.cs @@ -0,0 +1,28 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using Dot.GameHosting; +using DustInTheWind.Dot.Ports.PresentationAccess; + +namespace DustInTheWind.Dot.Demo; + +internal class ModuleHost : StandardModuleHost +{ + public ModuleHost(IPresentation presentation, ModuleEngine moduleEngine) + : base(presentation, moduleEngine) + { + } +} \ No newline at end of file diff --git a/sources/Dot.Demo/Objects/Acorn.cs b/sources/Dot.Demo/Objects/Acorn.cs index 7704ee3..0653b4b 100644 --- a/sources/Dot.Demo/Objects/Acorn.cs +++ b/sources/Dot.Demo/Objects/Acorn.cs @@ -1,37 +1,52 @@ -using System.Collections; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections; using DustInTheWind.Dot.AdventureGame.ActionResults; using DustInTheWind.Dot.AdventureGame.ObjectModel; using DustInTheWind.Dot.Domain.AudioTextModel; -namespace DustInTheWind.Dot.Demo.Objects +namespace DustInTheWind.Dot.Demo.Objects; + +internal class Acorn : ObjectBase, ITakeable { - internal class Acorn : ObjectBase, ITakeable - { - public override string Id => "acorn"; + public override string Id => "acorn"; + + public override string Name => "acorn"; - public override string Name => "acorn"; + public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.acorn.ascii"; - public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.acorn.ascii"; + public override IEnumerable LookAt() + { + yield return CreateDescriptionStory(new AudioText + { + Text = "An acorn." + }); + } - public override IEnumerable LookAt() + public IEnumerable Take() + { + yield return CreateDescriptionStory(new AudioText { - yield return CreateDescriptionStory(new AudioText - { - Text = "An acorn." - }); - } + Text = "You take the acorn and put it in your pocket." + }); - public IEnumerable Take() + yield return new AcquireObjectsResult { - yield return CreateDescriptionStory(new AudioText - { - Text = "You take the acorn and put it in your pocket." - }); - - yield return new AcquireObjectsResult - { - Objects = new[] { this } - }; - } + Objects = new[] { this } + }; } } \ No newline at end of file diff --git a/sources/Dot.Demo/Objects/CrossroadsLocation.cs b/sources/Dot.Demo/Objects/CrossroadsLocation.cs index d55c798..80333b0 100644 --- a/sources/Dot.Demo/Objects/CrossroadsLocation.cs +++ b/sources/Dot.Demo/Objects/CrossroadsLocation.cs @@ -1,32 +1,47 @@ -using System.Collections; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections; using DustInTheWind.Dot.AdventureGame.LocationModel; using DustInTheWind.Dot.Domain.AudioTextModel; -namespace DustInTheWind.Dot.Demo.Objects +namespace DustInTheWind.Dot.Demo.Objects; + +internal class CrossroadsLocation : LocationBase { - internal class CrossroadsLocation : LocationBase - { - public override string Id { get; } = "crossroads"; + public override string Id { get; } = "crossroads"; - public override string Name { get; } = "Crossroads"; + public override string Name { get; } = "Crossroads"; - public override void InitializeNew() - { - } + public override void InitializeNew() + { + } - public override IEnumerable LookAt() + public override IEnumerable LookAt() + { + yield return CreateDescriptionStory(new AudioText { - yield return CreateDescriptionStory(new AudioText - { - Text = "The cars are making allot of noise." - }); - - MakeAllChildrenVisible(); - } + Text = "The cars are making allot of noise." + }); - public override AudioText ResumeDescription { get; } = new AudioText - { - Text = "You are back in the city, next to the crossroads. The cars are making allot of noise." - }; + MakeAllChildrenVisible(); } + + public override AudioText ResumeDescription { get; } = new() + { + Text = "You are back in the city, next to the crossroads. The cars are making allot of noise." + }; } \ No newline at end of file diff --git a/sources/Dot.Demo/Objects/NorthRoad.cs b/sources/Dot.Demo/Objects/NorthRoad.cs index 740aebc..1104e47 100644 --- a/sources/Dot.Demo/Objects/NorthRoad.cs +++ b/sources/Dot.Demo/Objects/NorthRoad.cs @@ -1,32 +1,47 @@ -using System.Collections; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections; using DustInTheWind.Dot.AdventureGame.ActionResults; using DustInTheWind.Dot.AdventureGame.ObjectModel; using DustInTheWind.Dot.Domain.AudioTextModel; -namespace DustInTheWind.Dot.Demo.Objects +namespace DustInTheWind.Dot.Demo.Objects; + +internal class NorthRoad : ObjectBase, IExitWay { - internal class NorthRoad : ObjectBase, IExitWay - { - public override string Id { get; } = "north-road"; + public override string Id { get; } = "north-road"; - public override string Name { get; } = "north road"; + public override string Name { get; } = "north road"; - public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.road.ascii"; + public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.road.ascii"; - public override IEnumerable LookAt() + public override IEnumerable LookAt() + { + yield return CreateDescriptionStory(new AudioText { - yield return CreateDescriptionStory(new AudioText - { - Text = "The road goes to the north." - }); - } + Text = "The road goes to the north." + }); + } - public IEnumerable Exit() + public IEnumerable Exit() + { + yield return new ChangeLocationResult { - yield return new ChangeLocationResult - { - DestinationId = "crossroads" - }; - } + DestinationId = "crossroads" + }; } } \ No newline at end of file diff --git a/sources/Dot.Demo/Objects/Oak.cs b/sources/Dot.Demo/Objects/Oak.cs index b91ede4..f61e2df 100644 --- a/sources/Dot.Demo/Objects/Oak.cs +++ b/sources/Dot.Demo/Objects/Oak.cs @@ -1,31 +1,46 @@ -using System.Collections; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections; using DustInTheWind.Dot.AdventureGame.ObjectModel; using DustInTheWind.Dot.Domain.AudioTextModel; -namespace DustInTheWind.Dot.Demo.Objects +namespace DustInTheWind.Dot.Demo.Objects; + +internal class Oak : ContainerObject { - internal class Oak : ContainerObject - { - public override string Id { get; } = "oak"; + public override string Id { get; } = "oak"; - public override string Name { get; } = "oak"; + public override string Name { get; } = "oak"; - public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.oak.ascii"; + public override string ImagePath { get; } = "DustInTheWind.Dot.Demo.Ascii.oak.ascii"; - public Oak() - { - Acorn acorn = new Acorn(); - AddObject(acorn); - } + public Oak() + { + Acorn acorn = new(); + AddObject(acorn); + } - public override IEnumerable LookAt() + public override IEnumerable LookAt() + { + yield return CreateDescriptionStory(new AudioText { - yield return CreateDescriptionStory(new AudioText - { - Text = "A tall oak. On the lowest branch there is a big {{acorn}}." - }); + Text = "A tall oak. On the lowest branch there is a big {{acorn}}." + }); - MakeAllChildrenVisible(); - } + MakeAllChildrenVisible(); } } \ No newline at end of file diff --git a/sources/Dot.Demo/Objects/ParkLocation.cs b/sources/Dot.Demo/Objects/ParkLocation.cs index 5cbcf58..7c63da2 100644 --- a/sources/Dot.Demo/Objects/ParkLocation.cs +++ b/sources/Dot.Demo/Objects/ParkLocation.cs @@ -1,47 +1,62 @@ -using System.Collections; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System.Collections; using DustInTheWind.Dot.AdventureGame.LocationModel; using DustInTheWind.Dot.Domain.AudioTextModel; -namespace DustInTheWind.Dot.Demo.Objects +namespace DustInTheWind.Dot.Demo.Objects; + +internal class ParkLocation : LocationBase { - internal class ParkLocation : LocationBase + public override string Id { get; } = "park"; + + public override string Name { get; } = "Park"; + + public override void InitializeNew() { - public override string Id { get; } = "park"; + Oak oak = new(); + AddObject(oak); - public override string Name { get; } = "Park"; + NorthRoad northRoad = new(); + AddObject(northRoad); + } - public override void InitializeNew() - { - Oak oak = new Oak(); - AddObject(oak); - - NorthRoad northRoad = new NorthRoad(); - AddObject(northRoad); - } - - public override IEnumerable LookAt() + public override IEnumerable LookAt() + { + yield return CreateDescriptionStory(new AudioTextList { - yield return CreateDescriptionStory(new AudioTextList + new AudioText { - new AudioText - { - Text = "You are standing in the middle of a beautiful park. " + - "Next to you there is a tall {{oak}}. " + - "You feel that you know that {{oak}} from a distant past, " + - "but you cannot remember anything else." - }, - new AudioText - { - Text = "Further, in the distance, to the north ({{north road}}), the city sounds can be heard." - } - }); - - MakeAllChildrenVisible(); - } - - public override AudioText ResumeDescription { get; } = new AudioText - { - Text = "You are back in the middle of the park, next to the tall oak." - }; + Text = "You are standing in the middle of a beautiful park. " + + "Next to you there is a tall {{oak}}. " + + "You feel that you know that {{oak}} from a distant past, " + + "but you cannot remember anything else." + }, + new AudioText + { + Text = "Further, in the distance, to the north ({{north road}}), the city sounds can be heard." + } + }); + + MakeAllChildrenVisible(); } + + public override AudioText ResumeDescription { get; } = new() + { + Text = "You are back in the middle of the park, next to the tall oak." + }; } \ No newline at end of file diff --git a/sources/Dot.Demo/Program.cs b/sources/Dot.Demo/Program.cs index b5d26af..a455d4c 100644 --- a/sources/Dot.Demo/Program.cs +++ b/sources/Dot.Demo/Program.cs @@ -1,24 +1,39 @@ -using System; +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using System; using DustInTheWind.Dot.Presentation.ConsoleHelpers.ConsoleUtil; -namespace DustInTheWind.Dot.Demo +namespace DustInTheWind.Dot.Demo; + +internal class Program { - internal class Program + private static void Main(string[] args) { - private static void Main(string[] args) + try + { + Bootstrapper bootstrapper = new(); + bootstrapper.Run(); + } + catch (Exception ex) { - try - { - Bootstrapper bootstrapper = new Bootstrapper(); - bootstrapper.Run(); - } - catch (Exception ex) - { - CustomConsole.WriteError("Fatal error"); - CustomConsole.WriteError(ex); + CustomConsole.WriteError("Fatal error"); + CustomConsole.WriteError(ex); - CustomConsole.Pause(); - } + CustomConsole.Pause(); } } } \ No newline at end of file diff --git a/sources/Dot.Domain/IGameApplication.cs b/sources/Dot.Domain/IGameApplication.cs deleted file mode 100644 index 35872e3..0000000 --- a/sources/Dot.Domain/IGameApplication.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace DustInTheWind.Dot.Domain -{ - public interface IGameApplication - { - void Run(); - - void Close(); - } -} \ No newline at end of file diff --git a/sources/Dot.Domain/ModuleModel/IModule.cs b/sources/Dot.Domain/ModuleModel/IModule.cs deleted file mode 100644 index b4abe63..0000000 --- a/sources/Dot.Domain/ModuleModel/IModule.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace DustInTheWind.Dot.Domain.ModuleModel -{ - public interface IModule - { - string Id { get; } - - string Run(); - - void RequestExit(); - } -} \ No newline at end of file diff --git a/sources/Dot.Domain/ModuleModel/ModuleRunExceptionEventArgs.cs b/sources/Dot.Domain/ModuleModel/ModuleRunExceptionEventArgs.cs deleted file mode 100644 index e746703..0000000 --- a/sources/Dot.Domain/ModuleModel/ModuleRunExceptionEventArgs.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace DustInTheWind.Dot.Domain.ModuleModel -{ - public class ModuleRunExceptionEventArgs : EventArgs - { - public Exception Exception { get; } - - public string NextModule { get; set; } - - public ModuleRunExceptionEventArgs(Exception ex) - { - Exception = ex; - } - } -} \ No newline at end of file diff --git a/sources/Dot.GameAccess/JActionStep.cs b/sources/Dot.GameAccess/JActionStep.cs index 9ae5200..aa9aaee 100644 --- a/sources/Dot.GameAccess/JActionStep.cs +++ b/sources/Dot.GameAccess/JActionStep.cs @@ -21,13 +21,4 @@ public class JActionStep public string Type { get; set; } public JCondition Condition { get; set; } -} - -public class JCondition -{ - public string Type { get; set; } - - public bool Exists { get; set; } - - public string Value { get; set; } } \ No newline at end of file diff --git a/sources/Dot.GameAccess/JCondition.cs b/sources/Dot.GameAccess/JCondition.cs new file mode 100644 index 0000000..8244dce --- /dev/null +++ b/sources/Dot.GameAccess/JCondition.cs @@ -0,0 +1,26 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace Dot.GameAccess; + +public class JCondition +{ + public string Type { get; set; } + + public bool Exists { get; set; } + + public string Value { get; set; } +} \ No newline at end of file diff --git a/sources/Dot.GameHosting/Dot.GameHosting.csproj b/sources/Dot.GameHosting/Dot.GameHosting.csproj new file mode 100644 index 0000000..b24c460 --- /dev/null +++ b/sources/Dot.GameHosting/Dot.GameHosting.csproj @@ -0,0 +1,12 @@ + + + + net6.0 + enable + + + + + + + diff --git a/sources/Dot.GameHosting/IModule.cs b/sources/Dot.GameHosting/IModule.cs new file mode 100644 index 0000000..704c814 --- /dev/null +++ b/sources/Dot.GameHosting/IModule.cs @@ -0,0 +1,26 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace Dot.GameHosting; + +public interface IModule +{ + string Id { get; } + + string Run(); + + void RequestExit(); +} \ No newline at end of file diff --git a/sources/Dot.GameHosting/IModuleHost.cs b/sources/Dot.GameHosting/IModuleHost.cs new file mode 100644 index 0000000..8da6096 --- /dev/null +++ b/sources/Dot.GameHosting/IModuleHost.cs @@ -0,0 +1,24 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace Dot.GameHosting; + +public interface IModuleHost +{ + void Run(); + + void Close(); +} \ No newline at end of file diff --git a/sources/Dot.Domain/ModuleModel/ModuleEngine.cs b/sources/Dot.GameHosting/ModuleEngine.cs similarity index 96% rename from sources/Dot.Domain/ModuleModel/ModuleEngine.cs rename to sources/Dot.GameHosting/ModuleEngine.cs index 6181acd..1ddcaf8 100644 --- a/sources/Dot.Domain/ModuleModel/ModuleEngine.cs +++ b/sources/Dot.GameHosting/ModuleEngine.cs @@ -14,11 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; -using System.Collections.Generic; -using System.Linq; - -namespace DustInTheWind.Dot.Domain.ModuleModel; +namespace Dot.GameHosting; public class ModuleEngine { diff --git a/sources/Dot.Domain/ModuleModel/ModuleNotFoundException.cs b/sources/Dot.GameHosting/ModuleNotFoundException.cs similarity index 93% rename from sources/Dot.Domain/ModuleModel/ModuleNotFoundException.cs rename to sources/Dot.GameHosting/ModuleNotFoundException.cs index 29c38f2..bae71bd 100644 --- a/sources/Dot.Domain/ModuleModel/ModuleNotFoundException.cs +++ b/sources/Dot.GameHosting/ModuleNotFoundException.cs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; - -namespace DustInTheWind.Dot.Domain.ModuleModel; +namespace Dot.GameHosting; public class ModuleNotFoundException : Exception { diff --git a/sources/Dot.GameHosting/ModuleRunExceptionEventArgs.cs b/sources/Dot.GameHosting/ModuleRunExceptionEventArgs.cs new file mode 100644 index 0000000..8c80221 --- /dev/null +++ b/sources/Dot.GameHosting/ModuleRunExceptionEventArgs.cs @@ -0,0 +1,29 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace Dot.GameHosting; + +public class ModuleRunExceptionEventArgs : EventArgs +{ + public Exception Exception { get; } + + public string NextModule { get; set; } + + public ModuleRunExceptionEventArgs(Exception ex) + { + Exception = ex; + } +} \ No newline at end of file diff --git a/sources/Dot.Domain/ModuleModel/NoModulesException.cs b/sources/Dot.GameHosting/NoModulesException.cs similarity index 93% rename from sources/Dot.Domain/ModuleModel/NoModulesException.cs rename to sources/Dot.GameHosting/NoModulesException.cs index a81551f..138514d 100644 --- a/sources/Dot.Domain/ModuleModel/NoModulesException.cs +++ b/sources/Dot.GameHosting/NoModulesException.cs @@ -14,9 +14,7 @@ // You should have received a copy of the GNU General Public License // along with this program. If not, see . -using System; - -namespace DustInTheWind.Dot.Domain.ModuleModel; +namespace Dot.GameHosting; public class NoModulesException : Exception { diff --git a/sources/Dot.GameHosting/StandardModuleHost.cs b/sources/Dot.GameHosting/StandardModuleHost.cs new file mode 100644 index 0000000..aa5ad5a --- /dev/null +++ b/sources/Dot.GameHosting/StandardModuleHost.cs @@ -0,0 +1,87 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using DustInTheWind.Dot.Ports.PresentationAccess; + +namespace Dot.GameHosting; + +public class StandardModuleHost : IModuleHost +{ + private volatile bool closeWasRequested; + + private readonly IPresentation presentation; + private readonly ModuleEngine moduleEngine; + + public StandardModuleHost(IPresentation presentation, ModuleEngine moduleEngine) + { + this.presentation = presentation ?? throw new ArgumentNullException(nameof(presentation)); + this.moduleEngine = moduleEngine ?? throw new ArgumentNullException(nameof(moduleEngine)); + + moduleEngine.ModuleRunException += HandleModuleRunException; + } + + protected void HandleModuleRunException(object sender, ModuleRunExceptionEventArgs e) + { + switch (e.Exception) + { + case NotImplementedException: + presentation.DisplayFunctionalityNotImplementedInfo(); + e.NextModule = "main-menu"; + break; + + case OperationCanceledException: + presentation.DisplayOperationCanceledInfo(); + e.NextModule = "main-menu"; + break; + + default: + presentation.DisplayError(e.Exception); + e.NextModule = null; + break; + } + } + + public void Run() + { + presentation.ResetConsoleWindow(); + presentation.DisplayApplicationHeader(); + + closeWasRequested = false; + + while (!closeWasRequested) + { + try + { + moduleEngine.Run(); + } + catch (OperationCanceledException) + { + } + catch (Exception ex) + { + presentation.DisplayError(ex); + } + } + + presentation.DisplayGoodByeMessage(); + } + + public void Close() + { + closeWasRequested = true; + moduleEngine.Close(); + } +} \ No newline at end of file diff --git a/sources/Dot.Ports.PresentationAccess/Dot.Ports.PresentationAccess.csproj b/sources/Dot.Ports.PresentationAccess/Dot.Ports.PresentationAccess.csproj new file mode 100644 index 0000000..b9a51e8 --- /dev/null +++ b/sources/Dot.Ports.PresentationAccess/Dot.Ports.PresentationAccess.csproj @@ -0,0 +1,10 @@ + + + + net6 + enable + DustInTheWind.Dot.Ports.PresentationAccess + DustInTheWind.Dot.Ports.PresentationAccess + + + \ No newline at end of file diff --git a/sources/Dot.Ports.PresentationAccess/IPresentation.cs b/sources/Dot.Ports.PresentationAccess/IPresentation.cs new file mode 100644 index 0000000..7bdc05e --- /dev/null +++ b/sources/Dot.Ports.PresentationAccess/IPresentation.cs @@ -0,0 +1,32 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +namespace DustInTheWind.Dot.Ports.PresentationAccess; + +public interface IPresentation +{ + void DisplayApplicationHeader(); + + void ResetConsoleWindow(); + + void DisplayFunctionalityNotImplementedInfo(); + + void DisplayOperationCanceledInfo(); + + void DisplayGoodByeMessage(); + + void DisplayError(Exception exception); +} \ No newline at end of file diff --git a/sources/Dot.Presentation/Commands/ExitCommand.cs b/sources/Dot.Presentation/Commands/ExitCommand.cs index 99f2c11..e3fcd80 100644 --- a/sources/Dot.Presentation/Commands/ExitCommand.cs +++ b/sources/Dot.Presentation/Commands/ExitCommand.cs @@ -1,4 +1,5 @@ using System; +using Dot.GameHosting; using DustInTheWind.Dot.Domain; using DustInTheWind.Dot.Presentation.ConsoleHelpers.UIControls; @@ -6,13 +7,13 @@ namespace DustInTheWind.Dot.Presentation.Commands { internal class ExitCommand : ICommand { - private readonly IGameApplication gameApplication; + private readonly IModuleHost moduleHost; public event EventHandler CanExecuteChanges; - public ExitCommand(IGameApplication gameApplication) + public ExitCommand(IModuleHost moduleHost) { - this.gameApplication = gameApplication ?? throw new ArgumentNullException(nameof(gameApplication)); + this.moduleHost = moduleHost ?? throw new ArgumentNullException(nameof(moduleHost)); } public bool CanExecute() @@ -22,7 +23,7 @@ public bool CanExecute() public void Execute() { - gameApplication.Close(); + moduleHost.Close(); } } } \ No newline at end of file diff --git a/sources/Dot.Presentation/Dot.Presentation.csproj b/sources/Dot.Presentation/Dot.Presentation.csproj index f2e8959..ec0e09d 100644 --- a/sources/Dot.Presentation/Dot.Presentation.csproj +++ b/sources/Dot.Presentation/Dot.Presentation.csproj @@ -20,6 +20,8 @@ + + diff --git a/sources/Dot.Presentation/Modules/GameModule.cs b/sources/Dot.Presentation/Modules/GameModule.cs index 0b583e9..db00c32 100644 --- a/sources/Dot.Presentation/Modules/GameModule.cs +++ b/sources/Dot.Presentation/Modules/GameModule.cs @@ -1,5 +1,5 @@ using System; -using DustInTheWind.Dot.Domain.ModuleModel; +using Dot.GameHosting; using DustInTheWind.Dot.Presentation.Presenters; namespace DustInTheWind.Dot.Presentation.Modules diff --git a/sources/Dot.Presentation/Modules/MenuModule.cs b/sources/Dot.Presentation/Modules/MenuModule.cs index 8de0498..2ad660d 100644 --- a/sources/Dot.Presentation/Modules/MenuModule.cs +++ b/sources/Dot.Presentation/Modules/MenuModule.cs @@ -1,5 +1,5 @@ using System; -using DustInTheWind.Dot.Domain.ModuleModel; +using Dot.GameHosting; using DustInTheWind.Dot.Presentation.ConsoleHelpers.ConsoleUtil; using DustInTheWind.Dot.Presentation.Presenters; diff --git a/sources/Dot.Presentation/Presenters/GamePresenter.cs b/sources/Dot.Presentation/Presenters/GamePresenter.cs index 74fd4c1..f196008 100644 --- a/sources/Dot.Presentation/Presenters/GamePresenter.cs +++ b/sources/Dot.Presentation/Presenters/GamePresenter.cs @@ -1,6 +1,7 @@ using System; using System.Collections; using System.Collections.Generic; +using Dot.GameHosting; using DustInTheWind.Dot.AdventureGame; using DustInTheWind.Dot.AdventureGame.ActionModel; using DustInTheWind.Dot.AdventureGame.ActionResultHandlers; @@ -12,7 +13,6 @@ using DustInTheWind.Dot.Domain.AudioTextModel; using DustInTheWind.Dot.Domain.DataAccess; using DustInTheWind.Dot.Domain.GameModel; -using DustInTheWind.Dot.Domain.ModuleModel; using DustInTheWind.Dot.Presentation.Views; namespace DustInTheWind.Dot.Presentation.Presenters @@ -78,9 +78,9 @@ internal class GamePresenter private readonly ActionSet actions = new ActionSet(); public GamePresenter(GameView gameView, GameRepository gameRepository, ResultHandlersCollection resultHandlers, - IGameApplication gameApplication, IUseCaseFactory useCaseFactory, ModuleEngine moduleEngine) + IModuleHost moduleHost, IUseCaseFactory useCaseFactory, ModuleEngine moduleEngine) { - if (gameApplication == null) throw new ArgumentNullException(nameof(gameApplication)); + if (moduleHost == null) throw new ArgumentNullException(nameof(moduleHost)); if (useCaseFactory == null) throw new ArgumentNullException(nameof(useCaseFactory)); if (moduleEngine == null) throw new ArgumentNullException(nameof(moduleEngine)); @@ -102,7 +102,7 @@ public GamePresenter(GameView gameView, GameRepository gameRepository, ResultHan actions.Add(new MainMenuAction(moduleEngine)); - actions.Add(new ExitAction(gameApplication)); + actions.Add(new ExitAction(moduleHost)); actions.Add(new NewGameAction(useCaseFactory)); actions.Add(new LoadGameAction(useCaseFactory)); actions.Add(new SaveGameAction(useCaseFactory)); diff --git a/sources/Dot.Presentation/StandardGameApplication.cs b/sources/Dot.Presentation/StandardGameApplication.cs deleted file mode 100644 index 058e0f3..0000000 --- a/sources/Dot.Presentation/StandardGameApplication.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using DustInTheWind.Dot.Domain; -using DustInTheWind.Dot.Domain.ModuleModel; -using DustInTheWind.Dot.Presentation.ConsoleHelpers.ConsoleUtil; -using DustInTheWind.Dot.Presentation.Views; - -namespace DustInTheWind.Dot.Presentation -{ - public class StandardGameApplication : IGameApplication - { - private volatile bool closeWasRequested; - - protected ApplicationView View { get; } - - protected ModuleEngine ModuleEngine { get; } - - public StandardGameApplication(ApplicationView view, ModuleEngine moduleEngine) - { - View = view ?? throw new ArgumentNullException(nameof(view)); - ModuleEngine = moduleEngine ?? throw new ArgumentNullException(nameof(moduleEngine)); - - moduleEngine.ModuleRunException += HandleModuleRunException; - } - - protected void HandleModuleRunException(object sender, ModuleRunExceptionEventArgs e) - { - switch (e.Exception) - { - case NotImplementedException _: - View.DisplayFunctionalityNotImplementedInfo(); - e.NextModule = "main-menu"; - break; - - case OperationCanceledException _: - View.DisplayOperationCanceledInfo(); - e.NextModule = "main-menu"; - break; - - default: - View.DisplayError(e.Exception); - e.NextModule = null; - break; - } - } - - public void Run() - { - View.ResetConsoleWindow(); - View.DisplayApplicationHeader(); - - closeWasRequested = false; - - while (!closeWasRequested) - { - try - { - ModuleEngine.Run(); - } - catch (OperationCanceledException) - { - } - catch (Exception ex) - { - CustomConsole.WriteError(ex); - } - } - - View.DisplayGoodByeMessage(); - } - - public void Close() - { - closeWasRequested = true; - ModuleEngine.Close(); - } - } -} \ No newline at end of file diff --git a/sources/Dot.Presentation/Views/ApplicationView.cs b/sources/Dot.Presentation/Views/ApplicationView.cs index ad09f68..a269f45 100644 --- a/sources/Dot.Presentation/Views/ApplicationView.cs +++ b/sources/Dot.Presentation/Views/ApplicationView.cs @@ -63,7 +63,7 @@ public void DisplayGoodByeMessage() public void DisplayError(Exception exception) { - CustomConsole.WriteError("Internal error occured. " + exception); + CustomConsole.WriteError("Internal error occurred. " + exception); } } } \ No newline at end of file diff --git a/sources/Dot.PresentationAccess/Dot.PresentationAccess.csproj b/sources/Dot.PresentationAccess/Dot.PresentationAccess.csproj new file mode 100644 index 0000000..211484e --- /dev/null +++ b/sources/Dot.PresentationAccess/Dot.PresentationAccess.csproj @@ -0,0 +1,16 @@ + + + + net6 + enable + DustInTheWind.Dot.PresentationAccess + DustInTheWind.Dot.PresentationAccess + + + + + + + + + \ No newline at end of file diff --git a/sources/Dot.PresentationAccess/Presentation.cs b/sources/Dot.PresentationAccess/Presentation.cs new file mode 100644 index 0000000..5b6149d --- /dev/null +++ b/sources/Dot.PresentationAccess/Presentation.cs @@ -0,0 +1,60 @@ +// Dot +// Copyright (C) 2020-2024 Dust in the Wind +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +using DustInTheWind.Dot.Ports.PresentationAccess; +using DustInTheWind.Dot.Presentation.Views; + +namespace DustInTheWind.Dot.PresentationAccess; + +public class Presentation : IPresentation +{ + private readonly ApplicationView applicationView; + + public Presentation(ApplicationView applicationView) + { + this.applicationView = applicationView ?? throw new ArgumentNullException(nameof(applicationView)); + } + + public void DisplayApplicationHeader() + { + applicationView.DisplayApplicationHeader(); + } + + public void ResetConsoleWindow() + { + applicationView.ResetConsoleWindow(); + } + + public void DisplayFunctionalityNotImplementedInfo() + { + applicationView.DisplayFunctionalityNotImplementedInfo(); + } + + public void DisplayOperationCanceledInfo() + { + applicationView.DisplayOperationCanceledInfo(); + } + + public void DisplayGoodByeMessage() + { + applicationView.DisplayGoodByeMessage(); + } + + public void DisplayError(Exception exception) + { + applicationView.DisplayError(exception); + } +} \ No newline at end of file diff --git a/sources/Dot.sln b/sources/Dot.sln index 9845976..6c534bd 100644 --- a/sources/Dot.sln +++ b/sources/Dot.sln @@ -44,6 +44,12 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Dot.GameAccess", "Dot.GameA EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "GameModules", "GameModules", "{D6C42C04-865B-49FA-93A3-8AED5107B720}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dot.Ports.PresentationAccess", "Dot.Ports.PresentationAccess\Dot.Ports.PresentationAccess.csproj", "{C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dot.PresentationAccess", "Dot.PresentationAccess\Dot.PresentationAccess.csproj", "{002450D7-CAFB-4BF2-96D3-929F53046BE3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Dot.GameHosting", "Dot.GameHosting\Dot.GameHosting.csproj", "{238CCE62-0221-4220-8C2E-3AAF509108CA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -110,6 +116,18 @@ Global {C8FF28A9-0950-4170-9F25-8A985D369A0E}.Debug|Any CPU.Build.0 = Debug|Any CPU {C8FF28A9-0950-4170-9F25-8A985D369A0E}.Release|Any CPU.ActiveCfg = Release|Any CPU {C8FF28A9-0950-4170-9F25-8A985D369A0E}.Release|Any CPU.Build.0 = Release|Any CPU + {C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72}.Release|Any CPU.Build.0 = Release|Any CPU + {002450D7-CAFB-4BF2-96D3-929F53046BE3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {002450D7-CAFB-4BF2-96D3-929F53046BE3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {002450D7-CAFB-4BF2-96D3-929F53046BE3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {002450D7-CAFB-4BF2-96D3-929F53046BE3}.Release|Any CPU.Build.0 = Release|Any CPU + {238CCE62-0221-4220-8C2E-3AAF509108CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {238CCE62-0221-4220-8C2E-3AAF509108CA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {238CCE62-0221-4220-8C2E-3AAF509108CA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {238CCE62-0221-4220-8C2E-3AAF509108CA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -119,6 +137,8 @@ Global {944619C8-D290-4278-832C-3DB434C86E3D} = {5AACFF78-6728-4D14-862E-E6BAF36A5317} {8134FA14-3C3E-4E16-8E6B-8EC9AF02347F} = {1729746B-38CB-4296-A467-9147E1367C94} {C8FF28A9-0950-4170-9F25-8A985D369A0E} = {5AACFF78-6728-4D14-862E-E6BAF36A5317} + {C23A9E50-AA5D-4E57-ABD5-BE90A08ECA72} = {1729746B-38CB-4296-A467-9147E1367C94} + {002450D7-CAFB-4BF2-96D3-929F53046BE3} = {5AACFF78-6728-4D14-862E-E6BAF36A5317} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {337FF7E9-B5A4-4D8E-953F-FB64A69C238D}