Skip to content

Commit ffa61e3

Browse files
committed
Rough sketch for chained wrapped node code generation.
1 parent d13169e commit ffa61e3

1 file changed

Lines changed: 170 additions & 2 deletions

File tree

ReClass.NET/CodeGenerator/CppCodeGenerator.cs

Lines changed: 170 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public string GenerateCode(IEnumerable<ClassNode> classes, ILogger logger)
4646
var classNodes = classes as IList<ClassNode> ?? classes.ToList();
4747

4848
var sb = new StringBuilder();
49-
sb.AppendLine($"// Created with {Constants.ApplicationName} by {Constants.Author}");
49+
sb.AppendLine($"// Created with {Constants.ApplicationName} {Constants.ApplicationVersion} by {Constants.Author}");
5050
sb.AppendLine();
5151
sb.AppendLine(
5252
string.Join(
@@ -74,13 +74,20 @@ public string GenerateCode(IEnumerable<ClassNode> classes, ILogger logger)
7474

7575
csb.AppendLine("{");
7676
csb.AppendLine("public:");
77-
csb.AppendLine(
77+
/*csb.AppendLine(
7878
string.Join(
7979
Environment.NewLine,
8080
GetMemberDefinitionsForNodes(c.Nodes.Skip(skipFirstMember ? 1 : 0).WhereNot(n => n is FunctionNode), logger)
8181
.Select(MemberDefinitionToString)
8282
.Select(s => "\t" + s)
8383
)
84+
);*/
85+
csb.AppendLine(
86+
string.Join(
87+
Environment.NewLine,
88+
GetMemberDeclsForNodes(c.Nodes.Skip(skipFirstMember ? 1 : 0).WhereNot(n => n is FunctionNode), logger)
89+
.Select(s => "\t" + s)
90+
)
8491
);
8592

8693
var vTableNodes = c.Nodes.OfType<VirtualMethodTableNode>().ToList();
@@ -198,6 +205,58 @@ private IEnumerable<MemberDefinition> GetMemberDefinitionsForNodes(IEnumerable<B
198205
}
199206
}
200207

208+
private IEnumerable<string> GetMemberDeclsForNodes(IEnumerable<BaseNode> members, ILogger logger)
209+
{
210+
Contract.Requires(members != null);
211+
Contract.Requires(Contract.ForAll(members, m => m != null));
212+
Contract.Ensures(Contract.Result<IEnumerable<string>>() != null);
213+
Contract.Ensures(Contract.ForAll(Contract.Result<IEnumerable<string>>(), d => d != null));
214+
215+
int fill = 0;
216+
int fillStart = 0;
217+
218+
string CreatePaddingDecl(int offset, int count)
219+
{
220+
return $"{Program.Settings.TypePadding} pad_{offset:X04}[{count}]; //0x{offset:X04}";
221+
}
222+
223+
foreach (var member in members.WhereNot(m => m is VirtualMethodTableNode))
224+
{
225+
if (member is BaseHexNode)
226+
{
227+
if (fill == 0)
228+
{
229+
fillStart = member.Offset.ToInt32();
230+
}
231+
fill += member.MemorySize;
232+
233+
continue;
234+
}
235+
236+
if (fill != 0)
237+
{
238+
yield return CreatePaddingDecl(fillStart, fill);
239+
240+
fill = 0;
241+
}
242+
243+
var definition = GetMemberDeclForNode(member, logger);
244+
if (definition != null)
245+
{
246+
yield return definition;
247+
}
248+
else
249+
{
250+
logger.Log(LogLevel.Error, $"Skipping node with unhandled type: {member.GetType()}");
251+
}
252+
}
253+
254+
if (fill != 0)
255+
{
256+
yield return CreatePaddingDecl(fillStart, fill);
257+
}
258+
}
259+
201260
private MemberDefinition GetMemberDefinitionForNode(BaseNode member, ILogger logger)
202261
{
203262
var generator = CustomCodeGenerator.GetGenerator(member, Language);
@@ -254,6 +313,115 @@ private MemberDefinition GetMemberDefinitionForNode(BaseNode member, ILogger log
254313
return null;
255314
}
256315

316+
private string GetSimpleType(BaseNode member, ILogger logger)
317+
{
318+
if (typeToTypedefMap.TryGetValue(member.GetType(), out var type))
319+
{
320+
return type;
321+
}
322+
if (member is BitFieldNode bitFieldNode)
323+
{
324+
return GetSimpleType(bitFieldNode.GetUnderlayingNode(), logger);
325+
}
326+
327+
if (member is ClassInstanceNode classInstanceNode)
328+
{
329+
return $"class {classInstanceNode.InnerNode.Name}";
330+
}
331+
332+
return null;
333+
}
334+
335+
private string GetMemberDeclForNode(BaseNode member, ILogger logger)
336+
{
337+
var generator = CustomCodeGenerator.GetGenerator(member, Language);
338+
if (generator != null)
339+
{
340+
throw new NotImplementedException();
341+
//return generator.GetMemberDefinition(member, Language, logger);
342+
}
343+
344+
var simpleType = GetSimpleType(member, logger);
345+
if (simpleType != null)
346+
{
347+
return NodeToString(member, simpleType);
348+
}
349+
350+
if (member is BaseWrapperNode wrapperNode)
351+
{
352+
var sb = new StringBuilder();
353+
354+
sb.Append(GetDeclForWrappedNode(wrapperNode, false, logger));
355+
356+
sb.Append($"; //0x{member.Offset.ToInt32():X04} {member.Comment}".Trim());
357+
358+
return sb.ToString();
359+
}
360+
361+
return null;
362+
}
363+
364+
private string GetDeclForWrappedNode(BaseNode node, bool isAnonymousExpression, ILogger logger)
365+
{
366+
Contract.Requires(node != null);
367+
368+
var sb = new StringBuilder();
369+
if (!isAnonymousExpression)
370+
{
371+
sb.Append(node.Name);
372+
}
373+
374+
var lastWrapperNode = node;
375+
var currentNode = node;
376+
377+
while (true)
378+
{
379+
if (currentNode is PointerNode pointerNode)
380+
{
381+
sb.Insert(0, '*');
382+
383+
if (pointerNode.InnerNode == null) // void*
384+
{
385+
sb.Insert(0, "void ");
386+
break;
387+
}
388+
389+
lastWrapperNode = pointerNode;
390+
currentNode = pointerNode.InnerNode;
391+
}
392+
else if (currentNode is ArrayNode arrayNode)
393+
{
394+
if (lastWrapperNode is PointerNode)
395+
{
396+
sb.Insert(0, '(');
397+
sb.Append(')');
398+
}
399+
400+
sb.Append($"[{arrayNode.Count}]");
401+
402+
lastWrapperNode = arrayNode;
403+
currentNode = arrayNode.InnerNode;
404+
}
405+
else
406+
{
407+
var simpleType = GetSimpleType(currentNode, logger);
408+
409+
sb.Insert(0, $"{simpleType} ");
410+
break;
411+
}
412+
}
413+
414+
return sb.ToString();
415+
}
416+
417+
private static string NodeToString(BaseNode node, string type)
418+
{
419+
Contract.Requires(node != null);
420+
Contract.Requires(type != null);
421+
422+
return $"{type} {node.Name}; //0x{node.Offset.ToInt32():X04} {node.Comment}".Trim();
423+
}
424+
257425
private static string MemberDefinitionToString(MemberDefinition member)
258426
{
259427
Contract.Requires(member != null);

0 commit comments

Comments
 (0)