Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/caellian/loaderenv
Compiler plugin that allows conditional compilation based on active mod loader.
https://github.com/caellian/loaderenv
annotation annotation-processor compiler-plugin gradle-plugin javac minecraft
Last synced: 14 days ago
JSON representation
Compiler plugin that allows conditional compilation based on active mod loader.
- Host: GitHub
- URL: https://github.com/caellian/loaderenv
- Owner: Caellian
- License: apache-2.0
- Created: 2024-08-11T23:01:10.000Z (3 months ago)
- Default Branch: trunk
- Last Pushed: 2024-08-17T08:29:37.000Z (3 months ago)
- Last Synced: 2024-08-17T09:37:31.880Z (3 months ago)
- Topics: annotation, annotation-processor, compiler-plugin, gradle-plugin, javac, minecraft
- Language: Java
- Homepage:
- Size: 59.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE-2.0
Awesome Lists containing this project
README
# LoaderEnv
This is a very simple Java compiler plugin that (optionally) integrates into Gradle build environment to allow
conditional inclusion and exclusion of classes/methods/fields based on the mod loaders that are present while compiling
a project. See [Usage](#Usage) section below for examples.## Usage
LoaderEnv library adds two annotations:
- [`@NotForLoader`](https://github.com/Caellian/LoaderEnv/blob/trunk/modules/lib/src/main/java/net/tinsvagelj/mc/loaderenv/NotForLoader.java)
- [`@OnlyForLoader`](https://github.com/Caellian/LoaderEnv/blob/trunk/modules/lib/src/main/java/net/tinsvagelj/mc/loaderenv/OnlyForLoader.java)You can annotate classes and methods with either to hide them if specified mod loader is(n't) present:
```java
@OnlyForLoader(Loader.FORGE)
public void useFluid(net.minecraftforge.fluids.FluidStack fluid) {
useFluid(fluid.getFluid(), fluid.getAmount());
}
public void useFluid(Fluid fluid, float buckets) {
// ... implementation details ...
}
```If the code is compiled without Forge in classpath (e.g. for Fabric), the first method definition will not be present.
This means you can also add your own polyfill to bridge functionality you need to rely on (if not already available).
```java
package must.be.in.your.own.pkg;// ... imports ...
// Cause compiler errors if wrong class is used in Forge:
@NotForLoader(Loader.FORGE)
class FluidStack {
// ... implementation details ...
}
```Last important bit of information is that you can specify multiple mod loaders. This allows fine-grained control over
mod functionality at compile time:
```java
@OnlyForLoader({Loader.FORGE, Loader.NEO_FORGE})
public void initClientsideModLogic() {
// ... forge/neoforge client init ...
}
@NotForLoader({Loader.FORGE, Loader.NEO_FORGE})
public void initClientsideModLogic() {
// ... non-forge client init ...
}
```## Important Notes
**IDEs _will_ (by default) show errors even though element conditions are mutually exclusive.**
Code itself will however properly compile with `gradle`/`javac` - this is because Java IDEs have their own error
inspection code and don't use java compiler for error reporting (such as missing types).
While this is a much faster approach, the tradeoff is inaccurate highlighting.Properly supporting all mainstream IDEs is a lot of work and adds more maintenance burden than I'm willing to put into
this project at the moment.
There's a [minimal implementation](./modules/jetbrains) available for Jetbrains IntelliJ platform (IDEA).
Contributions are welcome.This plugin runs before any other annotations have been processed, which means it should (hopefully) work as expected
alongside other annotation processors such as [Lombok](https://github.com/projectlombok/lombok).Questions And Answers
- How likely is the plugin to break?
- This compiler plugin relies on abstractions provided by java compiler to avoid touching too much of compiler internals.
It's more stable than rest of the code you'll write, so don't worry about it. - I want another/my mod loader supported.
- Make a PR. You need to only add an entry to
LoaderEnv
enum in the loaderenv-lib module. - Why add ancient/discontinued mod loaders?
- They serve as examples.
- It's very cheap to add
LoaderEnv
entries so there's no reason not to support old stuff. - Archival purposes.
- What's the purpose of this?
- It's supposed to make writing base libraries that work
for different mod loaders easier. It should also work for mods, but that's a lot more involved and I believe it's better
to separate implementations into different submodules and then use this processor in the common code instead. - Why not just use reflection?
- While reflection is much simpler, it's too costly when it runs in a game loop. This plugin bridges the gap between
development ergonomics and build system complexity. - What's your motivation for writing this?
- I wanted to try writing a Java compiler plugin that does something similar to C/C++ preprocessor and Rust cfg.
## License
This project is licensed under ternary [MIT](./LICENSE-MIT)/[Apache-2.0](./LICENSE-APACHE-2.0)/[Zlib](./LICENSE-ZLIB) license.
Adhere to whichever fits your use case the best.