From 05a8a7215891417c79b98e9a6632aa2c905bc435 Mon Sep 17 00:00:00 2001 From: Stone_Red <56473591+Stone-Red-Code@users.noreply.github.com> Date: Wed, 13 Sep 2023 12:21:43 +0200 Subject: [PATCH] Some bug fixes and add `IDrawable` interface --- .../Content/ContextMenu.xmmp | 14 ++--- .../Content/LoadWorldWindow.xmmp | 16 +++--- .../Content/SaveWorldWindow.xmmp | 22 ++++---- .../LogicGates/Interfaces/IDrawable.cs | 8 +++ .../LogicGates/Interfaces/LogicGate.cs | 55 ++++++++++++------- .../UserInterface/Screens/WorldScreen.cs | 15 ++++- .../Utilities/LogicGatesManager.cs | 18 +++++- 7 files changed, 98 insertions(+), 50 deletions(-) create mode 100644 StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/IDrawable.cs diff --git a/StoneRed.LogicSimulator/Content/ContextMenu.xmmp b/StoneRed.LogicSimulator/Content/ContextMenu.xmmp index ff69662..872ee51 100644 --- a/StoneRed.LogicSimulator/Content/ContextMenu.xmmp +++ b/StoneRed.LogicSimulator/Content/ContextMenu.xmmp @@ -1,8 +1,8 @@ - - - - + + + + \ No newline at end of file diff --git a/StoneRed.LogicSimulator/Content/LoadWorldWindow.xmmp b/StoneRed.LogicSimulator/Content/LoadWorldWindow.xmmp index f1536dc..a377be3 100644 --- a/StoneRed.LogicSimulator/Content/LoadWorldWindow.xmmp +++ b/StoneRed.LogicSimulator/Content/LoadWorldWindow.xmmp @@ -1,9 +1,9 @@ - - - - - - - - + + + + + + + + \ No newline at end of file diff --git a/StoneRed.LogicSimulator/Content/SaveWorldWindow.xmmp b/StoneRed.LogicSimulator/Content/SaveWorldWindow.xmmp index 8ce91e9..85870b4 100644 --- a/StoneRed.LogicSimulator/Content/SaveWorldWindow.xmmp +++ b/StoneRed.LogicSimulator/Content/SaveWorldWindow.xmmp @@ -1,12 +1,12 @@ - - - - - - - - - - - + + + + + + + + + + + \ No newline at end of file diff --git a/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/IDrawable.cs b/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/IDrawable.cs new file mode 100644 index 0000000..d5f4129 --- /dev/null +++ b/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/IDrawable.cs @@ -0,0 +1,8 @@ +using Microsoft.Xna.Framework.Graphics; + +namespace StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces; + +internal interface IDrawable +{ + Texture2D Texture { get; } +} \ No newline at end of file diff --git a/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/LogicGate.cs b/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/LogicGate.cs index d6e5317..fe1edc9 100644 --- a/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/LogicGate.cs +++ b/StoneRed.LogicSimulator/Simulation/LogicGates/Interfaces/LogicGate.cs @@ -1,4 +1,6 @@ -using StoneRed.LogicSimulator.Utilities; +using Microsoft.Xna.Framework.Graphics; + +using StoneRed.LogicSimulator.Utilities; using System; using System.Collections.Generic; @@ -14,22 +16,22 @@ internal abstract class LogicGate private int newInput; private int output; private int cachedOutput; - - public LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData(); - public ulong Id { get; internal set; } + internal GraphicsDevice? GraphicsDevice { get; set; } + internal LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData(); + internal ulong Id { get; set; } public IReadOnlyList LogicGateConnections => logicGateConnections.AsReadOnly(); public abstract int OutputCount { get; set; } public abstract int InputCount { get; set; } - public void NextTick() + internal void NextTick() { currentInput = newInput; newInput = 0; output = 0; } - public void SetInput(int value, int index) + internal void SetInput(int value, int index) { if (index >= InputCount) { @@ -44,7 +46,7 @@ internal abstract class LogicGate } } - public void Connect(LogicGate logicGate, int inputIndex, int outputIndex) + internal void Connect(LogicGate logicGate, int inputIndex, int outputIndex) { if (inputIndex >= logicGate.InputCount) { @@ -56,30 +58,37 @@ internal abstract class LogicGate throw new IndexOutOfRangeException(); } - logicGateConnections.Add(new LogicGateConnection(logicGate, inputIndex, outputIndex)); + lock (logicGateConnections) + { + logicGateConnections.Add(new LogicGateConnection(logicGate, inputIndex, outputIndex)); + } } - public bool IsConnectedTo(LogicGate logicGate) + internal bool IsConnectedTo(LogicGate logicGate) { -#pragma warning disable S6605 // Collection-specific "Exists" method should be used instead of the "Any" extension - return logicGateConnections.Any(c => c.LogicGate.Id == logicGate.Id); -#pragma warning restore S6605 // Collection-specific "Exists" method should be used instead of the "Any" extension + lock (logicGateConnections) + { + return logicGateConnections.Any(c => c.LogicGate.Id == logicGate.Id); + } } - public void Disconnect(LogicGate logicGate) + internal void Disconnect(LogicGate logicGate) { - int index = logicGateConnections.FindIndex(c => c.LogicGate.Id == logicGate.Id); - logicGateConnections.RemoveAt(index); + lock (logicGateConnections) + { + int index = logicGateConnections.FindIndex(c => c.LogicGate.Id == logicGate.Id); + logicGateConnections.RemoveAt(index); + } } - public void Update() + internal void Update() { Execute(); cachedOutput = output; PublishOutput(); } - public int GetCachedOutputBit(int index) + internal int GetCachedOutputBit(int index) { if (index < 0 || index >= OutputCount) { @@ -122,11 +131,19 @@ internal abstract class LogicGate output.SetBit(value, index); } + protected Texture2D CreateTexture(int width, int height) + { + return new Texture2D(GraphicsDevice, width, height); + } + private void PublishOutput() { - foreach (LogicGateConnection connection in logicGateConnections) + lock (logicGateConnections) { - connection.LogicGate.SetInput(output.GetBit(connection.OutputIndex), connection.InputIndex); + foreach (LogicGateConnection connection in logicGateConnections) + { + connection.LogicGate.SetInput(output.GetBit(connection.OutputIndex), connection.InputIndex); + } } } } diff --git a/StoneRed.LogicSimulator/UserInterface/Screens/WorldScreen.cs b/StoneRed.LogicSimulator/UserInterface/Screens/WorldScreen.cs index d6ee75f..c815e4e 100644 --- a/StoneRed.LogicSimulator/UserInterface/Screens/WorldScreen.cs +++ b/StoneRed.LogicSimulator/UserInterface/Screens/WorldScreen.cs @@ -108,19 +108,28 @@ internal class WorldScreen : SrlsScreen { color = colorable.Color; } + if (logicGate is IInteractable interactable) { richTextLayout.Text = interactable.Info; richTextLayout.Draw(srls.SpriteBatch, (new Vector2(0, 15) * srls.Scale) + (logicGate.WorldData.Position * srls.Scale), Color.Black, new Vector2(srls.Scale, srls.Scale), layerDepth: 0); } + // Draw logic gate + if (logicGate is Simulation.LogicGates.Interfaces.IDrawable drawable) + { + Rectangle rectangle = new Rectangle((logicGate.WorldData.Position * srls.Scale).ToPoint(), (logicGateSize * srls.Scale).ToPoint()); + srls.SpriteBatch.Draw(drawable.Texture, rectangle, null, color, 0, Vector2.Zero, SpriteEffects.None, 0.2f); + } + else + { + srls.SpriteBatch.FillRectangle(logicGate.WorldData.Position * srls.Scale, logicGateSize * srls.Scale, color, 0.2f); + } + // Draw text for components richTextLayout.Text = logicGate.WorldData.Name; richTextLayout.Draw(srls.SpriteBatch, logicGate.WorldData.Position * srls.Scale, Color.Black, new Vector2(srls.Scale, srls.Scale), layerDepth: 0); - // Draw logic gate - srls.SpriteBatch.FillRectangle(logicGate.WorldData.Position * srls.Scale, logicGateSize * srls.Scale, color, 0.2f); - // Draw logic gate connections foreach (LogicGateConnection connection in logicGate.LogicGateConnections) { diff --git a/StoneRed.LogicSimulator/Utilities/LogicGatesManager.cs b/StoneRed.LogicSimulator/Utilities/LogicGatesManager.cs index 33a79df..40e6f3a 100644 --- a/StoneRed.LogicSimulator/Utilities/LogicGatesManager.cs +++ b/StoneRed.LogicSimulator/Utilities/LogicGatesManager.cs @@ -1,4 +1,6 @@ -using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes; +using Microsoft.Xna.Framework.Graphics; + +using StoneRed.LogicSimulator.Simulation.LogicGates.Attributes; using StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces; using System; @@ -10,6 +12,13 @@ namespace StoneRed.LogicSimulator.Utilities; internal class LogicGatesManager { + private readonly GraphicsDevice graphicsDevice; + + public LogicGatesManager(GraphicsDevice graphicsDevice) + { + this.graphicsDevice = graphicsDevice; + } + private readonly Dictionary logicGates = new Dictionary(); public void LoadLogicGates() @@ -44,7 +53,10 @@ internal class LogicGatesManager { Type type = logicGates[new LogicGateInfo(typeName, null)]; - return (LogicGate)Activator.CreateInstance(type)!; + LogicGate logicGate = (LogicGate)Activator.CreateInstance(type)!; + logicGate.GraphicsDevice = graphicsDevice; + + return logicGate; } public string GetTypeName(Type type) @@ -76,6 +88,8 @@ internal class LogicGatesManager Type type = logicGates[new LogicGateInfo(typeName, null)]; logicGate = (LogicGate)Activator.CreateInstance(type)!; + logicGate.GraphicsDevice = graphicsDevice; + return true; } }