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.ExportOptions />
<VerticalStackPanel BorderThickness="1" Padding="0, 10, 0, 5" Background="#333130FF" Border="#1BA1E2FF">
<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" />
<VerticalMenu HorizontalAlignment="Stretch" Margin="0, 10, 0, 0" BorderThickness="0, 1, 0, 0" Padding="0, 10, 0, 5" Background="#333130FF" Id="menu" />
</VerticalStackPanel>
<Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions />
<VerticalStackPanel BorderThickness="1" Padding="0, 10, 0, 5" Background="#333130FF" Border="#1BA1E2FF">
<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" />
<VerticalMenu HorizontalAlignment="Stretch" Margin="0, 10, 0, 0" BorderThickness="0, 1, 0, 0" Padding="0, 10, 0, 5" Background="#333130FF" Id="menu" />
</VerticalStackPanel>
</Project>
@@ -1,9 +1,9 @@
<Project StylesheetPath="C:\Users\David\My Drive\Programming\StoneRed.LogicSimulator\StoneRed.LogicSimulator\Content\stylesheet\default_ui_skin.xmms">
<Project.ExportOptions />
<Window Title="Load world" Left="266" Top="198" MinWidth="400">
<VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" />
<TextButton Text="Load" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="load" />
</VerticalStackPanel>
</Window>
<Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions />
<Window Title="Load world" Left="266" Top="198" MinWidth="400">
<VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" />
<TextButton Text="Load" Enabled="False" Margin="0, 10, 0, 0" Padding="5, 5, 8, 5" Id="load" />
</VerticalStackPanel>
</Window>
</Project>
@@ -1,12 +1,12 @@
<Project StylesheetPath="C:\Users\David\My Drive\Programming\StoneRed.LogicSimulator\StoneRed.LogicSimulator\Content\stylesheet\default_ui_skin.xmms">
<Project.ExportOptions />
<Window Title="Load world" Left="266" Top="201" MinWidth="400">
<VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" />
<HorizontalStackPanel Spacing="10">
<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" />
</HorizontalStackPanel>
</VerticalStackPanel>
</Window>
<Project StylesheetPath="stylesheet/default_ui_skin.xmms">
<Project.ExportOptions />
<Window Title="Load world" Left="266" Top="201" MinWidth="400">
<VerticalStackPanel>
<ListBox HorizontalAlignment="Stretch" Id="saves" />
<HorizontalStackPanel Spacing="10">
<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" />
</HorizontalStackPanel>
</VerticalStackPanel>
</Window>
</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.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<LogicGateConnection> 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);
}
}
}
}
@@ -108,19 +108,28 @@ internal class WorldScreen : SrlsScreen<Grid>
{
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)
{
@@ -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<LogicGateInfo, Type> logicGates = new Dictionary<LogicGateInfo, Type>();
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;
}
}