mirror of
https://github.com/Stone-Red-Code/StoneRed.LogicSimulator.git
synced 2026-09-04 00:56:23 +02:00
Fix some bugs and add TestLogicGate
This commit is contained in:
@@ -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
|
||||||
@@ -36,6 +36,8 @@ internal class Srls : Game
|
|||||||
|
|
||||||
public Settings Settings { get; set; }
|
public Settings Settings { get; set; }
|
||||||
|
|
||||||
|
public const ushort CurrentSaveVersion = 1;
|
||||||
|
|
||||||
public Srls()
|
public Srls()
|
||||||
{
|
{
|
||||||
Content.RootDirectory = "Content";
|
Content.RootDirectory = "Content";
|
||||||
@@ -162,7 +164,7 @@ internal class Srls : Game
|
|||||||
FileAssetResolver assetResolver = new FileAssetResolver(Paths.GetContentPath());
|
FileAssetResolver assetResolver = new FileAssetResolver(Paths.GetContentPath());
|
||||||
AssetManager = new AssetManager(assetResolver);
|
AssetManager = new AssetManager(assetResolver);
|
||||||
|
|
||||||
LogicGatesManager = new LogicGatesManager();
|
LogicGatesManager = new LogicGatesManager(GraphicsDevice);
|
||||||
LogicGatesManager.LoadLogicGates();
|
LogicGatesManager.LoadLogicGates();
|
||||||
|
|
||||||
LoadScreen<StartScreen>();
|
LoadScreen<StartScreen>();
|
||||||
|
|||||||
@@ -49,8 +49,8 @@ internal class LoadingScreen : SrlsScreen<VerticalStackPanel>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
srls.ShowWindow(new InfoDialog(string.Join(',', result.Errors.Select(e => e.Message))));
|
|
||||||
srls.LoadScreen<StartScreen>();
|
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()
|
public WorldScreen()
|
||||||
{
|
{
|
||||||
simulator = new LogicGateSimulator(Enumerable.Empty<LogicGate>());
|
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()
|
protected override void Initialize()
|
||||||
@@ -173,7 +173,7 @@ internal class WorldScreen : SrlsScreen<Grid>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fpsLabel.Text = $"FPS: {Math.Round(fps)}";
|
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)}";
|
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();
|
simulator.TargetTicksPerSecond = (int)frequency.Value.GetValueOrDefault();
|
||||||
@@ -222,8 +222,15 @@ internal class WorldScreen : SrlsScreen<Grid>
|
|||||||
{
|
{
|
||||||
selectedLogicGate.WorldData.Position /= srls.Scale;
|
selectedLogicGate.WorldData.Position /= srls.Scale;
|
||||||
simulator.AddLogicGate(selectedLogicGate);
|
simulator.AddLogicGate(selectedLogicGate);
|
||||||
selectedLogicGate = null;
|
|
||||||
nativeComponentsListBox.SelectedIndex = -1;
|
if (keyboardState.IsShiftDown())
|
||||||
|
{
|
||||||
|
SelectLogicGate();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UnSelectLogicGate();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -236,12 +243,12 @@ internal class WorldScreen : SrlsScreen<Grid>
|
|||||||
|
|
||||||
if (keyboardState.IsKeyDown(Keys.C))
|
if (keyboardState.IsKeyDown(Keys.C))
|
||||||
{
|
{
|
||||||
connectionContext = null;
|
UnSelectLogicGate();
|
||||||
selectedLogicGate = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keyboardState.IsKeyDown(Keys.Q))
|
if (keyboardState.IsKeyDown(Keys.Q))
|
||||||
{
|
{
|
||||||
|
UnSelectLogicGate();
|
||||||
worldData.LogicGates = simulator.GetLogicGates();
|
worldData.LogicGates = simulator.GetLogicGates();
|
||||||
srls.ShowWindow(new QuickMenu(worldData));
|
srls.ShowWindow(new QuickMenu(worldData));
|
||||||
}
|
}
|
||||||
@@ -278,7 +285,7 @@ internal class WorldScreen : SrlsScreen<Grid>
|
|||||||
return r < 0 ? r + m : r;
|
return r < 0 ? r + m : r;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NativeComponentsListBox_SelectedIndexChanged(object? sender, EventArgs e)
|
private void SelectLogicGate()
|
||||||
{
|
{
|
||||||
if (nativeComponentsListBox.SelectedItem is not null)
|
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)
|
private void ShowConnectionContextMenu(LogicGate logicGate, Point position, bool showInputs)
|
||||||
{
|
{
|
||||||
showInputs = logicGate.OutputCount <= 0 || (showInputs && logicGate.InputCount > 0);
|
showInputs = logicGate.OutputCount <= 0 || (showInputs && logicGate.InputCount > 0);
|
||||||
|
|||||||
@@ -59,13 +59,13 @@ internal class LogicGatesManager
|
|||||||
return logicGate;
|
return logicGate;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetTypeName(Type type)
|
public static string GetTypeLogicGateName(Type type)
|
||||||
{
|
{
|
||||||
LogicGateNameAttribute nameAttribute = (LogicGateNameAttribute)type.GetCustomAttributes(typeof(LogicGateNameAttribute), false)[0];
|
LogicGateNameAttribute nameAttribute = (LogicGateNameAttribute)type.GetCustomAttributes(typeof(LogicGateNameAttribute), false)[0];
|
||||||
return nameAttribute.Name;
|
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)
|
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 IEnumerable<LogicGate> LogicGates { get; set; }
|
||||||
|
|
||||||
public int SaveVersion { get; set; }
|
public ushort SaveVersion { get; set; }
|
||||||
|
|
||||||
public string SaveName { 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;
|
LogicGates = logicGates;
|
||||||
SaveVersion = saveVersion;
|
SaveVersion = saveVersion;
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ internal class WorldReaderV1 : IWorldReader
|
|||||||
progress.Report(new(0, "Opening file"));
|
progress.Report(new(0, "Opening file"));
|
||||||
|
|
||||||
reader = new BinaryReader(File.OpenRead(Paths.GetWorldSaveFilePath(saveName)));
|
reader = new BinaryReader(File.OpenRead(Paths.GetWorldSaveFilePath(saveName)));
|
||||||
int saveVersion = reader.ReadUInt16();
|
ushort saveVersion = reader.ReadUInt16();
|
||||||
|
|
||||||
int numberOfLogicGates = reader.ReadInt32();
|
int numberOfLogicGates = reader.ReadInt32();
|
||||||
|
|
||||||
|
|||||||
@@ -9,18 +9,16 @@ namespace StoneRed.LogicSimulator.WorldSaveSystem;
|
|||||||
|
|
||||||
internal class WorldSaver
|
internal class WorldSaver
|
||||||
{
|
{
|
||||||
private readonly Srls srls;
|
public WorldSaver(Srls _)
|
||||||
|
|
||||||
public WorldSaver(Srls srls)
|
|
||||||
{
|
{
|
||||||
this.srls = srls;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task<Result> SaveWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
|
public Task<Result> SaveWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
|
||||||
{
|
{
|
||||||
IWorldWriter? worldWriter = worldData.SaveVersion switch
|
IWorldWriter? worldWriter = worldData.SaveVersion switch
|
||||||
{
|
{
|
||||||
1 => new WorldWriterV1(srls),
|
1 => new WorldWriterV1(),
|
||||||
_ => null
|
_ => null
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
using StoneRed.LogicSimulator.Misc;
|
using StoneRed.LogicSimulator.Misc;
|
||||||
using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes;
|
using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes;
|
||||||
using StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
|
using StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
|
||||||
|
using StoneRed.LogicSimulator.Utilities;
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@@ -13,13 +14,6 @@ namespace StoneRed.LogicSimulator.WorldSaveSystem.WorldWriters;
|
|||||||
|
|
||||||
internal class WorldWriterV1 : IWorldWriter
|
internal class WorldWriterV1 : IWorldWriter
|
||||||
{
|
{
|
||||||
private readonly Srls srls;
|
|
||||||
|
|
||||||
public WorldWriterV1(Srls srls)
|
|
||||||
{
|
|
||||||
this.srls = srls;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task<Result> WriteWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
|
public Task<Result> WriteWorld(WorldData worldData, IProgress<WorldSaveLoadProgress> progress)
|
||||||
{
|
{
|
||||||
return Task.Run(() => InternalWriteWorld(worldData, progress));
|
return Task.Run(() => InternalWriteWorld(worldData, progress));
|
||||||
@@ -39,14 +33,14 @@ internal class WorldWriterV1 : IWorldWriter
|
|||||||
|
|
||||||
int numberOfLogicGates = worldData.LogicGates.Count();
|
int numberOfLogicGates = worldData.LogicGates.Count();
|
||||||
|
|
||||||
writer.Write((short)1); // Write file version
|
writer.Write((ushort)1); // Write file version
|
||||||
writer.Write(numberOfLogicGates);
|
writer.Write(numberOfLogicGates);
|
||||||
|
|
||||||
foreach (LogicGate logicGate in worldData.LogicGates)
|
foreach (LogicGate logicGate in worldData.LogicGates)
|
||||||
{
|
{
|
||||||
writer.Write(logicGate.Id);
|
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!");
|
return Result.Fail($"Logic gate type \"{logicGate.GetType().FullName}\" has no \"{nameof(LogicGateNameAttribute)}\" attribute!");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user