Replies: 3 comments
-
Thank you for the suggestion! I am unsure if implementing either of these suggestions is something I personally think benefits the API enough to justify the tremendous amount of diff we'd have to maintain. Disposable PluginDataHolder Events already exist (as described above) to catch "disposals". End I'll leave this open for other team members to comment on, thank you again for the suggestion it was certainly an interesting read. |
Beta Was this translation helpful? Give feedback.
-
I get your point, there is actually no reason this should be part of paper explicitly. Especially Disposable could be a pretty nice library on its own. Here is btw the jetbrains explanation of how Disposable works. They use them in combination with their event system and listeners can be linked to a disposable to restrict their lifetime to that object too (for example a world specific listener to a world if World were disposable). But I also see that minecraft listeners are usually more broad and filter the player within the listener callback rather than having one listener per player. |
Beta Was this translation helpful? Give feedback.
-
https://github.com/CubBossa/Disposables |
Beta Was this translation helpful? Give feedback.
-
Is your feature request related to a problem?
Not really, rather general code style
Describe the solution you'd like.
When working on a Jetbrains plugin I was positively surprised about how nice the plugin system works. I came across two patterns that I would love to use in Minecraft development and wanted to throw them in as ideas here.
Disposables:
A simple interface like Closable and AutoClosable, offering a
void dispose()
method. The dispose method is not similar to a destructor but declares the end of usage of an object. A constructor invocation and thedispose()
invocation frame the lifetime of the object unrelated to the garbage collection and referencing or anything.In combination with a Disposer instance, Disposables can be put into relation. For example,
Plugin
would extendDisposable
and whenever I create any lasting object within my plugin (classes like ScoreboardHandler, PlayerDataHandler, ...) I would let them implement Disposable and bind them to my plugin within the constructor.
If a plugin for whatever reasons disables, all its resources would be disposed by evaluating the relations in the Disposer instance.
A very common situation is that a plugin constructor needs to set up many different manager classes, which may want to be closed in onDisable().
If any step in onEnable() fails, onDisable() would be likely to create NullpointerExceptions and therefore have issues while disabling too.
With the disposable system, resources would be freed only if they have been claimed first and there would no need to reference them in the onDisable hook.
Another feature of it: Your own plugin could be linked to another plugin, so for example whenever Vault gets disabled, your plugin would be disposed through the linkage in the Disposer and disable itself too, if it relies on Vault. The lifespan of your plugin would be bound to its dependencies and if any fails, your plugin would not work properly and therefore disables too.
PluginDataHolder:
Another thing Jetbrains does is implement an Interface to hold keys and values, similar to the Pointered class from adventure. They implement it with File objects, AST nodes, Editors, etc.
If paper had a similar system for example for World or Entity, plugin developers could attach cache data to the player object. Whenever the player object gets cleared (or disposed) the cached data would be invalidated. Meaning, instead of requiring a
Map<UUID, MyParticlePlayer>
in any not so nice "ParticlePlayerHandler" class, I could attach myMyParticlePlayer
to the player object directly, using aKey<MyParticlePlayer>
as key. Why would I need a ParticlePlayer instance if the player is offline, so the lifespan of the player object always frames the lifespan of the ParticlePlayer. (Additionally by combining both mechanics, I could link the ParticlePlayer as Disposable to the World object it is playing in, so if the world gets deleted OR the player goes offline, the disposer takes care of the ParticlePlayer).Jetbrains pushes this to the point where a value can be cached and listens to certain changes in its holder, like cached values on an AST node become invalidated once the AST changes or, transferred to minecraft, cached values in the entities data become invalid if its location changes for example.
I know especially the second suggestion implies big changes but I thought about it so much that I felt like I had to at least suggest it once. Plugin reloading after all became discouraged because you could run into artifacts of the previous plugin instance, like not freed singletons and stuff. Disposables are the way jetbrains handles the (de)activation of plugins at any time and only under some conditions enforces a restart. Plugins that failed to load don't needlessly occupy memory and so on.
Describe alternatives you've considered.
None, its additional features
Other
No response
Beta Was this translation helpful? Give feedback.
All reactions