Skip to content

Commit 993f7d2

Browse files
arena string improvements
1 parent 2ec93ad commit 993f7d2

File tree

6 files changed

+76
-54
lines changed

6 files changed

+76
-54
lines changed

Flamui/ArenaList.cs

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,24 +29,29 @@ public ArenaList(Arena arena, int initialCapacity = 1)
2929
_backingSliceAllocateNum = arena.AllocNum;
3030
}
3131

32-
public unsafe void Add(T value)
32+
public void AddRange(ReadOnlySpan<T> values)
3333
{
34-
var arena = Ui.Arena;
34+
EnsureInit();
35+
ResizeIfNeeded(Count + values.Length);
36+
values.CopyTo(_backingSlice.Span.Slice(Count));
37+
Count += values.Length;
38+
}
3539

36-
if (_arenaHash == 0)
37-
_arenaHash = arena.GetHashCode();
40+
public void Add(T value)
41+
{
42+
EnsureInit();
3843

39-
Debug.Assert(arena.GetHashCode() == _arenaHash);
44+
ResizeIfNeeded(Count);
4045

41-
if (Capacity == 0) //in case the ArenaList isn't initialized via the constructor
42-
{
43-
_backingSlice = arena.AllocateSlice<T>(1);
44-
_backingSliceAllocateNum = arena.AllocNum;
45-
}
46+
_backingSlice[Count] = value;
47+
Count++;
48+
}
4649

47-
Debug.Assert(Count <= Capacity);
50+
private unsafe void ResizeIfNeeded(int neededCapacity)
51+
{
52+
var arena = Ui.Arena;
4853

49-
if (Count == Capacity)
54+
if (neededCapacity >= Capacity)
5055
{
5156
//if there hasn't been another allocation on the arena, we don't need to allocate a new slice, we can just "extend" the current one
5257

@@ -62,14 +67,11 @@ public unsafe void Add(T value)
6267
{
6368
var newSlice = arena.AllocateSlice<T>(Capacity * 2);
6469
_backingSliceAllocateNum = arena.AllocNum;
65-
70+
6671
_backingSlice.Span.CopyTo(newSlice.Span);
6772
_backingSlice = newSlice;
6873
}
6974
}
70-
71-
_backingSlice[Count] = value;
72-
Count++;
7375
}
7476

7577
public ref T this[int index]
@@ -103,6 +105,23 @@ public Enumerator GetEnumerator()
103105
return new Enumerator(this);
104106
}
105107

