Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GTParticle/bloom effect refactor and cleanup #2073

Merged
merged 20 commits into from
Nov 26, 2023

Conversation

Tictim
Copy link
Contributor

@Tictim Tictim commented Sep 7, 2023

What

This PR is yet another "internal refactor" PR that murders backwards compatibility for the sake of delusional concepts such as "cleaner code" and nothing else a refactor and cleanup for small part of client code, namely GTParticle and bloom effect code.

Implementation Details

GTParticle refactor

Among 5 GTParticle implementations only 3 of them are used in base mod. Not to mention most of the functionality contained in GTParticle are not utilized. Since the 3 implementations used in base mod are all non-universal implementations for only one use case each. I've decided to refactor all GTParticle implementations to reflect these use cases.

  • Drastically reduced features GTParticle base class provides by default. GTParticle no longer directly extends vanilla Particle, which removes things like particle movements, colors, particle ages etc. Also the weird atlas animation thing was removed from GTParticle.
  • Made each 3 implementations directly interact with MTE on update. Previously the tick function was injected from caller, which I think is redundant for already highly localized implementations.
  • Removed unused GTTexturedParticle and GTTexturedShaderParticle.
  • Migrated IGTParticleHandler to base interface ICustomRenderFast, which got renamed to RenderSetup to reflect the functionality of the type better.

Parameter of GTParticleManager#addEffect was changed from addEffect(GTParticle...) to addEffect(GTParticle).

GTParticleManager has additional behavior change compared to previous iteration; on particle draw, particles with depth mask disabled now gets rendered first instead of last. This behavior is actually in line with vanilla particle manager, and since I don't see reasoning behind this particular change, I just applied vanilla logic.

Bloom effect refactor

Most of the changes are naming corrections and code restructurings. One major change, however, is the removal of requestCustomBloom in favor of the new method scheduleBloomRender. IBloomRenderFast was also migrated to base class ICustomRenderFast, which got renamed to RenderSetup.

However this approach is still massively inefficient, because each custom bloom render still has to be registered each tick. This could produce nontrivial amount of heap pollution if enough renders get scheduled, but for now the performance impact shouldn't be apparent at least on base mod since this feature is currently being used on whopping 2 places.

Some fields and methods were preserved for compatibility reasons, namely BloomEffectUtil#BLOOM and BloomEffectUtil#getRealBloomLayer. The latter was renamed to avoid connotations of the returned object being the "real" bloom layer, which isn't true.

Others (TM)

Changed names of Eases enum because I couldn't stand it. The old names are provided with static final fields to prevent API breaking changes. #archcommit

Outcome

No major behavior change is to be expected.

Potential Compatibility Issues

Technically the number of API change is one, but I'm pretty sure there's no person calling Eases#valueOf() so I think this one is safe. If someone is calling Eases#valueOf(), please contact me so I can change the number of people calling Eases#valueOf() back to 0.

Addons using GTParticle system should cope adjust the usage to new code. Same goes for BloomEffectUtil#scheduleBloomRender.

@Tictim Tictim requested a review from a team as a code owner September 7, 2023 05:50
@Tictim Tictim added the type: refactor Suggestion to refactor a section of code label Sep 7, 2023
@TechLord22 TechLord22 added this to the 2.8 milestone Sep 24, 2023
Copy link
Member

@bruberu bruberu left a comment

Choose a reason for hiding this comment

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

The code itself looks good, other than a couple of things addressed on Discord. This should just need in-game testing now.

@bruberu
Copy link
Member

bruberu commented Nov 17, 2023

In-game testing seems fine, except for energy laser particles disappearing after exiting and rejoining a world.

src/main/java/gregtech/api/util/interpolate/Eases.java Outdated Show resolved Hide resolved
for (GTParticle particle : newParticleQueue) {
var queue = particle.shouldDisableDepth() ? depthDisabledParticles : depthEnabledParticles;

ArrayDeque<GTParticle> particles = queue.computeIfAbsent(particle.getRenderSetup(), setup -> new ArrayDeque<>());
Copy link
Member

Choose a reason for hiding this comment

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

Since particle.getRenderSetup() is nullable, we may we wish to skip this operation altogether. Associating a deque for a null key sounds like cause for potential issues here. If using null this way is intentional, I think some sort of explicit dummy IRenderSetup would be more appropriate.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nullable render setup instance is an explicit decision here, because I found the notion of null render setups more straightforward - "no render setup" directly correlates to "no render setup instance (null)", while using nonnull representation you have to say there should be something even if the thing that object represents is just nothing. Plus it avoids pitfall of users just making empty impl for the interface because returning null crashes the game with NPE, breaking render setup's equality contract in the process.

The inner part of the API (the part of code this conversation is taking place) also uses nullable keys, because (1) the collection lib gracefully supports it (fuck you stdlib), (2) it's (probably) (slightly) faster and (3) there's no need to make null-object representation if base API does not uses it.

While the key nullability is undocumented, the render setup is used in one place, and the collection is only internal, so I think there's no big risk there. I personally would have liked nullable annotation in the type (like Map<@Nullable IRenderSetup, ArrayDeque<GTParticle>>), but I couldn't do that since I was using findbugs nullable annotations, which cannot target types.

Still I probably have to document the nullability lol

Comment on lines +23 to +33
public int getValue() {
return switch (this) {
case GAUSSIAN -> 0;
case UNITY -> 1;
case UNREAL -> 2;
case DISABLED -> -1;
};
}

@Nonnull
public static BloomType fromValue(int value) {
Copy link
Member

Choose a reason for hiding this comment

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

Instead of these two methods, I think we should use the enum in the config directly. Forge does natively support this and does also display a list of valid enum constants to choose in the config file.

Copy link
Contributor

@ghzdude ghzdude left a comment

Choose a reason for hiding this comment

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

looks fine in-game on client and server.

on server rejoin particles disappear, but this is not really an issue so it's non-blocking. name particles are fine.

@serenibyss serenibyss enabled auto-merge (squash) November 26, 2023 21:33
@serenibyss serenibyss merged commit 0e716f8 into GregTechCEu:master Nov 26, 2023
@Tictim Tictim deleted the gtparticle_cleanup branch November 28, 2023 05:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: refactor Suggestion to refactor a section of code
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants