Conversation
Everest already needs the .NET 9 SDK to compile, so we might as well utilize its features.
microlith57
left a comment
There was a problem hiding this comment.
initial comments, will review more thoroughly later!
| [MaybeNull] out Effect customEffect, | ||
| out Matrix transformMatrix) | ||
| { | ||
| // life would be good if we could just access these directly... |
There was a problem hiding this comment.
query: why can't we? surely monomod has some way do do this right?
There was a problem hiding this comment.
I am using DynamicData here.
It'd be great if we didn't have to resort to DynamicData or reflection and just access fields directly.
There was a problem hiding this comment.
yes that's what i mean, i don't know if monomodlinkto does what we want but if not i would expect a similar thing exists
i guess in the worst case we can always write the body of this method in il
There was a problem hiding this comment.
The JIT would still check access permissions, unless we [IgnoreAccessChecksTo("FNA")], but I don't feel like this is a good idea.
There was a problem hiding this comment.
Everest already applies patches to FNA, I think it wouldn't be too crazy to do this, especially since this api is by definition going to be called on a hot path. I could see it being useful for mods to be able to access the current sprite batch state in general as well. (Doesn't Everest already have a different place (Parallax?) where it gets this information as well?)
There was a problem hiding this comment.
yea, definitely agree. it's well within everest's remit to do this. if we just ignore access checks from everest to fna (while still requiring mods to do that manually themselves if applicable), that should be fine right?
There was a problem hiding this comment.
I'm wondering what sort of patches would be necessary here to avoid having to use DynamicData without breaking mods who might be reflecting on it...
There was a problem hiding this comment.
I think adding get-only props to SpriteBatch would be fine, and wouldn't conflict with reflection.
|
Since we've already on .net 8, what about enable null context for this file instead of using these attributes? |
| [MaybeNull] out Effect customEffect, | ||
| out Matrix transformMatrix) | ||
| { | ||
| // life would be good if we could just access these directly... |
There was a problem hiding this comment.
Everest already applies patches to FNA, I think it wouldn't be too crazy to do this, especially since this api is by definition going to be called on a hot path. I could see it being useful for mods to be able to access the current sprite batch state in general as well. (Doesn't Everest already have a different place (Parallax?) where it gets this information as well?)
I missed this, huh. I guess we can go with |
microlith57
left a comment
There was a problem hiding this comment.
still uncomfortable with the DynamicData so this isn't an approval yet. but good progress, i like the ArrayPool!
| <AssemblyName>Celeste.Mod.mm</AssemblyName> | ||
| <RootNamespace>Celeste</RootNamespace> | ||
| <AllowUnsafeBlocks>true</AllowUnsafeBlocks> | ||
| <LangVersion>11</LangVersion> |
There was a problem hiding this comment.
nitpick/query: did you mean to remove this entirely? why not explicitly specify 12? i guess if it's the default that's fine but seems strange nevertheless
There was a problem hiding this comment.
I thought we were using C#11 since we're in .NET 8 but apparently not.
Not setting the language version explicitly makes it default to the latest one at the time of the release of the version specified by the TFM. In this case it would be C#12.
Though, since several other PRs have suggested bumping the language version, I think we should move that change to a separate PR.
| [MaybeNull] out Effect customEffect, | ||
| out Matrix transformMatrix) | ||
| { | ||
| // life would be good if we could just access these directly... |
There was a problem hiding this comment.
yea, definitely agree. it's well within everest's remit to do this. if we just ignore access checks from everest to fna (while still requiring mods to do that manually themselves if applicable), that should be fine right?
| /// <summary> | ||
| /// The <see cref="SpriteSortMode"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly SpriteSortMode CurrentSortMode; | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="BlendState"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly BlendState CurrentBlendState; | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="SamplerState"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly SamplerState CurrentSamplerState; | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="DepthStencilState"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly DepthStencilState CurrentDepthStencilState; | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="RasterizerState"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly RasterizerState CurrentRasterizerState; | ||
|
|
||
| /// <summary> | ||
| /// The custom <see cref="Effect"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly Effect? CurrentCustomEffect; | ||
|
|
||
| /// <summary> | ||
| /// The transformation <see cref="Matrix"/> of this <see cref="TemporarySpriteBatch"/>. | ||
| /// </summary> | ||
| public readonly Matrix CurrentTransformMatrix; | ||
|
|
||
| /// <summary> | ||
| /// The <see cref="RenderTarget2D"/> swapped in for the duration of this <see cref="TemporarySpriteBatch"/> | ||
| /// or <c>null</c> to draw to the screen if <see cref="HasRenderTarget"/> is <c>true</c>; else always <c>null</c>. | ||
| /// </summary> | ||
| public readonly RenderTarget2D? CurrentRenderTarget; | ||
|
|
There was a problem hiding this comment.
These Current... fields seem a bit questionable, since they're only used in the ctor and bloat the already-large struct even more.
The fields could be useful as a way to pass rendering info around various methods, but the Builder seems better to use for this purpose (since the code receiving a builder can use it to restart/change the batch etc).
If Everest exposes a public way of retrieving this info from the SpriteBatch directly, these become less important as well.
| /// <b>Note: Restarting a spritebatch flushes it to the GPU.</b> | ||
| /// While the cost is not that significant, it's best to avoid restarting the spritebatch too often per frame. | ||
| /// </remarks> | ||
| public sealed class TemporarySpriteBatchBuilder |
There was a problem hiding this comment.
Maybe worth making a record (struct?) to allow easily making a copy of the builder (to later change some of its settings)? Or maybe just a Clone() method instead.
If this doesn't become a struct, would be good to make the TemporarySpriteBatch ctor public for cases where caching the builder is not reasonable. (In which case, the ctor should probably have default values for all parameters so it's easy to pick and choose named parameters as needed).
| [MaybeNull] out Effect customEffect, | ||
| out Matrix transformMatrix) | ||
| { | ||
| // life would be good if we could just access these directly... |
There was a problem hiding this comment.
I think adding get-only props to SpriteBatch would be fine, and wouldn't conflict with reflection.


Adds a helper
TemporarySpriteBatchtype to easily interrupt an existingSpriteBatch, optionally swap in aRenderTarget2D, and start a newSpriteBatch.When disposed, the new
SpriteBatchis ended, the oldRenderTarget2Dis restored and the previousSpriteBatchis resumed.Also bumps the language version to C# 13, as this is necessary for ref structs to implement interfaces.We already need .NET 9 to compile Everest, so we might as well make use of C# 13.EDIT: Implicitly implementing
IDisposablelets us go back to<LangVersion>12, so the version bump isn't necessary. Ideally we should implementIDisposablebut this will work for now, until we jump to .NET 10.