108+
private void EnsureInit()
109+
{
110+
var arena = Ui.Arena;
111+
112+
if (_arenaHash == 0)
113+
_arenaHash = arena.GetHashCode();
114+
115+
Debug.Assert(arena.GetHashCode() == _arenaHash);
116+
117+
if (Capacity == 0) //in case the ArenaList isn't initialized via the constructor
118+
{
119+
_backingSlice = arena.AllocateSlice<T>(1);
120+
_backingSliceAllocateNum = arena.AllocNum;
121+
}
122+
Debug.Assert(Count <= Capacity);
123+
}
124+
106125
IEnumerator<T> IEnumerable<T>.GetEnumerator()
107126
{
108127
return GetEnumerator();

Flamui/ArenaString.cs

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,29 @@ namespace Flamui;
55

66
public struct ArenaStringBuilder
77
{
8-
private readonly Arena _arena;
8+
public ArenaList<char> _backingList;
99

1010
public ArenaStringBuilder(Arena arena, int capacity)
1111
{
12-
_arena = arena;
12+
_backingList = new ArenaList<char>(arena, capacity);
1313
}
1414

1515
public void Add(ArenaString arenaString)
1616
{
17-
17+
_backingList.AddRange(arenaString.AsSpan());
1818
}
1919

2020
public void Add<T>(T val)
2121
{
22-
if (val is int i) {
23-
i.ToArenaString();
24-
}
25-
else if (val is bool b) {
26-
b.ToArenaString();
27-
}
28-
else if (val is char c) {
29-
c.ToArenaString();
30-
}
22+
var arenaString = val switch
23+
{
24+
int i => i.ToArenaString(),
25+
bool b => b.ToArenaString(),
26+
char c => c.ToArenaString(),
27+
string s => s,
28+
_ => throw new Exception($"{typeof(T)} is currently not supported :(")
29+
};
30+
Add(arenaString);
3131
}
3232

3333
public ArenaString Build()
@@ -85,7 +85,7 @@ public static unsafe ArenaString ToArenaString(this char i)
8585
[InterpolatedStringHandler]
8686
public struct ArenaString : IEquatable<ArenaString> //todo implement IEnumerable
8787
{
88-
// private ArenaStringBuilder _arenaStringBuilder;
88+
private ArenaStringBuilder _arenaStringBuilder;
8989
private Slice<char> _slice;
9090

9191
public int Length => _slice.Length;
@@ -137,20 +137,23 @@ public override string ToString()
137137
return AsSpan().ToString();
138138
}
139139

140-
// public ArenaString(int literalLength, int formattedCount)
141-
// {
142-
// _arenaStringBuilder = new ArenaStringBuilder(Ui.Arena, literalLength);
143-
// }
144-
//
145-
// public void AppendLiteral(string s)
146-
// {
147-
// _arenaStringBuilder.Add((ArenaString)s);
148-
// }
149-
//
150-
// public void AppendFormatted<T>(T t)
151-
// {
152-
// _arenaStringBuilder.Add(t);
153-
// }
140+
public ArenaString(int literalLength, int formattedCount)
141+
{
142+
_arenaStringBuilder = new ArenaStringBuilder(Ui.Arena, literalLength);
143+
}
144+
145+
public void AppendLiteral(string s)
146+
{
147+
_arenaStringBuilder.Add((ArenaString)s);
148+
_slice = _arenaStringBuilder._backingList.AsSlice();
149+
}
150+
151+
public void AppendFormatted<T>(T t)
152+
{
153+
_arenaStringBuilder.Add(t);
154+
_slice = _arenaStringBuilder._backingList.AsSlice();
155+
}
156+
154157
public bool Equals(ArenaString other)
155158
{
156159
return other.AsSpan().SequenceEqual(AsSpan());

Flamui/Ui.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public FlexContainer Div(
8484
return div;
8585
}
8686

87-
public UiText Text(string content,
87+
public UiText Text(ArenaString content,
8888
string key = "",
8989
[CallerFilePath] string path = "",
9090
[CallerLineNumber] int line = -1)
@@ -106,7 +106,7 @@ public UiText Text(string content,
106106
return text;
107107
}
108108

109-
public UiSvg SvgImage(string src, ColorDefinition? colorDefinition = null,
109+
public UiSvg SvgImage(ArenaString src, ColorDefinition? colorDefinition = null,
110110
string key = "",
111111
[CallerFilePath] string path = "",
112112
[CallerLineNumber] int line = -1)

Flamui/UiElements/UiSvg.cs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
using System.Numerics;
2-
using System.Runtime.InteropServices;
1+
using System.Runtime.InteropServices;
32
using Flamui.Drawing;
43
using Flamui.Layouting;
54
using Point = Flamui.Layouting.Point;
@@ -9,9 +8,9 @@ namespace Flamui.UiElements;
98
//Todo, we should probably offload svg loading onto a separate thread, or do them async etc., or maybe preload them
109
public class UiSvg : UiElement
1110
{
12-
public string Src { get; set; } = null!;
11+
public ArenaString Src { get; set; } = default;
1312
public ColorDefinition? ColorDefinition { get; set; }
14-
private static readonly Dictionary<string, (Slice<byte>, float aspectRatio)> SSvgCache = new();
13+
private static readonly Dictionary<int, (Slice<byte>, float aspectRatio)> SSvgCache = new();
1514

1615
public override void Render(RenderContext renderContext, Point offset)
1716
{
@@ -51,9 +50,9 @@ public override BoxSize Layout(BoxConstraint constraint)
5150

5251
private unsafe (Slice<byte>, float aspectRatio) GetBitmap()
5352
{
54-
if (!SSvgCache.TryGetValue(Src, out var entry))
53+
if (!SSvgCache.TryGetValue(Src.GetHashCode(), out var entry))
5554
{
56-
var bytes = File.ReadAllBytes(Src);
55+
var bytes = File.ReadAllBytes(Src.ToString());
5756

5857
var (width, height) = TinyVG.ParseHeader(bytes);
5958

@@ -62,7 +61,7 @@ private unsafe (Slice<byte>, float aspectRatio) GetBitmap()
6261
bytes.AsSpan().CopyTo(dest);
6362

6463
entry = (new Slice<byte>(ptr, bytes.Length), (float)width / (float)height);
65-
SSvgCache.Add(Src, entry);
64+
SSvgCache.Add(Src.GetHashCode(), entry);
6665
}
6766

6867
return entry;

Flamui/UiElements/UiText.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public UiTextInfo()
1717
public TextAlign HorizontalAlignment = TextAlign.Start;
1818
public TextAlign VerticalAlignment = TextAlign.Center;
1919
public bool Multiline;
20-
public string Content = string.Empty;
20+
public ArenaString Content = default;
2121
}
2222

2323
public struct TextPosition

Sample.LayoutTest/Program.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,10 +49,11 @@ public class LayoutTest(FlamuiApp app) : FlamuiComponent
4949

5050
public override void Build(Ui ui)
5151
{
52-
using (ui.Div().Margin(10).Color(C.Gray6).ScrollVertical().Clip())
52+
using (ui.Div().Margin(10).Color(C.Gray6).ScrollVertical().Clip().Padding(10))
5353
{
5454
foreach (var icon in icons)
5555
{
56+
ui.Text(icon, icon).Size(20);
5657
using (ui.Div(icon).Width(100).Height(100))
5758
{
5859
ui.SvgImage($"Icons/TVG/{icon}");

0 commit comments

Comments
 (0)