Fix some bugs and add TestLogicGate

This commit is contained in:
Stone_Red
2023-10-04 12:29:18 +02:00
parent 05a8a72158
commit f1992193e9
9 changed files with 71 additions and 28 deletions
@@ -0,0 +1,29 @@
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes;
using StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
namespace StoneRed.LogicSimulator.Simulation.LogicGates;
#if DEBUG
[LogicGateName("Test")]
internal class TestLogicGate : LogicGate, Interfaces.IDrawable
{
public override int OutputCount { get; set; } = 1;
public override int InputCount { get; set; } = 1;
public Texture2D Texture => CreateTexture(1, 1);
protected override void Execute()
{
Texture.SetData(new Color[] { Color.Red });
for (int i = 0; i < InputCount; i++)
{
SetOutputBit(GetInputBit(i), i);
}
}
}
#endif
+3 -1
View File
@@ -36,6 +36,8 @@ internal class Srls : Game
public Settings Settings { get; set; }
public const ushort CurrentSaveVersion = 1;
public Srls()
{
Content.RootDirectory = "Content";
@@ -162,7 +164,7 @@ internal class Srls : Game
FileAssetResolver assetResolver = new FileAssetResolver(Paths.GetContentPath());
AssetManager = new AssetManager(assetResolver);
LogicGatesManager = new LogicGatesManager();
LogicGatesManager = new LogicGatesManager(GraphicsDevice);
LogicGatesManager.LoadLogicGates();
LoadScreen<StartScreen>();
@@ -49,8 +49,8 @@ internal class LoadingScreen : SrlsScreen<VerticalStackPanel>
}
else
{
srls.ShowWindow(new InfoDialog(string.Join(',', result.Errors.Select(e => e.Message))));
srls.LoadScreen<StartScreen>();
srls.ShowWindow(new InfoDialog(string.Join(',', result.Errors.Select(e => e.Message))));
}
});
}
@@ -55,7 +55,7 @@ internal class WorldScreen : SrlsScreen<Grid>
public WorldScreen()
{
simulator = new LogicGateSimulator(Enumerable.Empty<LogicGate>());
worldData = new WorldData(Enumerable.Empty<LogicGate>(), 1, string.Empty);
worldData = new WorldData(Enumerable.Empty<LogicGate>(), Srls.CurrentSaveVersion, string.Empty);
}
protected override void Initialize()
@@ -173,7 +173,7 @@ internal class WorldScreen : SrlsScreen<Grid>
}
fpsLabel.Text = $"FPS: {Math.Round(fps)}";
upsLabel.Text = $"FRQ: {FrequencyCalculator.CalculateFrequency(simulator.ActualTicksPerSecond)}/{FrequencyCalculator.CalculateFrequency(simulator.TargetTicksPerSecond)}{(simulator.HighPerformanceClock ? "*" : string.Empty)} {(simulator.ClockCalibrating ? $"[Calibrating... {calibrationPercentage}%]" : string.Empty)}";
upsLabel.Text = $"FRQ: {FrequencyCalculator.CalculateFrequency(simulator.ActualTicksPerSecond)}/{FrequencyCalculator.CalculateFrequency(simulator.TargetTicksPerSecond)}{(simulator.HighPerformanceClock ? "*" : string.Empty)} {(simulator.ClockCalibrating && simulator.HighPerformanceClock ? $"[Calibrating... {calibrationPercentage}%]" : string.Empty)}";
positionLabel.Text = $"X/Y: {(long)Math.Round(camera.Position.X / logicGateSize.X / srls.Scale)}/{(long)Math.Round(camera.Position.Y / logicGateSize.Y / srls.Scale)}";
simulator.TargetTicksPerSecond = (int)frequency.Value.GetValueOrDefault();
@@ -222,8 +222,15 @@ internal class WorldScreen : SrlsScreen<Grid>
{
selectedLogicGate.WorldData.Position /= srls.Scale;
simulator.AddLogicGate(selectedLogicGate);
selectedLogicGate = null;
nativeComponentsListBox.SelectedIndex = -1;
if (keyboardState.IsShiftDown())
{
SelectLogicGate();
}
else
{
UnSelectLogicGate();
}
}
else
{
@@ -236,12 +243,12 @@ internal class WorldScreen : SrlsScreen<Grid>
if (keyboardState.IsKeyDown(Keys.C))
{
connectionContext = null;
selectedLogicGate = null;
UnSelectLogicGate();
}
if (keyboardState.IsKeyDown(Keys.Q))
{
UnSelectLogicGate();
worldData.LogicGates = simulator.GetLogicGates();
srls.ShowWindow(new QuickMenu(worldData));
}
@@ -278,7 +285,7 @@ internal class WorldScreen : SrlsScreen<Grid>
return r < 0 ? r + m : r;
}
private void NativeComponentsListBox_SelectedIndexChanged(object? sender, EventArgs e)
private void SelectLogicGate()
{
if (nativeComponentsListBox.SelectedItem is not null)
{
@@ -288,6 +295,19 @@ internal class WorldScreen : SrlsScreen<Grid>
}
}
private void UnSelectLogicGate()
{
connectionContext = null;
selectedLogicGate = null;
nativeComponentsListBox.SelectedIndex = -1;
nativeComponentsListBox.SelectedItem = null;
}
private void NativeComponentsListBox_SelectedIndexChanged(object? sender, EventArgs e)
{
SelectLogicGate();
}
private void ShowConnectionContextMenu(LogicGate logicGate, Point position, bool showInputs)
{
showInputs = logicGate.OutputCount <= 0 || (showInputs && logicGate.InputCount > 0);
@@ -59,13 +59,13 @@ internal class LogicGatesManager
return logicGate;
}
public string GetTypeName(Type type)
public static string GetTypeLogicGateName(Type type)
{
LogicGateNameAttribute nameAttribute = (LogicGateNameAttribute)type.GetCustomAttributes(typeof(LogicGateNameAttribute), false)[0];
return nameAttribute.Name;
}
public bool TryGetTypeName(Type type, [NotNullWhen(true)] out string? typeName)
public static bool TryGetTypeLogicGateName(Type type, [NotNullWhen(true)] out string? typeName)
{
if (type.GetCustomAttributes(typeof(LogicGateNameAttribute), false).FirstOrDefault() is not LogicGateNameAttribute nameAttribute)
{
@@ -8,11 +8,11 @@ internal class WorldData
{
public IEnumerable<LogicGate> LogicGates { get; set; }
public int SaveVersion { get; set; }
public ushort SaveVersion { get; set; }
public string SaveName { get; set; }
public WorldData(IEnumerable<LogicGate> logicGates, int saveVersion, string saveName)
public WorldData(IEnumerable<LogicGate> logicGates, ushort saveVersion, string saveName)
{
LogicGates = logicGates;
SaveVersion = saveVersion;
@@ -40,7 +40,7 @@ internal class WorldReaderV1 : IWorldReader
progress.Report(new(0, "Opening file"));
reader = new BinaryReader(File.OpenRead(Paths.GetWorldSaveFilePath(saveName)));
int saveVersion = reader.ReadUInt16();
ushort saveVersion = reader.ReadUInt16();
int numberOfLogicGates = reader.ReadInt32();
@@ -9,18 +9,16 @@ namespace StoneRed.LogicSimulator.WorldSaveSystem;
internal class WorldSaver
{
private readonly Srls srls;
public WorldSaver(Srls srls)
public WorldSaver(Srls _)
{
this.srls = srls;
}
public Task<Result> SaveWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
{
IWorldWriter? worldWriter = worldData.SaveVersion switch
{
1 => new WorldWriterV1(srls),
1 => new WorldWriterV1(),
_ => null
};
@@ -3,6 +3,7 @@
using StoneRed.LogicSimulator.Misc;
using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes;
using StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
using StoneRed.LogicSimulator.Utilities;
using System;
using System.IO;
@@ -13,13 +14,6 @@ namespace StoneRed.LogicSimulator.WorldSaveSystem.WorldWriters;
internal class WorldWriterV1 : IWorldWriter
{
private readonly Srls srls;
public WorldWriterV1(Srls srls)
{
this.srls = srls;
}
public Task<Result> WriteWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
{
return Task.Run(() => InternalWriteWorld(worldData, progress));
@@ -39,14 +33,14 @@ internal class WorldWriterV1 : IWorldWriter
int numberOfLogicGates = worldData.LogicGates.Count();
writer.Write((short)1); // Write file version
writer.Write((ushort)1); // Write file version
writer.Write(numberOfLogicGates);
foreach (LogicGate logicGate in worldData.LogicGates)
{
writer.Write(logicGate.Id);
if (!srls.LogicGatesManager.TryGetTypeName(logicGate.GetType(), out string? typeName))
if (!LogicGatesManager.TryGetTypeLogicGateName(logicGate.GetType(), out string? typeName))
{
return Result.Fail($"Logic gate type \"{logicGate.GetType().FullName}\" has no \"{nameof(LogicGateNameAttribute)}\" attribute!");
}