support different setup models

This commit is contained in:
beo3000 2025-11-27 18:06:45 +01:00
parent d07c9049e4
commit b3b4d01130
21 changed files with 161 additions and 63 deletions

View File

@ -1,4 +1,5 @@
@using KoogleApp.Components.Dialogs @using KoogleApp.Components.Dialogs
@using KoogleApp.Games
@using KoogleApp.Model @using KoogleApp.Model
@using KoogleApp.Store.DayFeature @using KoogleApp.Store.DayFeature
@using KoogleApp.Store.Game.Participants @using KoogleApp.Store.Game.Participants
@ -59,7 +60,7 @@
var dialog = await DialogService.ShowAsync<StartGameDialog>("Spiel starten", parameters, options); var dialog = await DialogService.ShowAsync<StartGameDialog>("Spiel starten", parameters, options);
var result = await dialog.Result; var result = await dialog.Result;
var startParams = result.Data as StartParams; var startParams = result.Data as IGameSetupModel;
if (!result.Canceled) if (!result.Canceled)
{ {
var action = new StartStopAction(ThrowPanelState.Value, startParams); var action = new StartStopAction(ThrowPanelState.Value, startParams);

View File

@ -101,13 +101,23 @@
private void Start() private void Start()
{ {
MudDialog.Close(DialogResult.Ok(new StartParams( var setupModel = Activator.CreateInstance(_selectedGameType.SetupModelType) as IGameSetupModel;
DayState.Value.Id, setupModel.ParticipantsMode = SetupState.Value.ParticipantsMode;
SetupState.Value.ThrowMode, setupModel.ThrowMode = SetupState.Value.ThrowMode;
SetupState.Value.ThrowsPerRound, setupModel.ThrowsPerRound = SetupState.Value.ThrowsPerRound;
PlayerIds, setupModel.Participants = PlayerIds;
SetupState.Value.ParticipantsMode, setupModel.DayId = DayState.Value.Id;
SetupState.Value.Game.GetType().Name setupModel.KnownGameType = SetupState.Value.Game.GetType().Name;
)));
// MudDialog.Close(DialogResult.Ok(new StartParams(
// DayState.Value.Id,
// SetupState.Value.ThrowMode,
// SetupState.Value.ThrowsPerRound,
// PlayerIds,
// SetupState.Value.ParticipantsMode,
// SetupState.Value.Game.GetType().Name
// )));
MudDialog.Close(DialogResult.Ok(setupModel));
} }
} }

View File

@ -47,7 +47,7 @@
@* @DayState.Value *@ @* @DayState.Value *@
@GetParticipantsState() @GetParticipantsState()
@* @StartParams(); *@ @* @SetupModel(); *@
@if (DayState.Value.Status != DayStatus.Started) @if (DayState.Value.Status != DayStatus.Started)
{ {

View File

@ -1,5 +1,6 @@
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
using Fluxor; using Fluxor;
using KoogleApp.Games.Shit;
using KoogleApp.Games.Training; using KoogleApp.Games.Training;
using KoogleApp.Model; using KoogleApp.Model;
using KoogleApp.Store.Game.ThrowPanel; using KoogleApp.Store.Game.ThrowPanel;
@ -7,22 +8,42 @@ using KoogleApp.Store.Game.ThrowPanel;
namespace KoogleApp.Games namespace KoogleApp.Games
{ {
[JsonDerivedType(typeof(TrainingState), typeDiscriminator: "TrainingState")] [JsonDerivedType(typeof(TrainingState), typeDiscriminator: "TrainingState")]
//[JsonDerivedType(typeof(v2), typeDiscriminator: "v2")] [JsonDerivedType(typeof(ShitState), typeDiscriminator: "ShitState")]
public interface IGameModel public interface IGameModel
{ {
} }
[JsonDerivedType(typeof(TrainingSetupState), typeDiscriminator: "TrainingSetupState")]
[JsonDerivedType(typeof(ShitSetupState), typeDiscriminator: "ShitSetupState")]
public interface IGameSetupModel
{
int DayId { get; set; }
ThrowMode ThrowMode { get; set; }
int ThrowsPerRound { get; set; }
int[] Participants { get; set; }
ParticipantsMode ParticipantsMode { get; set; }
string KnownGameType { get; set; }
}
public abstract record GameSetupModelBase : IGameSetupModel
{
public int DayId { get; set; }
public ThrowMode ThrowMode { get; set; }
public int ThrowsPerRound { get; set; }
public int[] Participants { get; set; }
public ParticipantsMode ParticipantsMode { get; set; }
public string KnownGameType { get; set; }
}
public interface IGameService public interface IGameService
{ {
public IKnownGame Game { get; } public IKnownGame Game { get; }
public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher); public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher);
public IGameModel InitGameModel(StartParams startParams); public IGameModel InitGameModel(IGameSetupModel startParams);
IGameModel FinalizeGameModel(); IGameModel FinalizeGameModel();
public IGameModel GameModel { get; }
} }
} }

View File

@ -9,5 +9,7 @@
public Type GameServiceType { get; } public Type GameServiceType { get; }
public Type BoardComponentType { get; } public Type BoardComponentType { get; }
public Type SetupModelType { get; }
} }
} }

View File

@ -0,0 +1,5 @@
<h3>Setup</h3>
@code {
}

View File

@ -0,0 +1,4 @@

@code {
}

View File

@ -0,0 +1,14 @@
using KoogleApp.Games.Training;
namespace KoogleApp.Games.Shit
{
public class ShitGame: IKnownGame
{
public string Name => "Scheiss-Spiel";
public Type SetupComponentType => typeof(Setup);
public Type SetupModelType => typeof(ShitSetupState);
public Type GameServiceType => typeof(ShitGameService);
public Type BoardComponentType => typeof(ShitBoard);
}
}

View File

@ -0,0 +1,26 @@
using Fluxor;
using KoogleApp.Model;
using KoogleApp.Store.Game.ThrowPanel;
namespace KoogleApp.Games.Shit
{
public class ShitGameService : IGameService
{
public IKnownGame Game => new ShitGame();
public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher)
{
return progress;
}
public IGameModel InitGameModel(IGameSetupModel startParams)
{
return null;
}
public IGameModel FinalizeGameModel()
{
return null;
}
}
}

View File

@ -0,0 +1,15 @@
using Fluxor;
using KoogleApp.Store.Game.ThrowPanel;
namespace KoogleApp.Games.Shit
{
[FeatureState]
public record ShitState : IGameModel
{}
[FeatureState]
public record ShitSetupState: GameSetupModelBase
{
public int ShitNumber { get; set; } = 5;
}
}

View File

@ -1,4 +0,0 @@
namespace KoogleApp.Games.Training
{
//public record UpdateTrainingStateAction(TrainingState TrainingState);
}

View File

@ -9,5 +9,7 @@
public Type GameServiceType => typeof(GameTrainingService); public Type GameServiceType => typeof(GameTrainingService);
public Type BoardComponentType => typeof(BoardTraining); public Type BoardComponentType => typeof(BoardTraining);
public Type SetupModelType => typeof(TrainingSetupState);
} }
} }

View File

