Skip to content

Implement menu source generation#76

Merged
flibber-hk merged 7 commits into
mainfrom
gen
May 4, 2026
Merged

Implement menu source generation#76
flibber-hk merged 7 commits into
mainfrom
gen

Conversation

@dplochcoder
Copy link
Copy Markdown
Collaborator

Summary of Changes

This enables quick and easy generation of menus for classes intended to be serialized with Json, as opposed to data specified through BepInEx configuration files. It does not yet have feature parity with MenuElementFactory but it is close and I think the generated API is much nicer to use than runtime reflection. Attributes exist to plug in custom elements, sub menus, and to clamp numeric values to bounded ranges.

I don't know if the packaging set up will work with nuget; I copied stuff from https://github.com/BadMagic100/DataDrivenConstants/blob/main/DataDrivenConstants.Package/DataDrivenConstants.Package.csproj. I've also never written a Roslyn analyzer before so I probably have some stuff wrong, but it at least all works in the test project and the diagnostics seem to be working too.

Checklist

  • No change is too small for a release, so pick one:
    • I have updated the package version following semantic versioning
    • There is another change actively WIP that will update the version (link issue or PR here)
    • This PR does not update user-facing code/config
    • I'm not sure how to set the version and would like the reviewer's help

@dplochcoder dplochcoder requested a review from BadMagic100 April 28, 2026 05:08
Comment thread Silksong.ModMenuTesting/Tests/GeneratorTest.cs
@flibber-hk
Copy link
Copy Markdown
Member

Suppose I have a menu generated with this procedure, and I want to modify the values of the underlying data object in code. What is the recommended way to do this? In HK.MC I believe the answer was to modify the menu elements directly - is the expectation here that they have to hold a reference to the generated menu and check if it exists before deciding whether to modify the data on the generated menu or on the data directly?

it may or may not be the case that the answer to this question is simply an article

@BadMagic100 BadMagic100 self-assigned this Apr 28, 2026
@dplochcoder
Copy link
Copy Markdown
Collaborator Author

Suppose I have a menu generated with this procedure, and I want to modify the values of the underlying data object in code. What is the recommended way to do this? In HK.MC I believe the answer was to modify the menu elements directly - is the expectation here that they have to hold a reference to the generated menu and check if it exists before deciding whether to modify the data on the generated menu or on the data directly?

it may or may not be the case that the answer to this question is simply an article

I wrote an article. The answer depends on what sort of syncing behaviour your actually want between the menu and the underlying data; if the answer is "always in-sync" then you want to respond to every value change with menu.ExportTo(underlyingDataSource) and you want to follow-up every data change with menu?.ApplyFrom(underlyingDataSource). You shouldn't ever need to modify the menu element's values directly.

@dplochcoder dplochcoder force-pushed the gen branch 2 times, most recently from 07d94a1 to cc44d03 Compare April 28, 2026 18:49
Comment thread docs/articles/generation.md Outdated
Copy link
Copy Markdown
Member

@BadMagic100 BadMagic100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would really strongly recommend creating a roslyn test project to verify the generated sources as well.

For locally testing the nuget packaging, you can set the package version as a prerelease and build, then set up a local package source with dotnet nuget add source and then take the prerelease version as a dependency. If you don't need the extra assurance you can also just change the extension of the package to .zip and inspect the content (nuget has an online package browser you can use to compare against other packages)

Comment thread docs/articles/generation.md
Comment thread docs/articles/generation.md
Comment thread Silksong.ModMenu/Generator/Attributes.cs
Comment thread Silksong.ModMenu/Silksong.ModMenu.csproj Outdated
Comment thread Silksong.ModMenuAnalyzers/MenuProperty.cs
/// <inheritdoc/>
public void Initialize(IncrementalGeneratorInitializationContext context)
{
var classDeclarations = context
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using ForAttributeWithMetadataName is generally significantly more performant and makes for cleaner code than scanning every class declaration yourself

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps I should have been clearer, this will also give you access to the compilation and the symbol

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this then?

Comment thread Silksong.ModMenuAnalyzers/ModMenuGenerator.cs Outdated
Comment thread Silksong.ModMenuAnalyzers/ModMenuGenerator.cs Outdated
Comment thread Silksong.ModMenuAnalyzers/Silksong.ModMenuAnalyzers.csproj Outdated
@dplochcoder dplochcoder force-pushed the gen branch 2 times, most recently from 87e1ecb to 5130d4b Compare May 3, 2026 04:13
Comment thread Silksong.ModMenu/Models/TextModels.cs Outdated
Comment thread Silksong.ModMenu/Models/TextModels.cs
Copy link
Copy Markdown
Member

@BadMagic100 BadMagic100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Few more comments, but on the whole I think this is nearly good, the roslyn tests give me more confidence that the implementation is sensible and correct

Comment thread Silksong.ModMenuAnalyzers/ModMenuGenerator.cs
Comment thread Silksong.ModMenuAnalyzerTest/GeneratorTest.cs Outdated
Comment thread Silksong.ModMenuAnalyzerTest/GeneratorTest.cs Outdated
Copy link
Copy Markdown
Member

@BadMagic100 BadMagic100 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, @flibber-hk I'll let you deal with the versioning w.r.t other prs

Copy link
Copy Markdown
Member

@flibber-hk flibber-hk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't reviewed the source gen stuff but approval for the rest of it (and obviously BadMagic's done a proper review of the source gen stuff)

@flibber-hk flibber-hk merged commit 37d0082 into main May 4, 2026
4 checks passed
This was referenced May 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants