Phase 8A (2/2): RioJoy.Core multi-targets net48 + net40 (Windows XP flavor)
- TargetFrameworks net48;net40. net48 keeps x64 + ViGEm + System.IO.Ports package; net40 adds Microsoft.Bcl.Async + System.ValueTuple and uses the in-box SerialPort. - Compat/TaskCompat bridges Task.Run/Delay/WhenAny/WhenAll (TaskEx on net40) and SemaphoreSlim.WaitAsync (net40 blocks briefly - trivial at 9600 baud). - IReadOnlyList/IReadOnlyDictionary -> IList/IDictionary throughout (net40 predates the IReadOnly* interfaces and the Bcl backport cannot make arrays implement them). - HashCode.Combine replaced with a manual combine (Bcl.HashCode has no net40 build); Marshal.SizeOf<T> -> typeof form; ViGEmJoystickSink gated #if !NET40. HidFeederJoystickSink stays on both flavors - it will drive RioGamepadXP.sys on XP via the same contract. Both TFMs build; 275 tests green on net48. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -50,7 +50,7 @@ public class CockpitPanelTests
|
||||
public void Keypad_PhysicalLayout_MapsDigitsToAddresses()
|
||||
{
|
||||
// Internal keypad: top-left "1" -> 0x51, bottom-middle "0" -> 0x50, "C" -> 0x5C.
|
||||
IReadOnlyList<PanelButton> all = CockpitPanel.Buttons();
|
||||
IList<PanelButton> all = CockpitPanel.Buttons();
|
||||
PanelGroup pad = CockpitPanel.Groups.Single(g => g.Title == "Internal Keypad");
|
||||
|
||||
Assert.Equal(0x51, pad.Addresses[0]); // row0 col0 = "1"
|
||||
|
||||
@@ -47,7 +47,7 @@ public class SheetLayoutTests
|
||||
"\"\",\"IsLit\",\"\",\"\",\"0F\"\n" +
|
||||
"\"\",\"\",\"\",\"\",\"HOME\"";
|
||||
|
||||
IReadOnlyList<SheetCell> cells = SheetLayout.Parse(csv);
|
||||
IList<SheetCell> cells = SheetLayout.Parse(csv);
|
||||
|
||||
SheetCell addr = Assert.Single(cells, c => c.Text == "0F");
|
||||
Assert.Equal(0x0F, addr.Address);
|
||||
@@ -64,7 +64,7 @@ public class SheetLayoutTests
|
||||
[Fact]
|
||||
public void Parse_RealSheet_HasFullAddressMap()
|
||||
{
|
||||
IReadOnlyList<SheetCell> cells = SheetLayout.Load(
|
||||
IList<SheetCell> cells = SheetLayout.Load(
|
||||
TestRepo.CustomBackground("config-sheet.csv"));
|
||||
|
||||
// Every RIO address 0x00..0x6F that exists should appear exactly once as a cell.
|
||||
|
||||
@@ -26,7 +26,7 @@ public class GoobieDataImporterTests
|
||||
[Fact]
|
||||
public void LabelsForRow_DropsEmptyValues()
|
||||
{
|
||||
IReadOnlyDictionary<string, string> labels =
|
||||
IDictionary<string, string> labels =
|
||||
GoobieDataImporter.LabelsForRow(GoobieDataImporter.Parse(Sample));
|
||||
|
||||
Assert.True(labels.ContainsKey("b-00"));
|
||||
|
||||
@@ -21,7 +21,7 @@ public class OverlayHitTesterTests
|
||||
[Fact]
|
||||
public void RegionsAt_ReturnsSmallestFirst()
|
||||
{
|
||||
IReadOnlyList<OverlayRegion> hits = OverlayHitTester.RegionsAt(Template(), 100, 50);
|
||||
IList<OverlayRegion> hits = OverlayHitTester.RegionsAt(Template(), 100, 50);
|
||||
|
||||
Assert.Equal(new[] { "small", "big" }, hits.Select(r => r.Name));
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public class OverlayLayoutEngineTests
|
||||
["b-99"] = "ORPHAN", // no such region -> ignored
|
||||
};
|
||||
|
||||
IReadOnlyList<PlacedLabel> placed = Engine.Layout(template, labels);
|
||||
IList<PlacedLabel> placed = Engine.Layout(template, labels);
|
||||
|
||||
Assert.Equal(2, placed.Count);
|
||||
Assert.Equal("b-00", placed[0].RegionName);
|
||||
|
||||
@@ -35,7 +35,7 @@ public class OverlayRenderIntegrationTests
|
||||
Assert.Equal(template.Width, baseImg.Width);
|
||||
Assert.Equal(template.Height, baseImg.Height);
|
||||
|
||||
IReadOnlyDictionary<string, string> labels =
|
||||
IDictionary<string, string> labels =
|
||||
GoobieDataImporter.LabelsForRow(GoobieDataImporter.Load(TestRepo.CustomBackground("TEST.data")));
|
||||
|
||||
using SKBitmap rendered = new SkiaOverlayRenderer().Render(template, labels, baseImg);
|
||||
|
||||
Reference in New Issue
Block a user