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 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!");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user