Skip to content

Commit 66da13e

Browse files
committed
Added experimental EnumNode.
1 parent 80575cd commit 66da13e

File tree

5 files changed

+287
-1
lines changed

5 files changed

+287
-1
lines changed

ReClass.NET/Nodes/EnumNode.cs

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics.Contracts;
4+
using System.Drawing;
5+
using System.Text;
6+
using ReClassNET.Extensions;
7+
using ReClassNET.Memory;
8+
using ReClassNET.Project;
9+
using ReClassNET.UI;
10+
11+
namespace ReClassNET.Nodes
12+
{
13+
public class EnumNode : BaseNode
14+
{
15+
public override int MemorySize => MetaData.UnderlyingTypeSize;
16+
17+
public EnumMetaData MetaData { get; private set; } = EnumMetaData.Default;
18+
19+
public EnumNode()
20+
{
21+
MetaData = new EnumMetaData
22+
{
23+
Name = "TestEnum"
24+
};
25+
MetaData.SetData(true, 4, new SortedDictionary<long, string>
26+
{
27+
{ 0, "Val0" },
28+
{ 1, "Val1" },
29+
{ 2, "Val2" },
30+
{ 4, "Val4" },
31+
{ 8, "Val8" },
32+
{ 16, "Val16" },
33+
{ 32, "Val32" },
34+
{ 64, "Val64" },
35+
{ 128, "Val128" },
36+
{ 256, "Val256" },
37+
{ 512, "Val512" },
38+
{ 1024, "Val1024" }
39+
});
40+
}
41+
42+
public override void GetUserInterfaceInfo(out string name, out Image icon)
43+
{
44+
name = "Enum";
45+
icon = Properties.Resources.B16x16_Button_Bits;
46+
}
47+
48+
/// <summary>
49+
/// Gets the underlaying node for the enum field.
50+
/// </summary>
51+
/// <returns></returns>
52+
public BaseNumericNode GetUnderlayingNode()
53+
{
54+
switch (MetaData.UnderlyingTypeSize)
55+
{
56+
case 1:
57+
return new UInt8Node();
58+
case 2:
59+
return new UInt16Node();
60+
case 4:
61+
return new UInt32Node();
62+
case 8:
63+
return new UInt64Node();
64+
}
65+
66+
throw new Exception(); // TODO
67+
}
68+
69+
public long ReadValueFromMemory(MemoryBuffer memory)
70+
{
71+
switch (MetaData.UnderlyingTypeSize)
72+
{
73+
case 1:
74+
return memory.ReadInt8(Offset);
75+
case 2:
76+
return memory.ReadInt16(Offset);
77+
case 4:
78+
return memory.ReadInt32(Offset);
79+
case 8:
80+
return memory.ReadInt64(Offset);
81+
}
82+
83+
throw new Exception(); // TODO
84+
}
85+
86+
private string GetStringRepresentation(long value)
87+
{
88+
if (!MetaData.UseFlagsMode)
89+
{
90+
var index = MetaData.Values.FindIndex(v => v == value);
91+
if (index == -1)
92+
{
93+
return value.ToString();
94+
}
95+
96+
return MetaData.Names[index];
97+
}
98+
99+
return GetFlagsStringRepresentation(value);
100+
}
101+
102+
private string GetFlagsStringRepresentation(long value)
103+
{
104+
var result = (ulong)value;
105+
106+
var names = MetaData.Names;
107+
var values = MetaData.Values;
108+
109+
Contract.Assert(names.Count == values.Count);
110+
111+
var index = values.Count - 1;
112+
var retval = new StringBuilder();
113+
var firstTime = true;
114+
var saveResult = result;
115+
116+
while (index >= 0)
117+
{
118+
var temp = (ulong)values[index];
119+
if (index == 0 && temp == 0)
120+
{
121+
break;
122+
}
123+
124+
if ((result & temp) == temp)
125+
{
126+
result -= temp;
127+
if (!firstTime)
128+
{
129+
retval.Prepend(" | ");
130+
}
131+
132+
retval.Prepend(names[index]);
133+
firstTime = false;
134+
}
135+
136+
index--;
137+
}
138+
139+
if (result != 0)
140+
{
141+
return value.ToString();
142+
}
143+
144+
if (saveResult == 0)
145+
{
146+
if (values.Count > 0 && values[0] == 0)
147+
{
148+
return names[0];
149+
}
150+
151+
return "0";
152+
}
153+
154+
return retval.ToString();
155+
}
156+
157+
public override Size Draw(ViewInfo view, int x, int y)
158+
{
159+
if (IsHidden && !IsWrapped)
160+
{
161+
return DrawHidden(view, x, y);
162+
}
163+
164+
var origX = x;
165+
166+
AddSelection(view, x, y, view.Font.Height);
167+
168+
x = AddOpenClose(view, x, y);
169+
x = AddIcon(view, x, y, Icons.Class, -1, HotSpotType.None);
170+
171+
x = AddAddressOffset(view, x, y);
172+
173+
x = AddText(view, x, y, view.Settings.TypeColor, HotSpot.NoneId, "Enum") + view.Font.Width;
174+
if (!IsWrapped)
175+
{
176+
x = AddText(view, x, y, view.Settings.NameColor, HotSpot.NameId, Name) + view.Font.Width;
177+
}
178+
x = AddText(view, x, y, view.Settings.ValueColor, HotSpot.NoneId, $"<{MetaData.Name}>") + view.Font.Width;
179+
x = AddIcon(view, x, y, Icons.Change, 4, HotSpotType.ChangeClassType) + view.Font.Width;
180+
181+
x = AddText(view, x, y, view.Settings.TextColor, HotSpot.NoneId, "=") + view.Font.Width;
182+
183+
var value = ReadValueFromMemory(view.Memory);
184+
185+
x = AddText(view, x, y, view.Settings.TextColor, HotSpot.NoneId, GetStringRepresentation(value)) + view.Font.Width;
186+
187+
x = AddComment(view, x, y);
188+
189+
DrawInvalidMemoryIndicator(view, y);
190+
AddTypeDrop(view, y);
191+
AddDelete(view, y);
192+
193+
return new Size(x - origX, view.Font.Height);
194+
}
195+
196+
public override int CalculateDrawnHeight(ViewInfo view)
197+
{
198+
return IsHidden && !IsWrapped ? HiddenHeight : view.Font.Height;
199+
}
200+
}
201+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
5+
namespace ReClassNET.Project
6+
{
7+
public class EnumMetaData
8+
{
9+
public static EnumMetaData Default => new EnumMetaData { Name = "DummyEnum" };
10+
11+
public string Name { get; set; }
12+
13+
public bool UseFlagsMode { get; private set; }
14+
15+
public int UnderlyingTypeSize { get; private set; } = sizeof(int);
16+
17+
public IReadOnlyList<long> Values { get; private set; }
18+
19+
public IReadOnlyList<string> Names { get; private set; }
20+
21+
public void SetData(bool useFlagsMode, int underlyingTypeSize, IDictionary<long, string> values)
22+
{
23+
if (!(underlyingTypeSize == 1 || underlyingTypeSize == 2 || underlyingTypeSize == 4 || underlyingTypeSize == 8))
24+
{
25+
throw new ArgumentOutOfRangeException(nameof(underlyingTypeSize));
26+
}
27+
28+
if (useFlagsMode)
29+
{
30+
var maxPossibleValue = ulong.MaxValue;
31+
switch (underlyingTypeSize)
32+
{
33+
case 1:
34+
maxPossibleValue = byte.MaxValue;
35+
break;
36+
case 2:
37+
maxPossibleValue = ushort.MaxValue;
38+
break;
39+
case 4:
40+
maxPossibleValue = uint.MaxValue;
41+
break;
42+
}
43+
44+
if (values.Keys.Select(v => (ulong)v).Max() > maxPossibleValue)
45+
{
46+
throw new ArgumentOutOfRangeException();
47+
}
48+
}
49+
else
50+
{
51+
var minPossibleValue = long.MinValue;
52+
var maxPossibleValue = long.MaxValue;
53+
switch (underlyingTypeSize)
54+
{
55+
case 1:
56+
minPossibleValue = sbyte.MinValue;
57+
maxPossibleValue = sbyte.MaxValue;
58+
break;
59+
case 2:
60+
minPossibleValue = short.MinValue;
61+
maxPossibleValue = short.MaxValue;
62+
break;
63+
case 4:
64+
minPossibleValue = int.MinValue;
65+
maxPossibleValue = int.MaxValue;
66+
break;
67+
}
68+
69+
if (values.Keys.Max() > maxPossibleValue || values.Keys.Min() < minPossibleValue)
70+
{
71+
throw new ArgumentOutOfRangeException();
72+
}
73+
}
74+
75+
UseFlagsMode = useFlagsMode;
76+
Values = values.Keys.ToList();
77+
Names = values.Values.ToList();
78+
}
79+
}
80+
}

ReClass.NET/Project/ReClassNetProject.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ public class ReClassNetProject : IDisposable
1313
public event ClassesChangedEvent ClassAdded;
1414
public event ClassesChangedEvent ClassRemoved;
1515

16+
private readonly List<EnumMetaData> enums = new List<EnumMetaData>();
1617
private readonly List<ClassNode> classes = new List<ClassNode>();
1718

19+
public IEnumerable<EnumMetaData> Enums => enums;
20+
1821
public IEnumerable<ClassNode> Classes => classes;
1922

2023
public string Path { get; set; }

ReClass.NET/ReClass.NET.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,10 +254,12 @@
254254
<Compile Include="Nodes\BaseWrapperNode.cs" />
255255
<Compile Include="Nodes\BoolNode.cs" />
256256
<Compile Include="Nodes\ClassUtil.cs" />
257+
<Compile Include="Nodes\EnumNode.cs" />
257258
<Compile Include="Nodes\FunctionNode.cs" />
258259
<Compile Include="Nodes\NodeUuid.cs" />
259260
<Compile Include="Nodes\PointerNode.cs" />
260261
<Compile Include="Project\CppTypeMapping.cs" />
262+
<Compile Include="Project\EnumMetaData.cs" />
261263
<Compile Include="Project\ReClassNetProject.cs" />
262264
<Compile Include="UI\BannerBox.cs">
263265
<SubType>Component</SubType>

ReClass.NET/UI/NodeTypesBuilder.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static NodeTypesBuilder()
2020
defaultNodeTypeGroupList.Add(new[] { typeof(Hex64Node), typeof(Hex32Node), typeof(Hex16Node), typeof(Hex8Node) });
2121
defaultNodeTypeGroupList.Add(new[] { typeof(Int64Node), typeof(Int32Node), typeof(Int16Node), typeof(Int8Node) });
2222
defaultNodeTypeGroupList.Add(new[] { typeof(UInt64Node), typeof(UInt32Node), typeof(UInt16Node), typeof(UInt8Node) });
23-
defaultNodeTypeGroupList.Add(new[] { typeof(BoolNode), typeof(BitFieldNode) });
23+
defaultNodeTypeGroupList.Add(new[] { typeof(BoolNode), typeof(BitFieldNode), typeof(EnumNode) });
2424
defaultNodeTypeGroupList.Add(new[] { typeof(FloatNode), typeof(DoubleNode) });
2525
defaultNodeTypeGroupList.Add(new[] { typeof(Vector4Node), typeof(Vector3Node), typeof(Vector2Node), typeof(Matrix4x4Node), typeof(Matrix3x4Node), typeof(Matrix3x3Node) });
2626
defaultNodeTypeGroupList.Add(new[] { typeof(Utf8TextNode), typeof(Utf8TextPtrNode), typeof(Utf16TextNode), typeof(Utf16TextPtrNode) });

0 commit comments

Comments
 (0)