mirror of
https://github.com/Stone-Red-Code/RemSox.git
synced 2026-09-06 23:41:33 +02:00
Reorganize project structure
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
namespace RemSox.Shared.UI.GUI.Rendering;
|
||||
|
||||
public interface IRenderSource
|
||||
{
|
||||
void Render(IEnumerable<RenderCommand> commands);
|
||||
void Composite();
|
||||
}
|
||||
@@ -0,0 +1,263 @@
|
||||
using System.Drawing;
|
||||
using System.Text;
|
||||
|
||||
namespace RemSox.Shared.UI.GUI.Rendering;
|
||||
|
||||
public class RenderCommand
|
||||
{
|
||||
public required int WindowId { get; set; }
|
||||
public required int ElementId { get; set; }
|
||||
public required RenderCommandType Type { get; set; }
|
||||
public Point Position { get; set; }
|
||||
public Dictionary<string, object?> Properties { get; set; } = [];
|
||||
|
||||
public byte[] ToBytes()
|
||||
{
|
||||
using MemoryStream ms = new();
|
||||
Write(ms);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
public void Write(Stream s)
|
||||
{
|
||||
s.WriteByte((byte)Type);
|
||||
WriteVarint(s, WindowId);
|
||||
WriteVarint(s, ElementId);
|
||||
|
||||
switch (Type)
|
||||
{
|
||||
case RenderCommandType.CreateWindow:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
Size size = GetProp("Size", new Size(160, 120));
|
||||
WriteUInt16(s, size.Width);
|
||||
WriteUInt16(s, size.Height);
|
||||
WriteVarint(s, GetProp("ZIndex", 0));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DestroyWindow:
|
||||
break;
|
||||
|
||||
case RenderCommandType.MoveWindow:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawFilledRect:
|
||||
case RenderCommandType.DrawRectBorder:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
Size rs = GetProp("Size", new Size(10, 10));
|
||||
WriteUInt16(s, rs.Width);
|
||||
WriteUInt16(s, rs.Height);
|
||||
WriteColor(s, GetProp("Color", Color.White));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawFilledCircle:
|
||||
case RenderCommandType.DrawCircle:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
WriteUInt16(s, GetProp("Radius", 10));
|
||||
WriteColor(s, GetProp("Color", Color.White));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawPoint:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
WriteColor(s, GetProp("Color", Color.White));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawText:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
WriteColor(s, GetProp("Color", Color.White));
|
||||
s.WriteByte((byte)GetProp("FontSize", 12));
|
||||
string text = GetProp("Content", string.Empty);
|
||||
byte[] utf8 = Encoding.UTF8.GetBytes(text);
|
||||
WriteVarint(s, utf8.Length);
|
||||
s.Write(utf8, 0, utf8.Length);
|
||||
WriteVarint(s, GetProp("MaxWidth", int.MaxValue));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawLine:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
Point end = GetProp("EndPosition", Position);
|
||||
WriteInt16(s, end.X);
|
||||
WriteInt16(s, end.Y);
|
||||
WriteColor(s, GetProp("Color", Color.White));
|
||||
break;
|
||||
|
||||
case RenderCommandType.RemovePrimitives:
|
||||
break;
|
||||
|
||||
case RenderCommandType.SetCursor:
|
||||
WriteInt16(s, Position.X);
|
||||
WriteInt16(s, Position.Y);
|
||||
break;
|
||||
|
||||
case RenderCommandType.ScreenInfo:
|
||||
WriteUInt16(s, GetProp("Width", 0));
|
||||
WriteUInt16(s, GetProp("Height", 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public static RenderCommand FromBytes(byte[] data)
|
||||
{
|
||||
int offset = 0;
|
||||
RenderCommandType type = (RenderCommandType)data[offset++];
|
||||
int windowId = ReadVarint(data, ref offset);
|
||||
int elementId = ReadVarint(data, ref offset);
|
||||
Point pos = default;
|
||||
Dictionary<string, object?> props = [];
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case RenderCommandType.CreateWindow:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Size"] = new Size(ReadUInt16(data, ref offset), ReadUInt16(data, ref offset));
|
||||
props["ZIndex"] = ReadVarint(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DestroyWindow:
|
||||
break;
|
||||
|
||||
case RenderCommandType.MoveWindow:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawFilledRect:
|
||||
case RenderCommandType.DrawRectBorder:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Size"] = new Size(ReadUInt16(data, ref offset), ReadUInt16(data, ref offset));
|
||||
props["Color"] = ReadColor(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawFilledCircle:
|
||||
case RenderCommandType.DrawCircle:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Radius"] = ReadUInt16(data, ref offset);
|
||||
props["Color"] = ReadColor(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawPoint:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Color"] = ReadColor(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawText:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Color"] = ReadColor(data, ref offset);
|
||||
props["FontSize"] = data[offset++];
|
||||
int textLen = ReadVarint(data, ref offset);
|
||||
props["Content"] = Encoding.UTF8.GetString(data, offset, textLen);
|
||||
offset += textLen;
|
||||
props["MaxWidth"] = ReadVarint(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.DrawLine:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["EndPosition"] = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
props["Color"] = ReadColor(data, ref offset);
|
||||
break;
|
||||
|
||||
case RenderCommandType.RemovePrimitives:
|
||||
break;
|
||||
|
||||
case RenderCommandType.SetCursor:
|
||||
pos = new Point(ReadInt16(data, ref offset), ReadInt16(data, ref offset));
|
||||
break;
|
||||
|
||||
case RenderCommandType.ScreenInfo:
|
||||
props["Width"] = ReadUInt16(data, ref offset);
|
||||
props["Height"] = ReadUInt16(data, ref offset);
|
||||
break;
|
||||
}
|
||||
|
||||
return new RenderCommand
|
||||
{
|
||||
Type = type,
|
||||
WindowId = windowId,
|
||||
ElementId = elementId,
|
||||
Position = pos,
|
||||
Properties = props,
|
||||
};
|
||||
}
|
||||
|
||||
// --- Serialization helpers ---
|
||||
|
||||
private T GetProp<T>(string key, T fallback)
|
||||
{
|
||||
return Properties.TryGetValue(key, out object? raw) && raw is T val ? val : fallback;
|
||||
}
|
||||
|
||||
private static void WriteVarint(Stream s, int value)
|
||||
{
|
||||
uint v = (uint)value;
|
||||
while (v >= 0x80)
|
||||
{
|
||||
s.WriteByte((byte)(v | 0x80));
|
||||
v >>= 7;
|
||||
}
|
||||
s.WriteByte((byte)v);
|
||||
}
|
||||
|
||||
private static void WriteInt16(Stream s, int value)
|
||||
{
|
||||
s.WriteByte((byte)(value & 0xFF));
|
||||
s.WriteByte((byte)((value >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
private static void WriteUInt16(Stream s, int value)
|
||||
{
|
||||
s.WriteByte((byte)(value & 0xFF));
|
||||
s.WriteByte((byte)((value >> 8) & 0xFF));
|
||||
}
|
||||
|
||||
private static void WriteColor(Stream s, Color c)
|
||||
{
|
||||
s.WriteByte(c.R);
|
||||
s.WriteByte(c.G);
|
||||
s.WriteByte(c.B);
|
||||
}
|
||||
|
||||
private static int ReadVarint(byte[] data, ref int offset)
|
||||
{
|
||||
uint result = 0;
|
||||
int shift = 0;
|
||||
while (true)
|
||||
{
|
||||
byte b = data[offset++];
|
||||
result |= (uint)(b & 0x7F) << shift;
|
||||
if ((b & 0x80) == 0)
|
||||
{
|
||||
return (int)result;
|
||||
}
|
||||
|
||||
shift += 7;
|
||||
}
|
||||
}
|
||||
|
||||
private static int ReadInt16(byte[] data, ref int offset)
|
||||
{
|
||||
int lo = data[offset++];
|
||||
int hi = data[offset++];
|
||||
return (short)(lo | (hi << 8));
|
||||
}
|
||||
|
||||
private static int ReadUInt16(byte[] data, ref int offset)
|
||||
{
|
||||
int lo = data[offset++];
|
||||
int hi = data[offset++];
|
||||
return lo | (hi << 8);
|
||||
}
|
||||
|
||||
private static Color ReadColor(byte[] data, ref int offset)
|
||||
{
|
||||
byte r = data[offset++];
|
||||
byte g = data[offset++];
|
||||
byte b = data[offset++];
|
||||
return Color.FromArgb(r, g, b);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
namespace RemSox.Shared.UI.GUI.Rendering;
|
||||
|
||||
/// <summary>
|
||||
/// <para>Render command opcodes, grouped by category:</para>
|
||||
/// <para>
|
||||
/// 0x01–0x0F System/setup<br/>
|
||||
/// 0x10–0x1F Window lifecycle<br/>
|
||||
/// 0x20–0x2F Primitives lifecycle<br/>
|
||||
/// 0x30–0x3F Primitives draw<br/>
|
||||
/// 0x40+ Future expansion
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public enum RenderCommandType : byte
|
||||
{
|
||||
// System / setup (0x01–0x0F)
|
||||
ScreenInfo = 0x01,
|
||||
SetCursor = 0x02,
|
||||
|
||||
// Window lifecycle (0x10–0x1F)
|
||||
CreateWindow = 0x10,
|
||||
DestroyWindow = 0x11,
|
||||
MoveWindow = 0x12,
|
||||
|
||||
// Primitives lifecycle (0x20–0x2F)
|
||||
RemovePrimitives = 0x20,
|
||||
|
||||
// Primitives draw (0x30–0x3F)
|
||||
DrawFilledRect = 0x30,
|
||||
DrawRectBorder = 0x31,
|
||||
DrawFilledCircle = 0x32,
|
||||
DrawCircle = 0x33,
|
||||
DrawText = 0x34,
|
||||
DrawLine = 0x35,
|
||||
DrawPoint = 0x36,
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
namespace RemSox.Shared.UI;
|
||||
|
||||
public record MouseEvent(MouseEventType Type, int X = 0, int Y = 0, MouseButton Button = MouseButton.None, int Delta = 0)
|
||||
{
|
||||
public static MouseEvent Move(int x, int y)
|
||||
{
|
||||
return new(MouseEventType.Move, x, y);
|
||||
}
|
||||
|
||||
public static MouseEvent ButtonDown(int x, int y, MouseButton button)
|
||||
{
|
||||
return new(MouseEventType.ButtonDown, x, y, button);
|
||||
}
|
||||
|
||||
public static MouseEvent ButtonUp(int x, int y, MouseButton button)
|
||||
{
|
||||
return new(MouseEventType.ButtonUp, x, y, button);
|
||||
}
|
||||
|
||||
public static MouseEvent Wheel(int x, int y, int delta)
|
||||
{
|
||||
return new(MouseEventType.Wheel, x, y, Delta: delta);
|
||||
}
|
||||
}
|
||||
|
||||
public enum MouseEventType
|
||||
{
|
||||
Move,
|
||||
ButtonDown,
|
||||
ButtonUp,
|
||||
Wheel
|
||||
}
|
||||
public enum MouseButton
|
||||
{
|
||||
Left,
|
||||
Right,
|
||||
Middle,
|
||||
None
|
||||
}
|
||||
Reference in New Issue
Block a user