@ -12,11 +12,9 @@ namespace KoogleApp.Games.Training
{ {
public IKnownGame Game => new GameTraining(); public IKnownGame Game => new GameTraining();
private TrainingState _gameModel; public IGameModel InitGameModel(IGameSetupModel startParams)
public IGameModel InitGameModel(StartParams startParams)
{ {
_gameModel = new TrainingState(); var _gameModel = new TrainingState();
var dict = new Dictionary<int, ThrowModel>(); var dict = new Dictionary<int, ThrowModel>();
@ -32,11 +30,9 @@ namespace KoogleApp.Games.Training
public IGameModel FinalizeGameModel() public IGameModel FinalizeGameModel()
{ {
return _gameModel; return null;
} }
public IGameModel GameModel => _gameModel;
public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher) public GameProgress HandleThrow(GameProgress progress, IDispatcher dispatcher)
{ {
var res = new List<object>(); var res = new List<object>();

View File

@ -35,6 +35,10 @@ namespace KoogleApp.Games.Training
} }
} }
[FeatureState]
public record TrainingSetupState : GameSetupModelBase
{}
public static class TrainingStateExtension public static class TrainingStateExtension
{ {
public static TrainingState DeepCopy(this TrainingState State) public static TrainingState DeepCopy(this TrainingState State)

View File

@ -16,7 +16,7 @@ namespace KoogleApp.Model
public class GameStatus public class GameStatus
{ {
public StartParams StartParams { get; set; } public IGameSetupModel SetupModel { get; set; }
public ThrowPanelState? ThrowPanelState { get; set; } public ThrowPanelState? ThrowPanelState { get; set; }

View File

@ -4,14 +4,14 @@ using KoogleApp.Store.Game.ThrowPanel;
namespace KoogleApp.Model namespace KoogleApp.Model
{ {
public record StartParams(int DayId, ThrowMode ThrowMode, int ThrowsPerRound, int[] Participants, //public record StartParams(int DayId, ThrowMode ThrowMode, int ThrowsPerRound, int[] Participants,
ParticipantsMode ParticipantsMode, string KnownGameType) // ParticipantsMode ParticipantsMode, string KnownGameType)
{ //{
public StartParams() : this(DayId: 0, ThrowMode: ThrowMode.Reposition, // public StartParams() : this(DayId: 0, ThrowMode: ThrowMode.Reposition,
ThrowsPerRound: 3, [], // ThrowsPerRound: 3, [],
ParticipantsMode: ParticipantsMode.FreeToChoose, KnownGameType: nameof(GameTraining)) // ParticipantsMode: ParticipantsMode.FreeToChoose, KnownGameType: nameof(GameTraining))
{ // {
} // }
} //}
} }

View File

@ -1,5 +1,6 @@
using KoogleApp.Model; using KoogleApp.Model;
using System.Text.Json; using System.Text.Json;
using KoogleApp.Games;
namespace KoogleApp.Services namespace KoogleApp.Services
{ {
@ -21,7 +22,7 @@ namespace KoogleApp.Services
//void Initialize(GameStatus content, string username); //void Initialize(GameStatus content, string username);
GameStatusSnapshot GetInitialData(); GameStatusSnapshot GetInitialData();
StartParams? StartParams { get; } IGameSetupModel? StartParams { get; }
} }
public class GameStatusDataService : IGameStatusDataService public class GameStatusDataService : IGameStatusDataService
@ -84,7 +85,7 @@ namespace KoogleApp.Services
return GetCurrentData(); return GetCurrentData();
} }
} }
public StartParams? StartParams => GetInitialData()?.Status?.StartParams; public IGameSetupModel? StartParams => GetInitialData()?.Status?.SetupModel;
public Task SaveToDatabaseAndReset(GameStatus lastContent, string username) public Task SaveToDatabaseAndReset(GameStatus lastContent, string username)
@ -123,10 +124,10 @@ namespace KoogleApp.Services
var isInitialSnapshot = _currentData == null; var isInitialSnapshot = _currentData == null;
if (isInitialSnapshot) if (isInitialSnapshot)
{ {
if (content.StartParams == null) if (content.SetupModel == null)
{ {
return; return;
//throw new InvalidOperationException("Service not initialized. StartParams required"); //throw new InvalidOperationException("Service not initialized. SetupModel required");
} }
_currentData = new GameStatusSnapshot _currentData = new GameStatusSnapshot

View File

@ -27,7 +27,7 @@ namespace KoogleApp.Store.Game.Setup
var data = _dataService.GetInitialData(); var data = _dataService.GetInitialData();
if (data.Status != null) if (data.Status != null)
{ {
var startParams = data.Status.StartParams; var startParams = data.Status.SetupModel;
if (startParams != null) if (startParams != null)
{ {
var setupState = new SetupState(startParams.ThrowMode, startParams.ThrowsPerRound, startParams.Participants, var setupState = new SetupState(startParams.ThrowMode, startParams.ThrowsPerRound, startParams.Participants,

View File

@ -7,7 +7,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
{ {
public record TogglePinValueAction(bool IsHit, int PinNumber); public record TogglePinValueAction(bool IsHit, int PinNumber);
public record StartStopAction(ThrowPanelState State, StartParams? StartParams); public record StartStopAction(ThrowPanelState State, IGameSetupModel? StartParams);
public record ConnectToHubAction(); public record ConnectToHubAction();
@ -46,7 +46,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
public record GameProgress(ThrowPanelState? BeforeThrowState, ParticipantsState? BeforeParticipantsState, public record GameProgress(ThrowPanelState? BeforeThrowState, ParticipantsState? BeforeParticipantsState,
ThrowPanelState AfterThrowState, ParticipantsState AfterParticipantsState, ThrowPanelState AfterThrowState, ParticipantsState AfterParticipantsState,
StartParams StartParams, IGameModel GameModel, IGameSetupModel StartParams, IGameModel GameModel,
ThrowPanelState? NextThrowState); ThrowPanelState? NextThrowState);
public record DeleteThrowPanelSessionAction(); public record DeleteThrowPanelSessionAction();

View File

@ -61,7 +61,7 @@ namespace KoogleApp.Store.Game.ThrowPanel
{ {
ThrowPanelState = throwPanelState.Value, ThrowPanelState = throwPanelState.Value,
ParticipantsState = participantsState, ParticipantsState = participantsState,
StartParams = startStopAction.StartParams, SetupModel = startStopAction.StartParams,
GameModel = gameModel GameModel = gameModel
}, username); }, username);
} }

View File

@ -1,7 +1,7 @@
{ {
"CurrentData": { "CurrentData": {
"Status": { "Status": {
"StartParams": null, "SetupModel": null,
"ThrowPanelState": { "ThrowPanelState": {
"IsStated": true, "IsStated": true,
"BellValue": false, "BellValue": false,
@ -14,8 +14,8 @@
"Pin7State": 0, "Pin7State": 0,
"Pin8State": 0, "Pin8State": 0,
"Pin9State": 0, "Pin9State": 0,
"ThrowsPerRound": 1, "ThrowsPerRound": 3,
"ThrowCounterPerRound": 1, "ThrowCounterPerRound": 2,
"ThrowMode": 0, "ThrowMode": 0,
"ThrowPanelStateStatus": 3, "ThrowPanelStateStatus": 3,
"ThrowCounter": 1, "ThrowCounter": 1,
@ -23,11 +23,11 @@
}, },
"ParticipantsState": { "ParticipantsState": {
"PlayerIds": [ "PlayerIds": [
12,
5,
3, 3,
10, 10,
12, 9
9,
5
], ],
"Eliminated": [] "Eliminated": []
}, },
@ -37,12 +37,12 @@
"5": { "5": {
"PlayerId": 5, "PlayerId": 5,
"TeamNr": 0, "TeamNr": 0,
"PinCount": 1, "PinCount": 0,
"CircleCount": 0, "CircleCount": 0,
"SinkCount": 0, "SinkCount": 0,
"StrikeCount": 0, "StrikeCount": 0,
"ClearedCount": 0, "ClearedCount": 0,
"ThrowCount": 1, "ThrowCount": 0,
"BellCount": 0 "BellCount": 0
}, },
"3": { "3": {
@ -70,12 +70,12 @@
"12": { "12": {
"PlayerId": 12, "PlayerId": 12,
"TeamNr": 0, "TeamNr": 0,
"PinCount": 0, "PinCount": 1,
"CircleCount": 0, "CircleCount": 0,
"SinkCount": 0, "SinkCount": 0,
"StrikeCount": 0, "StrikeCount": 0,
"ClearedCount": 0, "ClearedCount": 0,
"ThrowCount": 0, "ThrowCount": 1,
"BellCount": 0 "BellCount": 0
}, },
"9": { "9": {
@ -93,13 +93,13 @@
} }
}, },
"Version": 3, "Version": 3,
"LastModified": "2025-11-27T08:57:54.4108241+01:00", "LastModified": "2025-11-27T18:02:52.0439516+01:00",
"LastModifiedBy": "test1@test.de" "LastModifiedBy": "test1@test.de"
}, },
"UndoHistory": [ "UndoHistory": [
{ {
"Status": { "Status": {
"StartParams": null, "SetupModel": null,
"ThrowPanelState": { "ThrowPanelState": {
"IsStated": true, "IsStated": true,
"BellValue": false, "BellValue": false,
@ -112,7 +112,7 @@
"Pin7State": 0, "Pin7State": 0,
"Pin8State": 0, "Pin8State": 0,
"Pin9State": 1, "Pin9State": 1,
"ThrowsPerRound": 1, "ThrowsPerRound": 3,
"ThrowCounterPerRound": 1, "ThrowCounterPerRound": 1,
"ThrowMode": 0, "ThrowMode": 0,
"ThrowPanelStateStatus": 2, "ThrowPanelStateStatus": 2,
@ -121,10 +121,10 @@
}, },
"ParticipantsState": { "ParticipantsState": {
"PlayerIds": [ "PlayerIds": [
12,
5, 5,
3, 3,
10, 10,
12,
9 9
], ],
"Eliminated": [] "Eliminated": []
@ -191,15 +191,16 @@
} }
}, },
"Version": 2, "Version": 2,
"LastModified": "2025-11-27T08:57:54.3513899+01:00", "LastModified": "2025-11-27T18:02:52.0372178+01:00",
"LastModifiedBy": "test1@test.de" "LastModifiedBy": "test1@test.de"
}, },
{ {
"Status": { "Status": {
"StartParams": { "SetupModel": {
"$type": "TrainingSetupState",
"DayId": 35, "DayId": 35,
"ThrowMode": 0, "ThrowMode": 0,
"ThrowsPerRound": 1, "ThrowsPerRound": 3,
"Participants": [ "Participants": [
5, 5,
3, 3,
@ -207,7 +208,7 @@
12, 12,
9 9
], ],
"ParticipantsMode": 0, "ParticipantsMode": 1,
"KnownGameType": "GameTraining" "KnownGameType": "GameTraining"
}, },
"ThrowPanelState": { "ThrowPanelState": {
@ -222,7 +223,7 @@
"Pin7State": 0, "Pin7State": 0,
"Pin8State": 0, "Pin8State": 0,
"Pin9State": 0, "Pin9State": 0,
"ThrowsPerRound": 1, "ThrowsPerRound": 3,
"ThrowCounterPerRound": 1, "ThrowCounterPerRound": 1,
"ThrowMode": 0, "ThrowMode": 0,
"ThrowPanelStateStatus": 1, "ThrowPanelStateStatus": 1,
@ -301,7 +302,7 @@
} }
}, },
"Version": 1, "Version": 1,
"LastModified": "2025-11-27T07:56:55.6527668Z", "LastModified": "2025-11-27T17:02:45.406402Z",
"LastModifiedBy": "test1@test.de" "LastModifiedBy": "test1@test.de"
} }
], ],