22 protected ModuleModel? Model;
23 public string TemplateSubfolder =>
"Module";
25 public bool AddToTarget {
get;
private set; }
29 AddToTarget = addToTarget;
33 public void Generate(AbsolutePath templatesPath, AbsolutePath currentFolder,
string name)
43 if(Directory.Exists(currentFolder / name))
45 throw new InvalidOperationException($
"The module folder of {name} already exists in the current folder.");
48 if(!Directory.Exists(templatesPath / TemplateSubfolder))
49 templatesPath = DefaultTemplateFolder;
51 var templateDir = templatesPath / TemplateSubfolder;
55 if(Model.Plugin.IsValid)
61 protected void AddModuleToProjectUnit(AbsolutePath projectFile,
string name)
63 var unitJson = JObject.Parse(File.ReadAllText(projectFile));
65 if(!unitJson.ContainsKey(
"Modules"))
67 unitJson.Add(
"Modules",
new JArray());
69 if (unitJson[
"Modules"] is JArray modulesArray)
71 if(!modulesArray.Any(t => t[
"Name"]?.ToString().Equals(name, StringComparison.InvariantCultureIgnoreCase) ??
false))
73 modulesArray.Add(JObject.FromObject(
new {
77 LoadingPhase =
"Default"
80 else throw new InvalidOperationException($
"A module named {name} already exist.");
86 protected void AddModuleToPlugin()
88 var pluginFile = Model!.Plugin.Folder / $
"{Model.Plugin.Name}.uplugin";
91 AddModuleToProjectUnit(pluginFile, Model.Name);
95 Log.Warning($
"Couldn't add module {Model.Name} to {Model.Plugin.Name}.uproject, it has to be added manually.");
96 Log.Warning(e,
"Exception:");
100 protected void AddModuleToProject()
102 var projectFile = Model!.Project.Folder / $
"{Model.Project.Name}.uproject";
105 AddModuleToProjectUnit(projectFile, Model.Name);
109 Log.Warning($
"Couldn't add module {Model.Name} to {Model.Project.Name}.uproject, it has to be added manually.");
110 Log.Warning(e,
"Exception:");
114 var targetFile = Model.Project.Folder /
"Source" / $
"{Model.Project.Name}.Target.cs";
115 var editorTargetFile = Model.Project.Folder /
"Source" / $
"{Model.Project.Name}Editor.Target.cs";
118 AddModuleToTarget(targetFile);
119 AddModuleToTarget(editorTargetFile);
123 Log.Warning($
"Couldn't add module {Model.Name} to {Model.Project.Name}'s target rules, it has to be added manually.");
124 Log.Warning(e,
"Exception:");
129 protected void AddModuleToTarget(AbsolutePath targetFile)
131 var targetText = File.ReadAllText(targetFile);
132 var targetSt = CSharpSyntaxTree.ParseText(targetText);
134 var targetClass = targetSt.GetCompilationUnitRoot()
135 .DescendantNodes().OfType<ClassDeclarationSyntax>()
137 c.Identifier.ValueText.EndsWith(
"Target",
true,
null)
138 && c.Identifier.ValueText.Contains(Model!.Project.Name!, StringComparison.InvariantCultureIgnoreCase)
141 if(targetClass ==
null)
143 throw new InvalidDataException($
"Could not find the target rule class in {targetFile}");
146 var constructor = targetClass
147 .DescendantNodes().OfType<ConstructorDeclarationSyntax>()
150 if(constructor ==
null)
152 throw new InvalidDataException($
"Could not find the constructor of the target rule class in {targetFile}");
155 var extraModuleAdd = CSharpSyntaxTree.ParseText($
"ExtraModuleNames.Add(\"{Model!.Name}\");")
156 .GetCompilationUnitRoot()
157 .DescendantNodes().OfType<ExpressionStatementSyntax>()
160 if (extraModuleAdd !=
null)
162 var newBody = constructor.Body?.AddStatements(extraModuleAdd);
163 var newCtr = constructor.WithBody(newBody);
165 var root = targetSt.GetRoot().ReplaceNode(constructor, newCtr);
167 File.WriteAllText(targetFile, root.GetText().ToString());
172 protected void CheckInsideSourceFolder(AbsolutePath currentFolder)
174 if(!currentFolder.ToString().Contains(
"Source", StringComparison.InvariantCultureIgnoreCase))
176 throw new InvalidOperationException(
177 $
"{currentFolder} doesn't contain a Source folder. Unreal Engine requires Module to be inside the project or plugin Source folder."