Some bug fixes and add IDrawable interface

This commit is contained in:
Stone_Red
2023-09-13 12:21:43 +02:00
parent b1b185919b
commit 05a8a72158
7 changed files with 98 additions and 50 deletions
@@ -1,8 +1,8 @@
<Project StylesheetPath="C:\Users\David\My Drive\Programming\StoneRed.LogicSimulator\StoneRed.LogicSimulator\Content\stylesheet\default_ui_skin.xmms"> <Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions /> <Project.ExportOptions />
<VerticalStackPanel BorderThickness="1" Padding="0, 10, 0, 5" Background="#333130FF" Border="#1BA1E2FF"> <VerticalStackPanel BorderThickness="1" Padding="0, 10, 0, 5" Background="#333130FF" Border="#1BA1E2FF">
<Label Text="Context Menu" Margin="10, 0" ClipToBounds="True" Id="title" /> <Label Text="Context Menu" Margin="10, 0" ClipToBounds="True" Id="title" />
<TextButton Text="Settings" Margin="10, 10, 10, 0" BorderThickness="1" Padding="5" HorizontalAlignment="Center" Scale="0.9, 0.9" Border="#5BC6FAFF" Id="button" /> <TextButton Text="Settings" Margin="10, 10, 10, 0" BorderThickness="1" Padding="5" HorizontalAlignment="Center" Scale="0.9, 0.9" Border="#5BC6FAFF" Id="button" />
<VerticalMenu HorizontalAlignment="Stretch" Margin="0, 10, 0, 0" BorderThickness="0, 1, 0, 0" Padding="0, 10, 0, 5" Background="#333130FF" Id="menu" /> <VerticalMenu HorizontalAlignment="Stretch" Margin="0, 10, 0, 0" BorderThickness="0, 1, 0, 0" Padding="0, 10, 0, 5" Background="#333130FF" Id="menu" />
</VerticalStackPanel> </VerticalStackPanel>
</Project> </Project>
@@ -1,9 +1,9 @@
<Project StylesheetPath="C:\Users\David\My Drive\Programming\StoneRed.LogicSimulator\StoneRed.LogicSimulator\Content\stylesheet\default_ui_skin.xmms"> <Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions /> <Project.ExportOptions />
<Window Title="Load world" Left="266" Top="198" MinWidth="400"> <Window Title="Load world" Left="266" Top="198" MinWidth="400">
<VerticalStackPanel> <VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" /> <ListBox HorizontalAlignment="Stretch" Id="saves" />
<TextButton Text="Load" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="load" /> <TextButton Text="Load" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="load" />
</VerticalStackPanel> </VerticalStackPanel>
</Window> </Window>
</Project> </Project>
@@ -1,12 +1,12 @@
<Project StylesheetPath="C:\Users\David\My Drive\Programming\StoneRed.LogicSimulator\StoneRed.LogicSimulator\Content\stylesheet\default_ui_skin.xmms"> <Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions /> <Project.ExportOptions />
<Window Title="Load world" Left="266" Top="201" MinWidth="400"> <Window Title="Load world" Left="266" Top="201" MinWidth="400">
<VerticalStackPanel> <VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" /> <ListBox HorizontalAlignment="Stretch" Id="saves" />
<HorizontalStackPanel Spacing="10"> <HorizontalStackPanel Spacing="10">
<TextButton Text="Save" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="save" /> <TextButton Text="Save" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="save" />
<TextButton Text="New Save" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="newSave" /> <TextButton Text="New Save" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="newSave" />
</HorizontalStackPanel> </HorizontalStackPanel>
</VerticalStackPanel> </VerticalStackPanel>
</Window> </Window>
</Project> </Project>
@@ -0,0 +1,8 @@
using Microsoft.Xna.Framework.Graphics;
namespace StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
internal interface IDrawable
{
Texture2D Texture { get; }
}
@@ -1,4 +1,6 @@
using StoneRed.LogicSimulator.Utilities; using Microsoft.Xna.Framework.Graphics;
using StoneRed.LogicSimulator.Utilities;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -14,22 +16,22 @@ internal abstract class LogicGate
private int newInput; private int newInput;
private int output; private int output;
private int cachedOutput; private int cachedOutput;
internal GraphicsDevice? GraphicsDevice { get; set; }
public LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData(); internal LogicGateWorldData WorldData { get; init; } = new LogicGateWorldData();
public ulong Id { get; internal set; } internal ulong Id { get; set; }
public IReadOnlyList<LogicGateConnection> LogicGateConnections => logicGateConnections.AsReadOnly(); public IReadOnlyList<LogicGateConnection> LogicGateConnections => logicGateConnections.AsReadOnly();
public abstract int OutputCount { get; set; } public abstract int OutputCount { get; set; }
public abstract int InputCount { get; set; } public abstract int InputCount { get; set; }
public void NextTick() internal void NextTick()
{ {
currentInput = newInput; currentInput = newInput;
newInput = 0; newInput = 0;
output = 0; output = 0;
} }
public void SetInput(int value, int index) internal void SetInput(int value, int index)
{ {
if (index >= InputCount) 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) if (inputIndex >= logicGate.InputCount)
{ {
@@ -56,30 +58,37 @@ internal abstract class LogicGate
throw new IndexOutOfRangeException(); 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 lock (logicGateConnections)
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 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); lock (logicGateConnections)
logicGateConnections.RemoveAt(index); {
int index = logicGateConnections.FindIndex(c => c.LogicGate.Id == logicGate.Id);
logicGateConnections.RemoveAt(index);
}
} }
public void Update() internal void Update()
{ {
Execute(); Execute();
cachedOutput = output; cachedOutput = output;
PublishOutput(); PublishOutput();
} }
public int GetCachedOutputBit(int index) internal int GetCachedOutputBit(int index)
{ {
if (index < 0 || index >= OutputCount) if (index < 0 || index >= OutputCount)
{ {
@@ -122,11 +131,19 @@ internal abstract class LogicGate
output.SetBit(value, index); output.SetBit(value, index);
} }
protected Texture2D CreateTexture(int width, int height)
{
return new Texture2D(GraphicsDevice, width, height);
}
private void PublishOutput() 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);
}
} }
} }
} }
@@ -108,19 +108,28 @@ internal class WorldScreen : SrlsScreen<Grid>
{ {
color = colorable.Color; color = colorable.Color;
} }
if (logicGate is IInteractable interactable) if (logicGate is IInteractable interactable)
{ {
richTextLayout.Text = interactable.Info; 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); 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 // Draw text for components
richTextLayout.Text = logicGate.WorldData.Name; richTextLayout.Text = logicGate.WorldData.Name;
richTextLayout.Draw(srls.SpriteBatch, logicGate.WorldData.Position * srls.Scale, Color.Black, new Vector2(srls.Scale, srls.Scale), layerDepth: 0); 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 // Draw logic gate connections
foreach (LogicGateConnection connection in logicGate.LogicGateConnections) foreach (LogicGateConnection connection in logicGate.LogicGateConnections)
{ {
@@ -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 StoneRed.LogicSimulator.Simulation.LogicGates.Interfaces;
using System; using System;
@@ -10,6 +12,13 @@ namespace StoneRed.LogicSimulator.Utilities;
internal class LogicGatesManager internal class LogicGatesManager
{ {
private readonly GraphicsDevice graphicsDevice;
public LogicGatesManager(GraphicsDevice graphicsDevice)
{
this.graphicsDevice = graphicsDevice;
}
private readonly Dictionary<LogicGateInfo, Type> logicGates = new Dictionary<LogicGateInfo, Type>(); private readonly Dictionary<LogicGateInfo, Type> logicGates = new Dictionary<LogicGateInfo, Type>();
public void LoadLogicGates() public void LoadLogicGates()
@@ -44,7 +53,10 @@ internal class LogicGatesManager
{ {
Type type = logicGates[new LogicGateInfo(typeName, null)]; 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) public string GetTypeName(Type type)
@@ -76,6 +88,8 @@ internal class LogicGatesManager
Type type = logicGates[new LogicGateInfo(typeName, null)]; Type type = logicGates[new LogicGateInfo(typeName, null)];
logicGate = (LogicGate)Activator.CreateInstance(type)!; logicGate = (LogicGate)Activator.CreateInstance(type)!;
logicGate.GraphicsDevice = graphicsDevice;
return true; return true;
} }
} }