Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/refactor config system #118

Merged
merged 32 commits into from
Sep 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a5a3873
Add DebugInfo data per System.
highbyte Sep 8, 2024
464e9b8
Make SadConsole Debug Info panel general (non-system specific).
highbyte Sep 8, 2024
ffabc62
WIP: C64 Basic coding assistant with OpenAI integration.
highbyte Sep 10, 2024
3f3edbe
WIP: C64 Basic coding assistant with OpenAI integration.
highbyte Sep 10, 2024
c0197bc
WIP: Improving C64 Basic Assistant to consider entire Basic program (…
highbyte Sep 11, 2024
4fd728b
WIP: C64 Coding Assistant integration in WASM UI.
highbyte Sep 12, 2024
04d175d
Merge from master
highbyte Sep 12, 2024
968ed16
WASM UI startup timing issue fixed between OnInitializedAsync and OnA…
highbyte Sep 12, 2024
0d92e48
Move stream helper method to new class.
highbyte Sep 12, 2024
3ce186d
SadConsole UI for toggling C64 Basic AI coding assistant
highbyte Sep 13, 2024
0cae65a
Create new library Highbyte.DotNet6502.AI that now contains shared Op…
highbyte Sep 13, 2024
6fc9bee
WIP: Better SadConsole implementation for C64 code assistant AI. Cust…
highbyte Sep 20, 2024
dbee6c5
Common on how to get the game Elite (1984) working in C64 emulator.
highbyte Sep 20, 2024
87d5125
Add api key to custom AI code completion endpoint.
highbyte Sep 25, 2024
00bf848
Improve C64 AI coding assistant
highbyte Sep 26, 2024
7e5f0a2
Cleanup VSCode launch.json and task.json
highbyte Sep 26, 2024
a293c0d
Fix layout
highbyte Sep 27, 2024
451438e
Fix layout
highbyte Sep 27, 2024
a0d65a1
WIP: move C64 ROM config to not be specific for each model config.
highbyte Sep 28, 2024
a35cc02
Cleanup code
highbyte Sep 28, 2024
03f8b56
Major refactor of emulator configuration management.
highbyte Sep 29, 2024
b3eda3f
Fix WASM config ui after refactor.
highbyte Sep 29, 2024
3909d37
Remove unnecessary checks
highbyte Sep 29, 2024
242f1b4
Fix WASM C64 menu file picker dialog not pausing emulator before load…
highbyte Sep 29, 2024
adeb493
Fix keyboard bug in example snake game.
highbyte Sep 29, 2024
95ee277
SadConsole host UI fix
highbyte Sep 29, 2024
07b2677
Fix bug Stats panel bug in SilkNet Native app when stopping/starting.
highbyte Sep 29, 2024
f7cdb59
Misc tweaks
highbyte Sep 29, 2024
dabc108
Move config validation when starting emulator to Host config (previou…
highbyte Sep 29, 2024
57cb6a8
Fix broken tests
highbyte Sep 29, 2024
b8e5bcf
Merge from feature/c64-basic-coding-ai-assistant
highbyte Sep 29, 2024
4639246
Merge from master
highbyte Sep 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ public class C64ConfigUIConsole : Window
private const int USABLE_WIDTH = 60;
private const int USABLE_HEIGHT = 28;

public readonly C64Config C64Config;
public C64SystemConfig C64SystemConfig => C64HostConfig.SystemConfig;
public readonly C64HostConfig C64HostConfig;
private readonly IConfiguration _configuration;

public C64ConfigUIConsole(SadConsoleHostApp sadConsoleHostApp, IConfiguration configuration) : base(CONSOLE_WIDTH, CONSOLE_HEIGHT)
{

C64Config = (C64Config)sadConsoleHostApp.CurrentSystemConfig.Clone();
C64HostConfig = (C64HostConfig)sadConsoleHostApp.CurrentHostSystemConfig.Clone();

Controls.ThemeColors = SadConsoleUISettings.ThemeColors;
Expand Down Expand Up @@ -53,7 +52,7 @@ private void DrawUIItems()
Name = "romDirectoryTextBox",
Position = (1, romDirectoryLabel.Position.Y + 1),
};
romDirectoryTextBox.TextChanged += (s, e) => { C64Config.ROMDirectory = romDirectoryTextBox.Text; IsDirty = true; };
romDirectoryTextBox.TextChanged += (s, e) => { C64SystemConfig.ROMDirectory = romDirectoryTextBox.Text; IsDirty = true; };
Controls.Add(romDirectoryTextBox);

var selectROMDirectoryButton = new Button("...")
Expand All @@ -71,15 +70,15 @@ private void DrawUIItems()
Name = "kernalROMTextBox",
Position = (1, kernalROMLabel.Position.Y + 1)
};
kernalROMTextBox.TextChanged += (s, e) => { C64Config.SetROM(C64Config.KERNAL_ROM_NAME, kernalROMTextBox!.Text); IsDirty = true; };
kernalROMTextBox.TextChanged += (s, e) => { C64SystemConfig.SetROM(C64SystemConfig.KERNAL_ROM_NAME, kernalROMTextBox!.Text); IsDirty = true; };
Controls.Add(kernalROMTextBox);

var selectKernalROMButton = new Button("...")
{
Name = "selectKernalROMButton",
Position = (kernalROMTextBox.Bounds.MaxExtentX + 2, kernalROMTextBox.Position.Y),
};
selectKernalROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64Config.KERNAL_ROM_NAME);
selectKernalROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64SystemConfig.KERNAL_ROM_NAME);
Controls.Add(selectKernalROMButton);

