Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
erri120 committed Aug 16, 2023
1 parent 1c3cddb commit c81b9d1
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
10 changes: 5 additions & 5 deletions src/Games/NexusMods.Games.FOMOD/CoreDelegates/UiDelegate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ private static void DummyCancelInstaller() { }

private readonly SemaphoreSlim _semaphoreSlim = new (1, 1);
private readonly EventWaitHandle _waitHandle = new ManualResetEvent(initialState: false);
private long _taskFuckeryState;
private long _taskWaitingState;

private const long Ready = 0;
private const long WaitingForCallback = 1;
Expand Down Expand Up @@ -92,7 +92,7 @@ public void UpdateState(FomodInstaller.Interface.ui.InstallerStep[] installSteps
if (currentStepId < 0 || currentStepId >= installSteps.Length) return;

// NOTE(erri120): This fuckery is explained further below when we call _selectOptions()
if (Interlocked.Read(ref _taskFuckeryState) == WaitingForCallback)
if (Interlocked.Read(ref _taskWaitingState) == WaitingForCallback)
{
if (!_waitHandle.Set())
{
Expand Down Expand Up @@ -158,7 +158,7 @@ public void UpdateState(FomodInstaller.Interface.ui.InstallerStep[] installSteps
// NOTE(erri120): Once again, the FOMOD library we're using is complete ass and expects
// to be used in a JavaScript environment. However, this isn't JavaScript this is C#.
// When calling _selectOptions, the library spawns a new Task that runs in the background.
// This means that after calling _selectOptions, we state hasn't been updated YET.
// This means that after calling _selectOptions, the state hasn't been updated YET.
// Inside _selectOptions, the library wants to get the next step, however, if we
// call _continueToNextStep, then the next step variable has already been updated.
// The library doesn't do any checks to prevent this and can throw an exception
Expand All @@ -170,14 +170,14 @@ public void UpdateState(FomodInstaller.Interface.ui.InstallerStep[] installSteps
// updated its internal state. This behavior allows us to use an EventWaitHandle to "wait" for
// the library to call us back.
// We're also using CAS to set our state into "waiting" mode.
if (Interlocked.CompareExchange(ref _taskFuckeryState, WaitingForCallback, Ready) != Ready)
if (Interlocked.CompareExchange(ref _taskWaitingState, WaitingForCallback, Ready) != Ready)
_logger.LogWarning("Unable to CAS!");
_selectOptions(currentStepId, selectedGroupId, selectedOptionIds);
_waitHandle.WaitOne(TimeSpan.FromMilliseconds(200), exitContext: false);
_waitHandle.Reset();
if (Interlocked.CompareExchange(ref _taskFuckeryState, Ready, WaitingForCallback) != WaitingForCallback)
if (Interlocked.CompareExchange(ref _taskWaitingState, Ready, WaitingForCallback) != WaitingForCallback)
_logger.LogWarning("Unable to CAS!");
}
Expand Down
29 changes: 17 additions & 12 deletions src/NexusMods.CLI/CliGuidedInstaller.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ namespace NexusMods.CLI;
public class CliGuidedInstaller : IGuidedInstaller
{
private const string CancelInput = "x";
private const string PreviousInput = "p";
private const string BackInput = "b";
private const string NextInput = "n";

private static readonly string[] TableOfGroupsHeaders = { "Key", "Group" };
private static readonly object[] TableOfGroupsFooterNextGroup = { NextInput, "Next Step" };
private static readonly object[] TableOfGroupsFooterNextStep = { NextInput, "Next Step" };
private static readonly object[] TableOfGroupsFooterFinish = { NextInput, "Finish Installation" };
private static readonly object[] TableOfGroupsFooterGoBack = { BackInput, "Previous Step" };
private static readonly object[] TableOfGroupsFooterPreviousStep = { PreviousInput, "Previous Step" };
private static readonly object[] TableOfGroupsFooterCancel = { CancelInput, "Cancel Installation" };

private static readonly string[] TableOfOptionsHeaders = { "Key", "State", "Name", "Description" };
Expand Down Expand Up @@ -69,9 +70,7 @@ public Task<UserChoice> RequestUserChoice(GuidedInstallationStep installationSte
{
if (currentGroup is null)
{
// if the installation step has multiple groups
// the user has to select which group they want to use

// the user hasn't selected a group yet
RenderTableOfGroups(installationStep);

var input = SkipAll ? NextInput : GetUserInput();
Expand All @@ -80,7 +79,7 @@ public Task<UserChoice> RequestUserChoice(GuidedInstallationStep installationSte
{
case CancelInput:
return Task.FromResult(new UserChoice(new UserChoice.CancelInstallation()));
case BackInput:
case PreviousInput:
return Task.FromResult(new UserChoice(new UserChoice.GoToPreviousStep()));
case NextInput:
{
Expand All @@ -95,12 +94,16 @@ public Task<UserChoice> RequestUserChoice(GuidedInstallationStep installationSte
// proceed to the next step
return Task.FromResult(new UserChoice(new UserChoice.GoToNextStep(selectedOptions.ToArray())));
}
}
default:
{
var groupIndex = ParseNumericalUserInput(input, installationStep.Groups.Length);
if (groupIndex < 0) continue;

var groupIndex = ParseNumericalUserInput(input, installationStep.Groups.Length);
if (groupIndex < 0) continue;
currentGroup = installationStep.Groups[groupIndex];
break;
}
}

currentGroup = installationStep.Groups[groupIndex];
}
else
{
Expand Down Expand Up @@ -133,11 +136,11 @@ private void RenderTableOfGroups(GuidedInstallationStep installationStep)
var row = installationStep.Groups
.Select(group => new object[] { key++, group.Description })
.Append(installationStep.HasNextStep
? TableOfGroupsFooterNextGroup
? TableOfGroupsFooterNextStep
: TableOfGroupsFooterFinish
);

if (installationStep.HasPreviousStep) row = row.Append(TableOfGroupsFooterGoBack);
if (installationStep.HasPreviousStep) row = row.Append(TableOfGroupsFooterPreviousStep);
row = row.Append(TableOfGroupsFooterCancel);

var table = new Table(TableOfGroupsHeaders, row.ToArray(), "Select a Group");
Expand Down Expand Up @@ -227,6 +230,8 @@ private static int ParseNumericalUserInput(string input, int upperLimit)
{
try
{
// method returns a zero-based index for use as the option index
// the user inputs a one-based index, as it's easier to understand
var idx = int.Parse(input) - 1;
if (idx >= 0 && idx < upperLimit)
return idx;
Expand Down

0 comments on commit c81b9d1

Please sign in to comment.