Skip to content

Commit

Permalink
feat(menu): add multi-request elevator control option
Browse files Browse the repository at this point in the history
Introduces a new option for multi-request elevator control in the menu.
The `MenuSelection` enum is updated to include `MultiElevatorControl`,
and a new `ElevatorControlMultipleRequestScreen` is implemented to handle
multiple elevator requests through user input. This enhances user
functionality by allowing simultaneous requests for elevators.
  • Loading branch information
bertusviljoen committed Dec 10, 2024
1 parent 4d8e0ac commit 10fa607
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 21 deletions.
4 changes: 3 additions & 1 deletion src/Application/Screens/MenuSelection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ public enum MenuSelection
/// <summary> Dashboard </summary>
Dashboard,
/// <summary> ElevatorControl </summary>
ElevatorControl
ElevatorControl,
//Multi Request Elevator Control
MultiElevatorControl
}
20 changes: 5 additions & 15 deletions src/Infrastructure/Services/ElevatorSimulationHostedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,12 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
continue;
}

foreach (var elevator in elevatorsResult.Value)
foreach (var elevator in elevatorsResult.Value.AsParallel())
{
logger.LogInformation(
"Simulating elevator {ElevatorId} on floor {Floor}",
elevator.Id, elevator.CurrentFloor);

var elevatorChanged = true;
if (elevator.ElevatorStatus != ElevatorStatus.Active)
{
Expand All @@ -48,23 +52,9 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
case ElevatorDirection.Up:
elevator.CurrentFloor += elevator.FloorsPerSecond;
// //Simulate hard break!
// if (elevator.CurrentFloor >= elevator.DestinationFloor)
// {
// elevator.CurrentFloor = elevator.DestinationFloor;
// elevator.ElevatorDirection = ElevatorDirection.None;
// elevator.DoorStatus = ElevatorDoorStatus.Open;
// }
break;
case ElevatorDirection.Down:
elevator.CurrentFloor -= elevator.FloorsPerSecond;
//Simulate hard break!
// if (elevator.CurrentFloor <= elevator.DestinationFloor)
// {
// elevator.CurrentFloor = elevator.DestinationFloor;
// elevator.ElevatorDirection = ElevatorDirection.None;
// elevator.DoorStatus = ElevatorDoorStatus.Open;
// }
break;
case ElevatorDirection.None:
{
Expand Down
9 changes: 7 additions & 2 deletions src/Presentation/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ namespace Presentation;
// A hosted service that can be run by the Host
// This could be replaced by more complex logic such as background tasks,
// scheduled jobs, or other application logic
public class App(IServiceProvider serviceProvider) : IHostedService
public class App(IServiceProvider serviceProvider,IHostApplicationLifetime applicationLifetime) : IHostedService
{
// This method is called when the host starts
public async Task StartAsync(CancellationToken cancellationToken)
Expand Down Expand Up @@ -46,6 +46,10 @@ public async Task StartAsync(CancellationToken cancellationToken)
var elevatorControlScreen = serviceProvider.GetRequiredService<ElevatorControlScreen>();
await elevatorControlScreen.ShowAsync(cancellationToken);
break;
case MenuSelection.MultiElevatorControl:
var multiElevatorControlScreen = serviceProvider.GetRequiredService<ElevatorControlMultipleRequestScreen>();
await multiElevatorControlScreen.ShowAsync(cancellationToken);
break;
}

AnsiConsole.Clear();
Expand All @@ -68,6 +72,7 @@ private static void DisplayHeader()
public Task StopAsync(CancellationToken cancellationToken)
{
AnsiConsole.MarkupLine("[grey]Shutting down App...[/]");
throw new OperationCanceledException("App is shutting down");
applicationLifetime.StopApplication();
return Task.CompletedTask;
}
}
1 change: 1 addition & 0 deletions src/Presentation/DependencyInjections.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ public static IServiceCollection AddScreens(
services.AddTransient<LoginScreen>();
services.AddTransient<DashboardScreen>();
services.AddTransient<ElevatorControlScreen>();
services.AddTransient<ElevatorControlMultipleRequestScreen>();
return services;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using Application.Abstractions.Screen;
using Application.Elevators.Request;
using Domain.Common;
using Infrastructure.Persistence.SeedData;
using MediatR;
using Presentation.Extensions;
using Spectre.Console;

namespace Presentation.Screens.ElevatorControl;

public class ElevatorControlMultipleRequestScreen(IMediator mediator): IScreen<bool>
{
public async Task<Result<bool>> ShowAsync(CancellationToken token)
{
Result<Guid>? result = null;
var anotherRequest = true;
while (anotherRequest)
{
AnsiConsole.Clear();
AnsiConsole.Write(
new FigletText("Elevator Control")
.LeftJustified()
.Color(Color.Blue)
);

var floors = AnsiConsole.Prompt(
new TextPrompt<string>("What floors are you going to? (comma separated)"));

var buildingId = ApplicationDbContextSeedData.GetSeedBuildings().First()!.Id;
await AnsiConsole.Status()
.StartAsync("Requesting elevators...", async ctx =>
{
var floorRequests = floors.Split(',').Select(int.Parse).ToList();
foreach (int floorRequest in floorRequests.AsParallel())
{
var request = new RequestElevatorCommand(buildingId, floorRequest);
result = await mediator.Send(request, token);
}
});

anotherRequest = result?.Match(
onSuccess: () =>
{
AnsiConsole.MarkupLine("[green]Elevators requested successfully[/]");
return AnsiConsole.Confirm("Do you want to request more elevators?");
},
onFailure: error =>
{
var friendlyError = GetErrorMessage(error);
AnsiConsole.MarkupLine($"[red]{friendlyError}[/]");
return AnsiConsole.Confirm("Do you want to try again?");
}) ?? false;
}
return true;
}

private string GetErrorMessage(Result error)
{
if (error.Error is ValidationError validationError)
{
return string.Join(", ", validationError.Errors.Select(e => e.Description));
}
return error.Error.Description;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -61,5 +61,4 @@ private string GetErrorMessage(Result error)
}
return error.Error.Description;
}

}
4 changes: 2 additions & 2 deletions src/Presentation/Screens/MenuScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ public class MenuScreen : IScreen<MenuSelection>
{
private static readonly Dictionary<string, MenuSelection> MenuOptions = new()
{
["Login"] = MenuSelection.Login,
["Dashboard"] = MenuSelection.Dashboard,
["Elevator Control"] = MenuSelection.ElevatorControl,
["Multi Request Elevator Control"] = MenuSelection.MultiElevatorControl,
["Login"] = MenuSelection.Login,
["Exit"] = MenuSelection.Exit

};

public async Task<Result<MenuSelection>> ShowAsync(CancellationToken token)
Expand Down

0 comments on commit 10fa607

Please sign in to comment.