mirror of
https://github.com/Stone-Red-Code/StoneRed.LogicSimulator.git
synced 2026-09-07 07:55:58 +02:00
Some bug fixes and add IDrawable interface
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user