Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ All package updates & migration steps will be listed in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [4.6.1] - 2025-12-24
### Changed
- MenuItem code is code generated in one file to reduce git diffs when an info is added/removed.

## [4.6.0] - 2025-07-24
### Added
- Support to add pre-build events to the `ParameterBuildProcessor`
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
using System.Linq;
using PocketGems.Parameters.CodeGeneration.Operation.Editor;
using PocketGems.Parameters.CodeGeneration.Util.Editor;
using PocketGems.Parameters.Common.Operations.Editor;
Expand All @@ -23,18 +22,18 @@ public override void Execute(ICodeOperationContext context)
var fbFileRemover = new UnusedFileRemover(flatBufferClassesDir);

// generate files
var orderedInfos = context.ParameterInfos.OrderBy(t => t.BaseName);
int index = 0;
foreach (var parameterInfo in orderedInfos)
foreach (var parameterInfo in context.ParameterInfos)
{
var soFilename = CodeGenerator.GenerateScriptableObjectFile(parameterInfo, index, scriptableObjectDir);
var soFilename = CodeGenerator.GenerateScriptableObjectFile(parameterInfo, scriptableObjectDir);
soFileRemover.UsedFile(soFilename);

var fbClassFile = CodeGenerator.GenerateFlatBufferClassFile(parameterInfo, true, flatBufferClassesDir);
fbFileRemover.UsedFile(fbClassFile);
index++;
}

var menuItemFilename = CodeGenerator.GenerateScriptableObjectMenuItems(context.ParameterInfos, scriptableObjectDir);
soFileRemover.UsedFile(menuItemFilename);

var parameterStructs = context.ParameterStructs;
for (int i = 0; i < parameterStructs.Count; i++)
{
Expand Down
48 changes: 43 additions & 5 deletions Editor/CodeGeneration/Util/CodeGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,53 @@ private static bool AttemptGenerateValidationFile(IParameterInterface parameterI
return true;
}

/// <summary>
/// Generate the Scriptable Object class file that implements the interface.
/// </summary>
/// <param name="parameterInfos">All of the parameter infos.</param>
/// <param name="outputDirectory">Directory to write the class to.</param>
/// <returns>filepath of the file written</returns>
public static string GenerateScriptableObjectMenuItems(IReadOnlyList<IParameterInfo> parameterInfos, string outputDirectory)
{
if (!Directory.Exists(outputDirectory))
Directory.CreateDirectory(outputDirectory);

var orderedInfos = parameterInfos.OrderBy(t => t.BaseName);

var infoInterfaces = new List<object>();
int orderIndex = 0;
foreach (var parameterInfo in orderedInfos)
{
var infoArgs = new Dictionary<string, object>
{
{ "baseName", parameterInfo.BaseName },
{ "className", parameterInfo.ScriptableObjectClassName(false) },
{ "order", orderIndex }
};
infoInterfaces.Add(infoArgs);
orderIndex++;
}

var args = new Dictionary<string, object>
{
{ "namespace", ParameterConstants.GeneratedNamespace },
{ "infoInterfaces", infoInterfaces }
};

var fileName = EditorParameterConstants.ScriptableObjectClass.MenuItemsFileName;
var filePath = Path.Combine(outputDirectory, fileName);
var templateFileName = EditorParameterConstants.ScriptableObjectClass.MenuItemsTemplateFileName;
ScribanHelper.GenerateClass(templateFileName, filePath, args);
return fileName;
}

/// <summary>
/// Generate the Scriptable Object class file that implements the interface.
/// </summary>
/// <param name="parameterInfo">Interface to write the class for.</param>
/// <param name="order">The menu order.</param>
/// <param name="outputDirectory">Directory to write the class to.</param>
/// <returns>filepath of the file written</returns>
public static string GenerateScriptableObjectFile(IParameterInfo parameterInfo, int order, string outputDirectory)
public static string GenerateScriptableObjectFile(IParameterInfo parameterInfo, string outputDirectory)
{
if (!Directory.Exists(outputDirectory))
Directory.CreateDirectory(outputDirectory);
Expand All @@ -152,12 +191,11 @@ public static string GenerateScriptableObjectFile(IParameterInfo parameterInfo,
{ "baseName", parameterInfo.BaseName },
{ "className", parameterInfo.ScriptableObjectClassName(false) },
{ "interfaceName", parameterInfo.InterfaceName },
{ "properties", properties },
{ "order", order },
{ "properties", properties }
};
var fileName = parameterInfo.ScriptableObjectClassName(true);
var filePath = Path.Combine(outputDirectory, fileName);
var templateFileName = EditorParameterConstants.ScriptableObjectClass.TemplateFileName;
var templateFileName = EditorParameterConstants.ScriptableObjectClass.ClassTemplateFileName;
ScribanHelper.GenerateClass(templateFileName, filePath, args);
return fileName;
}
Expand Down
6 changes: 4 additions & 2 deletions Editor/Common/EditorParameterConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal static class EditorParameterConstants
/// Ideally it would be the most convenient to use the package version but that requires file I/O to
/// the package.json which can be costly if we're doing it all of the time.
/// </summary>
public const string InterfaceHashSalt = "27d36d97-4bdd-48f5-9d75-a4490bf5aecf";
public const string InterfaceHashSalt = "a7de937b-8b17-4584-8095-f3774383dbe9";

public static string SanitizedDataPath()
{
Expand Down Expand Up @@ -218,7 +218,9 @@ public static class ValidatorClass

public static class ScriptableObjectClass
{
public const string TemplateFileName = "ScriptableObject.template";
public const string MenuItemsFileName = "ScriptableObjectMenuItems.cs";
public const string MenuItemsTemplateFileName = "ScriptableObjectMenuItems.template";
public const string ClassTemplateFileName = "ScriptableObject.template";
}

public static class Struct
Expand Down
3 changes: 1 addition & 2 deletions Editor/Common/Templates/ScriptableObject.template
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ using UnityEngine.AddressableAssets;

namespace {{namespace}}
{
[CreateAssetMenu(fileName = "{{baseName}}", menuName = "Parameters/{{baseName}}", order = {{order}})]
internal class {{className}} : ParameterScriptableObject
internal partial class {{className}} : ParameterScriptableObject
#if !{{disableSymbol}}
, {{interfaceName}}
#endif
Expand Down
13 changes: 13 additions & 0 deletions Editor/Common/Templates/ScriptableObjectMenuItems.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// AUTOGENERATED FILE
// DO NOT MODIFY DIRECTLY

using UnityEngine;

namespace {{namespace}}
{
// The menu items are kept in one file to reduce the amount of file diffs when infos are added/removed.
{{~for interface in infoInterfaces~}}
[CreateAssetMenu(fileName = "{{interface.baseName}}", menuName = "Parameters/{{interface.baseName}}", order = {{interface.order}})]
internal partial class {{interface.className}} { }
{{~end~}}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ public void Execute()

void AssertFileCounts(int scriptableObjects, int structs, int flatbuffers)
{
Assert.AreEqual(scriptableObjects, FileCount(TestScriptableObjectsDir));
// +1 for the menu item file generated
Assert.AreEqual(scriptableObjects + 1, FileCount(TestScriptableObjectsDir));
Assert.AreEqual(structs, FileCount(TestStructsDir));
Assert.AreEqual(flatbuffers, FileCount(TestFlatBufferClassesDir));
}
Expand Down Expand Up @@ -87,7 +88,8 @@ public void ExecuteNoInputs()
var operation = new GenerateImplementationFilesOperation();
AssertExecute(operation, OperationState.Finished);

Assert.AreEqual(0, FileCount(TestScriptableObjectsDir));
// only 1 file for the menu item file
Assert.AreEqual(1, FileCount(TestScriptableObjectsDir));
Assert.AreEqual(0, FileCount(TestStructsDir));
Assert.AreEqual(0, FileCount(TestFlatBufferClassesDir));
}
Expand Down
11 changes: 10 additions & 1 deletion Tests/Editor/CodeGeneration/Util/CodeGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,19 @@ public void AttemptGenerateValidationFile()
AssertFileCount(5);
}

[Test]
public void GenerateMenuItemScriptableObjectFile()
{
CodeGenerator.GenerateScriptableObjectMenuItems(new List<IParameterInfo> { _mockParameterInfo1, _mockParameterInfo2 }, TestDirectoryName);

AssertFileCount(1);
AssertFileExists(EditorParameterConstants.ScriptableObjectClass.MenuItemsFileName);
}

[Test]
public void GenerateScriptableObjectFile()
{
CodeGenerator.GenerateScriptableObjectFile(_mockParameterInfo1, 0, TestDirectoryName);
CodeGenerator.GenerateScriptableObjectFile(_mockParameterInfo1, TestDirectoryName);

AssertFileCount(1);
AssertFileExists(_mockParameterInfo1.ScriptableObjectClassName(true));
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "com.pocketgems.scriptableobject.flatbuffer",
"version": "4.6.0",
"version": "4.6.1",
"displayName": "Scriptable Object - FlatBuffer",
"description": "Seamless syncing between Scriptable Objects and CSVs. Scriptable Object data built to Google FlatBuffers for optimal runtime loading & access.",
"unity": "2021.3",
Expand Down
Loading