Skip to content

Commit bdcc908

Browse files
committed
Added support for wrapper nodes.
1 parent 726d3a0 commit bdcc908

1 file changed

Lines changed: 67 additions & 52 deletions

File tree

ReClass.NET/CodeGenerator/CppCodeGenerator.cs

Lines changed: 67 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Collections.Generic;
33
using System.Diagnostics.Contracts;
44
using System.Linq;
@@ -9,7 +9,7 @@
99

1010
namespace ReClassNET.CodeGenerator
1111
{
12-
class CppCodeGenerator : ICodeGenerator
12+
public class CppCodeGenerator : ICodeGenerator
1313
{
1414
private readonly Dictionary<Type, string> typeToTypedefMap = new Dictionary<Type, string>
1515
{
@@ -77,7 +77,7 @@ public string GenerateCode(IEnumerable<ClassNode> classes, ILogger logger)
7777
csb.AppendLine(
7878
string.Join(
7979
Environment.NewLine,
80-
YieldMemberDefinitions(c.Nodes.Skip(skipFirstMember ? 1 : 0).WhereNot(n => n is FunctionNode), logger)
80+
GetMemberDefinitionsForNodes(c.Nodes.Skip(skipFirstMember ? 1 : 0).WhereNot(n => n is FunctionNode), logger)
8181
.Select(MemberDefinitionToString)
8282
.Select(s => "\t" + s)
8383
)
@@ -151,7 +151,7 @@ private static IEnumerable<ClassNode> YieldReversedHierarchy(ClassNode node, ISe
151151
.Append(node);
152152
}
153153

154-
private IEnumerable<MemberDefinition> YieldMemberDefinitions(IEnumerable<BaseNode> members, ILogger logger)
154+
private IEnumerable<MemberDefinition> GetMemberDefinitionsForNodes(IEnumerable<BaseNode> members, ILogger logger)
155155
{
156156
Contract.Requires(members != null);
157157
Contract.Requires(Contract.ForAll(members, m => m != null));
@@ -181,66 +181,81 @@ private IEnumerable<MemberDefinition> YieldMemberDefinitions(IEnumerable<BaseNod
181181
fill = 0;
182182
}
183183

184-
if (typeToTypedefMap.TryGetValue(member.GetType(), out var type))
184+
var definition = GetMemberDefinitionForNode(member, logger);
185+
if (definition != null)
185186
{
186-
var count = (member as BaseTextNode)?.Length ?? 0;
187-
188-
yield return new MemberDefinition(member, type, count);
189-
}
190-
else if (member is BitFieldNode bitFieldNode)
191-
{
192-
switch (bitFieldNode.Bits)
193-
{
194-
case 8:
195-
type = Program.Settings.TypeUInt8;
196-
break;
197-
case 16:
198-
type = Program.Settings.TypeUInt16;
199-
break;
200-
case 32:
201-
type = Program.Settings.TypeUInt32;
202-
break;
203-
case 64:
204-
type = Program.Settings.TypeUInt64;
205-
break;
206-
}
207-
208-
yield return new MemberDefinition(bitFieldNode, type);
187+
yield return definition;
209188
}
210-
else if (member is ClassInstanceArrayNode classInstanceArrayNode)
211-
{
212-
yield return new MemberDefinition(classInstanceArrayNode, classInstanceArrayNode.InnerNode.Name, classInstanceArrayNode.Count);
213-
}
214-
else if (member is ClassInstanceNode classInstanceNode)
189+
else
215190
{
216-
yield return new MemberDefinition(classInstanceNode, classInstanceNode.InnerNode.Name);
191+
logger.Log(LogLevel.Error, $"Skipping node with unhandled type: {member.GetType()}");
217192
}
218-
else if (member is ClassPtrArrayNode ptrArrayNode)
193+
}
194+
195+
if (fill != 0)
196+
{
197+
yield return new MemberDefinition(Program.Settings.TypePadding, fill, $"pad_{fillStart:X04}", fillStart, string.Empty);
198+
}
199+
}
200+
201+
private MemberDefinition GetMemberDefinitionForNode(BaseNode member, ILogger logger)
202+
{
203+
var generator = CustomCodeGenerator.GetGenerator(member, Language);
204+
if (generator != null)
205+
{
206+
return generator.GetMemberDefinition(member, Language, logger);
207+
}
208+
209+
if (typeToTypedefMap.TryGetValue(member.GetType(), out var type))
210+
{
211+
var count = (member as BaseTextNode)?.Length ?? 0;
212+
213+
return new MemberDefinition(member, type, count);
214+
}
215+
if (member is BitFieldNode bitFieldNode)
216+
{
217+
switch (bitFieldNode.Bits)
219218
{
220-
yield return new MemberDefinition(ptrArrayNode, $"class {ptrArrayNode.InnerNode.Name}*", ptrArrayNode.Count);
219+
case 8:
220+
type = Program.Settings.TypeUInt8;
221+
break;
222+
case 16:
223+
type = Program.Settings.TypeUInt16;
224+
break;
225+
case 32:
226+
type = Program.Settings.TypeUInt32;
227+
break;
228+
case 64:
229+
type = Program.Settings.TypeUInt64;
230+
break;
221231
}
222-
else if (member is ClassPtrNode classPtrNode)
232+
233+
return new MemberDefinition(bitFieldNode, type);
234+
}
235+
236+
if (member is ClassInstanceNode classInstanceNode)
237+
{
238+
return new MemberDefinition(classInstanceNode, classInstanceNode.InnerNode.Name);
239+
}
240+
241+
if (member is BaseWrapperNode wrapperNode)
242+
{
243+
// TODO Support WrapperNode chains
244+
if (member is PointerNode)
223245
{
224-
yield return new MemberDefinition(classPtrNode, $"class {classPtrNode.InnerNode.Name}*");
246+
var innerNode = wrapperNode.ResolveMostInnerNode();
247+
248+
return new MemberDefinition(member, innerNode == null ? "void*" : GetMemberDefinitionForNode(innerNode, logger).Type + "*");
225249
}
226-
else
250+
if (member is ArrayNode arrayNode)
227251
{
228-
var generator = CustomCodeGenerator.GetGenerator(member, Language);
229-
if (generator != null)
230-
{
231-
yield return generator.GetMemberDefinition(member, Language, logger);
232-
}
233-
else
234-
{
235-
logger.Log(LogLevel.Error, $"Skipping node with unhandled type: {member.GetType()}");
236-
}
252+
var innerNode = wrapperNode.ResolveMostInnerNode();
253+
254+
return new MemberDefinition(member, GetMemberDefinitionForNode(innerNode, logger).Type, arrayNode.Count);
237255
}
238256
}
239257

240-
if (fill != 0)
241-
{
242-
yield return new MemberDefinition(Program.Settings.TypePadding, fill, $"pad_{fillStart:X04}", fillStart, string.Empty);
243-
}
258+
return null;
244259
}
245260

246261
private static string MemberDefinitionToString(MemberDefinition member)

0 commit comments

Comments
 (0)