tutorial:mixin_accessors
Differences
This shows you the differences between two versions of the page.
| Next revision | Previous revision | ||
| tutorial:mixin_accessors [2020/08/05 22:26] – created emmanuelmess | tutorial:mixin_accessors [2025/11/30 20:08] (current) – gauntrecluse | ||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== | + | ====== |
| - | ===== Introduction ===== | + | **Accessor Mixins** are special mixins defined as interfaces which must **only** contain '' |
| - | A type of mixin allows to you to access | + | The '' |
| + | |||
| + | Unlike typical injectors, accessors do not prefix the merged methods with the modid of the mod that contains them. Additionally as the **Accessor Mixins** are used in user code, the names of the handlers are not mangled, these differences are important to keep in mind when writing **Accessor Mixins** for compatibility and debugging purposes. | ||
| + | |||
| + | '' | ||
| + | Prefixing accessor or invoker handlers is not necessary if they are static, as those may not conflict, and the stacktrace provides the Mixin class whose handlers are involved in errors, thus making it sufficient without needing to prefix with the modid. | ||
| + | |||
| + | ===== Accessor ===== | ||
| + | '' | ||
| + | |||
| + | ==== Getting a value from the field ==== | ||
| + | < | ||
| + | @Mixin(class_310.class) | ||
| + | public interface class_310Accessor { | ||
| + | @Accessor(" | ||
| + | int modid$getItemUseCooldown(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | < | ||
| + | int field_1752 = ((class_310Accessor) class_310.method_1551()).modid$getItemUseCooldown(); | ||
| + | </ | ||
| + | |||
| + | ==== Setting a value to the field ==== | ||
| + | < | ||
| + | @Mixin(class_310.class) | ||
| + | public interface class_310Accessor { | ||
| + | @Accessor(" | ||
| + | void modid$setItemUseCooldown(int field_1752); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | < | ||
| + | ((class_310Accessor) class_310.method_1551()).modid$setItemUseCooldown(100); | ||
| + | </ | ||
| + | |||
| + | When the field is final and you need to set it, use '' | ||
| + | |||
| + | ===== Accessor for static fields ===== | ||
| + | FIXME // | ||
| + | Suppose we want to access the '' | ||
| + | |||
| + | ==== Getting a value from the field ==== | ||
| <code java> | <code java> | ||
| - | @Mixin(StructuresConfig.class) | + | @Mixin(VanillaLayeredBiomeSource.class) |
| - | public interface | + | public interface |
| - | @Accessor(" | + | @Accessor(" |
| - | | + | static |
| - | throw new IllegalAccessError(); | + | throw new AssertionError(); |
| - | } | + | } |
| } | } | ||
| </ | </ | ||
| - | The error will never be thrown, you can use the function. | ||
| + | Usage: | ||
| + | <code java> | ||
| + | List< | ||
| + | </ | ||
| + | |||
| + | ==== Setting a value to the field ==== | ||
| + | <code java> | ||
| + | @Mixin(VanillaLayeredBiomeSource.class) | ||
| + | public interface VanillaLayeredBiomeSourceAccessor { | ||
| + | @Accessor(" | ||
| + | static void setBiomes(List< | ||
| + | throw new AssertionError(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | <code java> | ||
| + | VanillaLayeredBiomeSourceAccessor.setBiomes(biomes); | ||
| + | </ | ||
| + | |||
| + | When the field is final and you need to set it, use '' | ||
| + | |||
| + | ===== Invoker ===== | ||
| + | '' | ||
| + | |||
| + | < | ||
| + | @Mixin(class_1560.class) | ||
| + | public interface class_1560Invoker { | ||
| + | @Invoker(" | ||
| + | boolean modid$invokeTeleportTo(double x, double y, double z); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | < | ||
| + | class_1560 enderman = ...; | ||
| + | ((class_1560Invoker) enderman).modid$invokeTeleportTo(0.0D, | ||
| + | </ | ||
| + | |||
| + | ===== Invoker for static methods ===== | ||
| + | FIXME //This example is not fully accurate to latest versions, '' | ||
| + | Suppose we want to invoke '' | ||
| + | |||
| + | <code java> | ||
| + | @Mixin(BrewingRecipeRegistry.class) | ||
| + | public interface BrewingRecipeRegistryAccessor { | ||
| + | @Invoker(" | ||
| + | static void invokeRegisterPotionType(Item item) { | ||
| + | throw new AssertionError(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | |||
| + | <code java> | ||
| + | BrewingRecipeRegistryAccessor.invokeRegisterPotionType(item); | ||
| + | </ | ||
| + | |||
| + | ==== Invoker for constructors ==== | ||
| + | |||
| + | Invokers for constructors must be static, pass ''"< | ||
| + | |||
| + | For example, we will use the '' | ||
| + | <code java> | ||
| + | @Mixin(Identifier.class) | ||
| + | public interface IdentifierAccessor { | ||
| + | @Invoker("< | ||
| + | static Identifier newIdentifier(String namespace, String path) { | ||
| + | throw new AssertionError(); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Usage: | ||
| + | <code java> | ||
| + | Identifier exampleVariable = IdentifierAccessor.newIdentifier(" | ||
| + | </ | ||
tutorial/mixin_accessors.1596666389.txt.gz · Last modified: 2020/08/05 22:26 by emmanuelmess