// Basic ROM file
Expand All @@ -89,15 +88,15 @@ private void DrawUIItems()
Name = "basicROMTextBox",
Position = (1, basicROMLabel.Position.Y + 1)
};
basicROMTextBox.TextChanged += (s, e) => { C64Config.SetROM(C64Config.BASIC_ROM_NAME, basicROMTextBox!.Text); IsDirty = true; };
basicROMTextBox.TextChanged += (s, e) => { C64SystemConfig.SetROM(C64SystemConfig.BASIC_ROM_NAME, basicROMTextBox!.Text); IsDirty = true; };
Controls.Add(basicROMTextBox);

var selectBasicROMButton = new Button("...")
{
Name = "selectBasicROMButton",
Position = (basicROMTextBox.Bounds.MaxExtentX + 2, basicROMTextBox.Position.Y),
};
selectBasicROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64Config.BASIC_ROM_NAME);
selectBasicROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64SystemConfig.BASIC_ROM_NAME);
Controls.Add(selectBasicROMButton);

// Chargen ROM file
Expand All @@ -107,15 +106,15 @@ private void DrawUIItems()
Name = "chargenROMTextBox",
Position = (1, chargenROMLabel.Position.Y + 1),
};
chargenROMTextBox.TextChanged += (s, e) => { C64Config.SetROM(C64Config.CHARGEN_ROM_NAME, chargenROMTextBox!.Text); IsDirty = true; };
chargenROMTextBox.TextChanged += (s, e) => { C64SystemConfig.SetROM(C64SystemConfig.CHARGEN_ROM_NAME, chargenROMTextBox!.Text); IsDirty = true; };
Controls.Add(chargenROMTextBox);

var selectChargenROMButton = new Button("...")
{
Name = "selectChargenROMButton",
Position = (chargenROMTextBox.Bounds.MaxExtentX + 2, chargenROMTextBox.Position.Y),
};
selectChargenROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64Config.CHARGEN_ROM_NAME);
selectChargenROMButton.Click += (s, e) => ShowROMFilePickerDialog(C64SystemConfig.CHARGEN_ROM_NAME);
Controls.Add(selectChargenROMButton);


Expand Down Expand Up @@ -253,14 +252,14 @@ private void OpenURL(string url)

private void ShowROMFilePickerDialog(string romName)
{
var currentFolder = PathHelper.ExpandOSEnvironmentVariables(C64Config.ROMDirectory);
var window = new FilePickerConsole(FilePickerMode.OpenFile, currentFolder, C64Config.GetROM(romName).GetROMFilePath(currentFolder));
var currentFolder = PathHelper.ExpandOSEnvironmentVariables(C64SystemConfig.ROMDirectory);
var window = new FilePickerConsole(FilePickerMode.OpenFile, currentFolder, C64SystemConfig.GetROM(romName).GetROMFilePath(currentFolder));
window.Center();
window.Closed += (s2, e2) =>
{
if (window.DialogResult)
{
C64Config.SetROM(romName, Path.GetFileName(window.SelectedFile.FullName));
C64SystemConfig.SetROM(romName, Path.GetFileName(window.SelectedFile.FullName));
IsDirty = true;
}
};
Expand All @@ -269,14 +268,14 @@ private void ShowROMFilePickerDialog(string romName)

private void ShowROMFolderPickerDialog()
{
var currentFolder = PathHelper.ExpandOSEnvironmentVariables(C64Config.ROMDirectory);
var currentFolder = PathHelper.ExpandOSEnvironmentVariables(C64SystemConfig.ROMDirectory);
var window = new FilePickerConsole(FilePickerMode.OpenFolder, currentFolder);
window.Center();
window.Closed += (s2, e2) =>
{
if (window.DialogResult)
{
C64Config.ROMDirectory = window.SelectedDirectory.FullName;
C64SystemConfig.ROMDirectory = window.SelectedDirectory.FullName;
IsDirty = true;
}
};
Expand All @@ -292,25 +291,25 @@ protected override void OnIsDirtyChanged()
private void SetControlStates()
{
var romDirectoryTextBox = Controls["romDirectoryTextBox"] as TextBox;
romDirectoryTextBox!.Text = C64Config.ROMDirectory;
romDirectoryTextBox!.Text = C64SystemConfig.ROMDirectory;
romDirectoryTextBox!.IsDirty = true;

var kernalROMTextBox = Controls["kernalROMTextBox"] as TextBox;
kernalROMTextBox!.Text = C64Config.ROMs.SingleOrDefault(x => x.Name == C64Config.KERNAL_ROM_NAME).File;
kernalROMTextBox!.Text = C64SystemConfig.ROMs.SingleOrDefault(x => x.Name == C64SystemConfig.KERNAL_ROM_NAME).File;
kernalROMTextBox!.IsDirty = true;

var basicROMTextBox = Controls["basicROMTextBox"] as TextBox;
basicROMTextBox!.Text = C64Config.ROMs.SingleOrDefault(x => x.Name == C64Config.BASIC_ROM_NAME).File;
basicROMTextBox!.Text = C64SystemConfig.ROMs.SingleOrDefault(x => x.Name == C64SystemConfig.BASIC_ROM_NAME).File;
basicROMTextBox!.IsDirty = true;

var chargenROMTextBox = Controls["chargenROMTextBox"] as TextBox;
chargenROMTextBox!.Text = C64Config.ROMs.SingleOrDefault(x => x.Name == C64Config.CHARGEN_ROM_NAME).File;
chargenROMTextBox!.Text = C64SystemConfig.ROMs.SingleOrDefault(x => x.Name == C64SystemConfig.CHARGEN_ROM_NAME).File;
chargenROMTextBox!.IsDirty = true;

var codingAssistantTestButton = Controls["codingAssistantTestButton"] as Button;
codingAssistantTestButton.IsEnabled = C64HostConfig.CodeSuggestionBackendType != CodeSuggestionBackendTypeEnum.None;

var isOk = C64Config.IsValid(out List<string> validationErrors);
var isOk = C64SystemConfig.IsValid(out List<string> validationErrors);
var okButton = Controls["okButton"] as Button;
okButton!.IsEnabled = isOk;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private void DrawUIItems()
Controls.Add(c64ConfigButton);


var validationMessageValueLabel = CreateLabelValue(new string(' ', 20), 1, c64PasteTextButton.Bounds.MaxExtentY + 2, "validationMessageValueLabel");
var validationMessageValueLabel = CreateLabelValue(new string(' ', 20), 1, c64ConfigButton.Bounds.MaxExtentY + 2, "validationMessageValueLabel");
validationMessageValueLabel.TextColor = Controls.GetThemeColors().Red;

// Helper function to create a label and add it to the console
Expand Down Expand Up @@ -230,8 +230,7 @@ private void C64ConfigButton_Click(object sender, EventArgs e)
if (window.DialogResult)
{
// Update the system config
_sadConsoleHostApp.UpdateSystemConfig(window.C64Config);
//_sadConsoleHostApp.UpdateHostSystemConfig(window.C64HostConfig);
_sadConsoleHostApp.UpdateHostSystemConfig(window.C64HostConfig);

IsDirty = true;
SetControlStates(); // Setting IsDirty here above does not trigger OnIsDirtyChanged? Call SetControlStates directly here to make sure controls are updated.
Expand Down
6 changes: 3 additions & 3 deletions src/apps/Highbyte.DotNet6502.App.SadConsole/MenuConsole.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,17 +54,17 @@ private void DrawUIItems()
selectSystemComboBox.SelectedItemChanged += async (s, e) =>
{
await _sadConsoleHostApp.SelectSystem(selectSystemComboBox.SelectedItem.ToString());
await _sadConsoleHostApp.SelectSystemConfigurationVariant(_sadConsoleHostApp.CurrentSystemConfigurationVariants.First());
await _sadConsoleHostApp.SelectSystemConfigurationVariant(_sadConsoleHostApp.AllSelectedSystemConfigurationVariants.First());

var selectSystemVariantComboBox = Controls["selectSystemVariantComboBox"] as ComboBox;
selectSystemVariantComboBox.SetItems(_sadConsoleHostApp.CurrentSystemConfigurationVariants.ToArray());
selectSystemVariantComboBox.SetItems(_sadConsoleHostApp.AllSelectedSystemConfigurationVariants.ToArray());
selectSystemVariantComboBox.SelectedIndex = 0;
IsDirty = true;
};
Controls.Add(selectSystemComboBox);

var variantLabel = CreateLabel("Variant:", 1, systemLabel.Bounds.MaxExtentY + 1);
ComboBox selectSystemVariantComboBox = new ComboBox(12, 15, 5, _sadConsoleHostApp.CurrentSystemConfigurationVariants.ToArray())
ComboBox selectSystemVariantComboBox = new ComboBox(12, 15, 5, _sadConsoleHostApp.AllSelectedSystemConfigurationVariants.ToArray())
{
Position = (variantLabel.Bounds.MaxExtentX + 2, variantLabel.Position.Y),
Name = "selectSystemVariantComboBox",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ public void Run()

private IScreenObject CreateMainSadConsoleScreen(GameHost gameHost)
{
// Trigger sadConsoleHostApp.SelectSystem which initilzes selected system and variants that UI creation depends on below.
SelectSystem(_emulatorConfig.DefaultEmulator).Wait();

//ScreenSurface screen = new(gameInstance.ScreenCellsX, gameInstance.ScreenCellsY);
//return screen;
_sadConsoleScreen = new ScreenObject();
Expand Down Expand Up @@ -223,6 +226,10 @@ private IScreenObject CreateMainSadConsoleScreen(GameHost gameHost)

public override void OnAfterSelectSystem()
{
// Hack for when selecting a system during initialization triggers this event.
if (_menuConsole == null)
return;

// Set the default font size configured for the system
_menuConsole.SetEmulatorFontSize(CommonHostSystemConfig.DefaultFontSize);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,51 @@
using System.Text.Json.Serialization;
using Highbyte.DotNet6502.AI.CodingAssistant;
using Highbyte.DotNet6502.Systems.Commodore64.Config;

namespace Highbyte.DotNet6502.App.SadConsole.SystemSetup;

public class C64HostConfig : SadConsoleHostSystemConfigBase
{
public const string ConfigSectionName = "Highbyte.DotNet6502.C64.SadConsole";

public C64SystemConfig SystemConfig
{
get { return (C64SystemConfig)base.SystemConfig; }
set { base.SystemConfig = value; }
}

[JsonIgnore]
public override bool AudioSupported => true;

private bool _isDirty = false;
[JsonIgnore]
public bool IsDirty => _isDirty;
public void ClearDirty()
{
_isDirty = false;
}

public override bool IsValid(out List<string> validationErrors)
{
validationErrors = new List<string>();

SystemConfig.IsValid(out var systemConfigValidationErrors);
validationErrors.AddRange(systemConfigValidationErrors);

return validationErrors.Count == 0;
}

public bool BasicAIAssistantDefaultEnabled { get; set; }

//TODO: CodeSuggestionBackendType setting should be common and not specific for a system
public CodeSuggestionBackendTypeEnum CodeSuggestionBackendType { get; set; }

public C64HostConfig()
{
SystemConfig = new C64SystemConfig();

BasicAIAssistantDefaultEnabled = false;

CodeSuggestionBackendType = CodeSuggestionBackendTypeEnum.OpenAI;

//Font = "Fonts/C64.font";
Expand All @@ -23,6 +58,7 @@ public C64HostConfig()
public new object Clone()
{
var clone = (C64HostConfig)MemberwiseClone();
clone.SystemConfig = (C64SystemConfig)SystemConfig.Clone();
return clone;
}
}
53 changes: 25 additions & 28 deletions src/apps/Highbyte.DotNet6502.App.SadConsole/SystemSetup/C64Setup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ namespace Highbyte.DotNet6502.App.SadConsole.SystemSetup;
public class C64Setup : ISystemConfigurer<SadConsoleRenderContext, SadConsoleInputHandlerContext, NAudioAudioHandlerContext>
{
public string SystemName => C64.SystemName;

public Task<List<string>> GetConfigurationVariants(IHostSystemConfig hostSystemConfig) => Task.FromResult(s_systemVariants);
public List<string> ConfigurationVariants => s_systemVariants;

private static readonly List<string> s_systemVariants = C64ModelInventory.C64Models.Keys.ToList();
Expand All @@ -33,49 +35,44 @@ public C64Setup(ILoggerFactory loggerFactory, IConfiguration configuration)

public Task<IHostSystemConfig> GetNewHostSystemConfig()
{
// TODO: Read all system host config from appsettings.json
var c64HostConfig = new C64HostConfig
{
BasicAIAssistantDefaultEnabled = false,
CodeSuggestionBackendType = Enum.Parse<CodeSuggestionBackendTypeEnum>(_configuration["CodingAssistant:CodingAssistantType"] ?? "None")
};
return Task.FromResult<IHostSystemConfig>(c64HostConfig);
}
var c64HostConfig = new C64HostConfig();
_configuration.GetSection($"{C64HostConfig.ConfigSectionName}").Bind(c64HostConfig);

public Task PersistHostSystemConfig(IHostSystemConfig hostSystemConfig)
{
// TODO: Persist settings to file
return Task.CompletedTask;
}
// TODO: Why is list of ROMs are duplicated when binding from appsettings.json?
// This is a workaround to remove duplicates.
c64HostConfig.SystemConfig.ROMs = c64HostConfig.SystemConfig.ROMs.DistinctBy(p => p.Name).ToList();

public Task<ISystemConfig> GetNewConfig(string configurationVariant, IHostSystemConfig hostSystemConfig)
{
if (!s_systemVariants.Contains(configurationVariant))
throw new ArgumentException($"Unknown configuration variant '{configurationVariant}'.");
// TODO: Code suggestion AI backend type should not be set in system specific config.
// For now workaround by reading from a common setting.
c64HostConfig.CodeSuggestionBackendType = Enum.Parse<CodeSuggestionBackendTypeEnum>(_configuration["CodingAssistant:CodingAssistantType"] ?? "None");

var c64Config = new C64Config() { ROMs = new() };
_configuration.GetSection($"{C64Config.ConfigSectionName}.{configurationVariant}").Bind(c64Config);
return Task.FromResult<ISystemConfig>(c64Config);
return Task.FromResult<IHostSystemConfig>(c64HostConfig);
}

public Task PersistConfig(ISystemConfig systemConfig)
public Task PersistHostSystemConfig(IHostSystemConfig hostSystemConfig)
{
var c64Config = (C64Config)systemConfig;
// TODO: Persist settings to file

// TODO: Should user settings be persisted? If so method GetNewHostSystemConfig() also needs to be updated to read from there instead of appsettings.json.
return Task.CompletedTask;
}

public ISystem BuildSystem(ISystemConfig systemConfig)
public Task<ISystem> BuildSystem(string configurationVariant, IHostSystemConfig hostSystemConfig)
{
var c64Config = (C64Config)systemConfig;
var c64HostSystemConfig = (C64HostConfig)hostSystemConfig;
var c64Config = new C64Config
{
C64Model = configurationVariant,
Vic2Model = C64ModelInventory.C64Models[configurationVariant].Vic2Models.First().Name, // NTSC, NTSC_old, PAL
AudioEnabled = c64HostSystemConfig.SystemConfig.AudioEnabled,
ROMs = c64HostSystemConfig.SystemConfig.ROMs,
ROMDirectory = c64HostSystemConfig.SystemConfig.ROMDirectory,
};

var c64 = C64.BuildC64(c64Config, _loggerFactory);
return c64;
return Task.FromResult<ISystem>(c64);
}

public Task<SystemRunner> BuildSystemRunner(
ISystem system,
ISystemConfig systemConfig,
IHostSystemConfig hostSystemConfig,
SadConsoleRenderContext renderContext,
SadConsoleInputHandlerContext inputHandlerContext,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,50 @@
using System.Text.Json.Serialization;
using Highbyte.DotNet6502.Systems.Generic.Config;

namespace Highbyte.DotNet6502.App.SadConsole.SystemSetup;

public class GenericComputerHostConfig : SadConsoleHostSystemConfigBase
{
public const string ConfigSectionName = "Highbyte.DotNet6502.GenericComputer.SadConsole";

public GenericComputerSystemConfig SystemConfig
{
get { return (GenericComputerSystemConfig)base.SystemConfig; }
set { base.SystemConfig = value; }
}

public override bool AudioSupported => false;

private bool _isDirty = false;
[JsonIgnore]
public bool IsDirty => _isDirty || SystemConfig.IsDirty;
public void ClearDirty()
{
_isDirty = false;
SystemConfig.ClearDirty();
}

public GenericComputerHostConfig()
{
SystemConfig = new GenericComputerSystemConfig();
Font = null;
DefaultFontSize = IFont.Sizes.One;
}

public override bool IsValid(out List<string> validationErrors)
{
validationErrors = new List<string>();

SystemConfig.IsValid(out var systemConfigValidationErrors);
validationErrors.AddRange(systemConfigValidationErrors);

return validationErrors.Count == 0;
}

public new object Clone()
{
var clone = (GenericComputerHostConfig)MemberwiseClone();
clone.SystemConfig = (GenericComputerSystemConfig)SystemConfig.Clone();
return clone;
}
}
Loading
Loading