ArticyXImporter
ArticyXImporter for Unreal Engine
Loading...
Searching...
No Matches
CodeFileGenerator.h
1//
2// Copyright (c) 2023 articy Software GmbH & Co. KG. All rights reserved.
3//
4
5#pragma once
6
7#include "CodeGenerator.h"
8
16{
17public:
18
27 template<typename Lambda>
28 void SafeExecute(Lambda Lamb);
29
40 template<typename Lambda>
41 CodeFileGenerator(const FString& Path, const bool bHeader, Lambda ContentGenerator);
42
51 void Line(const FString& Line = "", const bool bSemicolon = false, const bool bIndent = true, const int IndentOffset = 0);
52
58 void Comment(const FString& Text);
59
65 void AccessModifier(const FString& Text);
66
72 void UPropertyMacro(const FString& Specifiers);
73
79 void UFunctionMacro(const FString& Specifiers);
80
81 //========================================//
82
91 template<typename Lambda>
92 void Block(const bool bIndent, Lambda Content, const bool bSemicolonAtEnd = false);
93
104 template<typename Lambda>
105 void Class(const FString& Classname, const FString& Comment, const bool bUClass, Lambda Content, const FString& UClassSpecifiers = "BlueprintType");
106
117 template<typename Lambda>
118 void Struct(const FString& Structname, const FString& Comment, const bool bUStruct, Lambda Content, const FString& InlineDeclaration = "");
119
129 template<typename Lambda>
130 void UInterface(const FString& Classname, const FString& UInterfaceSpecifiers, const FString& Comment, Lambda Content);
131
141 template<typename Type>
142 void Enum(const FString& Enumname, const FString& Comment, const bool bUEnum, TArray<Type> Values);
143
144 //========================================//
145
156 void Variable(const FString& Type, const FString& Name, const FString& Value = "", const FString& Comment = "",
157 const bool bUProperty = false, const FString& UPropertySpecifiers = "VisibleAnywhere, BlueprintReadOnly");
158
172 template<typename Lambda>
173 void Method(const FString& ReturnType, const FString& Name, const FString& Parameters = "", Lambda Definition = nullptr, const FString& Comment = "",
174 const bool bUFunction = false, const FString& UFunctionSpecifiers = "", const FString& MethodSpecifiers = "");
175
176
177private:
178
179 const FString Path;
180 FString FileContent = "";
181
182 int IndentCount = 0;
183 uint8 BlockCount = 0;
184
188 void PushIndent() { ++IndentCount; }
189
193 void PopIndent() { IndentCount = FMath::Max(0, IndentCount - 1); }
194
200 void StartBlock(const bool bIndent = true);
201
208 void EndBlock(const bool bUnindent = true, const bool bSemicolon = false);
209
218 void StartClass(const FString& Classname, const FString& Comment, const bool bUClass, const FString& UClassSpecifiers = "BlueprintType");
219
223 void EndClass() { EndBlock(true, true); }
224
232 void StartStruct(const FString& Structname, const FString& Comment, const bool bUStruct);
233
239 void EndStruct(const FString& InlineDeclaration);
240
246 void AddEnumEntry(FString Name);
247
254 template <typename TNameValuePair>
255 void AddEnumEntry(TNameValuePair Pair);
256
262 static FString GetExportMacro();
263
267 void WriteToFile() const;
268
275 FString SplitName(const FString& Name);
276};
277
278//---------------------------------------------------------------------------//
279//---------------------------------------------------------------------------//
280
281template<typename Lambda>
283{
284 Lamb();
285}
286
287template<>
288inline void CodeFileGenerator::SafeExecute(nullptr_t Lamb)
289{
290}
291
302template <typename Lambda>
303CodeFileGenerator::CodeFileGenerator(const FString& Path, const bool bHeader, Lambda ContentGenerator) : Path(CodeGenerator::GetSourceFolder() / Path)
304{
305 Line("// articy Software GmbH & Co. KG");
306 Comment("This code file was generated by ArticyImporter. Changes to this file will get lost once the code is regenerated.");
307
308 if (bHeader)
309 {
310 Line();
311 Line("#pragma once");
312 }
313
314 Line();
315
316 if (ensure(!std::is_null_pointer<Lambda>::value))
317 ContentGenerator(this);
318
319 WriteToFile();
320}
321
330template <typename Lambda>
331void CodeFileGenerator::Block(const bool bIndent, Lambda Content, const bool bSemicolonAtEnd)
332{
333 StartBlock(bIndent);
334 {
335 // Add the content
336 SafeExecute(Content);
337 }
338 EndBlock(bIndent, bSemicolonAtEnd);
339}
340
351template <typename Lambda>
352void CodeFileGenerator::Class(const FString& Classname, const FString& Comment, const bool bUClass, Lambda Content, const FString& UClassSpecifiers)
353{
354 StartClass(Classname, Comment, bUClass, UClassSpecifiers);
355 {
356 // Add the content
357 SafeExecute(Content);
358 }
359 EndClass();
360}
361
372template <typename Lambda>
373void CodeFileGenerator::Struct(const FString& Structname, const FString& Comment, const bool bUStruct, Lambda Content, const FString& InlineDeclaration)
374{
375 StartStruct(Structname, Comment, bUStruct);
376 {
377 // Add the content
378 SafeExecute(Content);
379 }
380 EndStruct(InlineDeclaration);
381}
382
392template <typename Lambda>
393void CodeFileGenerator::UInterface(const FString& Classname, const FString& UInterfaceSpecifiers, const FString& Comment, Lambda Content)
394{
395 if (!Comment.IsEmpty())
396 this->Comment(Comment);
397 Line(FString::Printf(TEXT("UINTERFACE(%s)"), *UInterfaceSpecifiers));
398 Line(FString::Printf(TEXT("class U%s : public UInterface { GENERATED_BODY() };"), *Classname));
399 Class("I" + Classname, "", false, [&]
400 {
401 Line("GENERATED_BODY()");
402 Line();
403 SafeExecute(Content);
404 });
405}
406
407//---------------------------------------------------------------------------//
408
418template <typename Type>
419void CodeFileGenerator::Enum(const FString& Enumname, const FString& Comment, const bool bUEnum, TArray<Type> Values)
420{
421 if (bUEnum)
422 Line("UENUM(BlueprintType)");
423
424 Line("enum");
425 StartClass(Enumname + (bUEnum ? " : uint8" : ""), Comment, false);
426 {
427 // Add the values
428 for (auto val : Values)
429 AddEnumEntry(val);
430 }
431 EndClass();
432}
433
439inline void CodeFileGenerator::AddEnumEntry(FString Name)
440{
441 Line(FString::Printf(TEXT("%s,"), *Name));
442}
443
450template <typename TNameValuePair>
451void CodeFileGenerator::AddEnumEntry(TNameValuePair Pair)
452{
453 Line(FString::Printf(TEXT("%s = %d,"), *Pair.Name, Pair.Value));
454}
455
456//---------------------------------------------------------------------------//
457
471template<typename Lambda>
472void CodeFileGenerator::Method(const FString& ReturnType, const FString& Name, const FString& Parameters, Lambda Definition, const FString& Comment, const bool bUFunction, const FString& UFunctionSpecifiers, const FString& MethodSpecifiers)
473{
474 if (!ensure(!Name.IsEmpty()))
475 return;
476
477 if (!Comment.IsEmpty())
478 this->Comment(Comment);
479
480 if (bUFunction)
481 this->UFunctionMacro(UFunctionSpecifiers);
482
483 // Check if nullptr was passed as Definition
484 constexpr auto hasDefinition = !std::is_null_pointer<Lambda>::value;
485
486 // ReturnType Name(Parameters..)
487 // Only add the semicolon if there is no definition
488 Line(FString::Printf(TEXT("%s %s(%s) %s"), *ReturnType, *Name, *Parameters, *MethodSpecifiers), !hasDefinition);
489
490 // Add definition, if any
491 if (hasDefinition)
492 Block(true, Definition, false);
493}
void Class(const FString &Classname, const FString &Comment, const bool bUClass, Lambda Content, const FString &UClassSpecifiers="BlueprintType")
Adds a class definition with optional UCLASS macro.
Definition CodeFileGenerator.h:352
void Variable(const FString &Type, const FString &Name, const FString &Value="", const FString &Comment="", const bool bUProperty=false, const FString &UPropertySpecifiers="VisibleAnywhere, BlueprintReadOnly")
Adds a variable definition, optionally as UPROPERTY.
Definition CodeFileGenerator.cpp:46
void Method(const FString &ReturnType, const FString &Name, const FString &Parameters="", Lambda Definition=nullptr, const FString &Comment="", const bool bUFunction=false, const FString &UFunctionSpecifiers="", const FString &MethodSpecifiers="")
Adds a method definition, optionally as UFUNCTION.
Definition CodeFileGenerator.h:472
void SafeExecute(Lambda Lamb)
Executes a lambda function safely.
Definition CodeFileGenerator.h:282
void UPropertyMacro(const FString &Specifiers)
Adds a UPROPERTY macro to the file content.
Definition CodeFileGenerator.cpp:36
CodeFileGenerator(const FString &Path, const bool bHeader, Lambda ContentGenerator)
Creates a new code file generator with default lines and executes a content generator.
Definition CodeFileGenerator.h:303
void Line(const FString &Line="", const bool bSemicolon=false, const bool bIndent=true, const int IndentOffset=0)
Adds a line to the file content.
Definition CodeFileGenerator.cpp:14
void Comment(const FString &Text)
Adds a comment to the file content.
Definition CodeFileGenerator.cpp:26
void Struct(const FString &Structname, const FString &Comment, const bool bUStruct, Lambda Content, const FString &InlineDeclaration="")
Adds a struct definition with optional USTRUCT macro.
Definition CodeFileGenerator.h:373
void Enum(const FString &Enumname, const FString &Comment, const bool bUEnum, TArray< Type > Values)
Adds an enum definition with optional UENUM macro.
Definition CodeFileGenerator.h:419
void UInterface(const FString &Classname, const FString &UInterfaceSpecifiers, const FString &Comment, Lambda Content)
Adds a UINTERFACE definition with corresponding interface class.
Definition CodeFileGenerator.h:393
void AccessModifier(const FString &Text)
Adds an access modifier with optional colon.
Definition CodeFileGenerator.cpp:31
void UFunctionMacro(const FString &Specifiers)
Adds a UFUNCTION macro to the file content.
Definition CodeFileGenerator.cpp:41
void Block(const bool bIndent, Lambda Content, const bool bSemicolonAtEnd=false)
Adds a block of code with optional indentation and semicolon.
Definition CodeFileGenerator.h:331
Manages the generation, compilation, and asset creation for Articy-imported data.
Definition CodeGenerator.h:19