-
-
Notifications
You must be signed in to change notification settings - Fork 371
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
Add Module System #4573
Add Module System #4573
Conversation
On the topic of modules, are there plans to modularise Skript further using JPMS? |
No, this is incompatible with Spigot/CB. |
Ah, of course |
Concerning this, we could revive Shane's old suggestion of allowing addons to be registered directly to Skript (as Modules) rather than as Bukkit plugins. Addons like skript-yaml, etc. don't need to be plugins and could save resources by just being our modules. |
@@ -518,42 +513,23 @@ public void onEnable() { | |||
@Override | |||
public void run() { | |||
assert Bukkit.getWorlds().get(0).getFullTime() == tick; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is this actually for? It's a test-only action but I can't see a comment explaining it.
getAddonInstance().loadClasses(c -> { | ||
if (Hook.class.isAssignableFrom(c) && !c.isInterface() && !Modifier.isAbstract(c.getModifiers())) { | ||
try { | ||
c.getDeclaredConstructor().newInstance(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to move away from using newInstance
here - it's the slowest and least-reliable way of creating instances.
|
||
try (final JarFile jar = new JarFile(file)) { | ||
boolean hasWithClass = withClass != null; | ||
for (JarEntry e : new EnumerationIterable<>(jar.entries())) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've been exploring a more efficient way of getting all classes within a package, will let you know on discord if it's a viable alternative.
return loadClasses(c -> { | ||
if (Module.class.isAssignableFrom(c) && !c.isInterface() && !Modifier.isAbstract(c.getModifiers())) { | ||
try { | ||
((Module) c.getConstructor().newInstance()).register(this); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Again, we may be able to find a better option for this.
This a good idea but can likely be done in another PR as it requires removing SkriptAddon's dependency on JavaPlugin. |
I've implemented a cache for the jar entries so that the loadClasses method is more performant when being called multiple times. Every SkriptAddon has a cache, and all caches are cleared when Skript stops accepting registrations. |
This implements the "current" behavior
My most recent commit makes a large change to Skript's general organization. I'm proposing two new main packages: In the future, I'd certainly like to hear thoughts on this :) |
Forgot to update for Structure API
Packages should reference the dependency ID so that it is clear where code comes from. |
It's not guaranteed
and formatting improvements
"common" and "bukkit"
I've decided to move syntax into two primary locations within
|
Don't you think this should target 2.8? We should have a full package change to com.skriptlang in a major version, not just a module system, but the planned package naming all done in one version. |
We can target this for 2.8 now yes. I did not plan to move all syntax with a simple rename. It should happen over time through targeted PRs (like my potions rework) to ensure that all syntax can be updated to current standards :) |
/** | ||
* Loads all module classes found in the package search. | ||
* @param basePackage The base package to start searching in (e.g. 'ch.njol.skript'). | ||
* @param subPackages Specific subpackages to search in (e.g. 'conditions'). | ||
* If no subpackages are provided, all subpackages will be searched. | ||
* Note that the search will go no further than the first layer of subpackages. | ||
* @return This SkriptAddon. | ||
*/ | ||
@SuppressWarnings("ThrowableNotThrown") | ||
public SkriptAddon loadModules(String basePackage, String... subPackages) { | ||
return loadClasses(basePackage, false, false, c -> { | ||
if (Module.class.isAssignableFrom(c) && !c.isInterface() && !Modifier.isAbstract(c.getModifiers())) { | ||
try { | ||
((Module) c.getConstructor().newInstance()).register(this); | ||
} catch (Exception e) { | ||
Skript.exception(e, "Failed to load module " + c); | ||
} | ||
} | ||
}, subPackages); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would prefer an alternative to this:
a) Code generation of module registration
b) Manual module registration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the addon discovery thing we talked about on Discord will become mainstream, a modules: ["org.example.addon.math.MathModule", ...]
field can be added to addon.json
.
bd134d0
to
3f08853
Compare
Closing as I am planning to reintegrate this system in a more meaningful manner in #5331 |
Description
The purpose of this PR is to start discussion on implementing a new package / syntax organization system for Skript. I created this as a PR as I wanted to be able to show an idea I had.
The actual proposal in this PR is to implement a new Module class. All SkriptAddon's would have one or more modules that contain syntax, classinfos, converters, and more. Skript itself would use this module system to reorganize its syntax. Here's an example:
What this PR changes:
org.skriptlang.skript
)ch.njol.skript.hooks
) using updated SkriptAddon load methodsloadClasses
method can no longer throw an IOException - This change is up for debate, but I personally don't see a reason to not handle it internally (it is unlikely to ever happen anyways) - however, it it were to happen, addons no longer have a way to handle it which could be a downsideloadModules
methodregister(SkriptAddon)
methodloadSyntax
methodsaddon.loadClasses("org.skriptlang.skript.potion.elements")
you could writeloadSyntax(addon)
loadClasses
so frequently. Perhaps it would be better off if syntax was "manually" initialized vianew MySyntaxElement()
Please share any questions, feedback or ideas! This proposal is certainly not perfect, so I am looking for any ideas you may have :)
Target Minecraft Versions: N/A
Requirements: None
Related Issues: