Skip to content

Implementation Policy: Bridges and Mixins

Chris Sanders edited this page Jun 24, 2019 · 29 revisions

Preamble

In the past, Sponge had no distinct structural policy beyond a couple of followed "rules" when adding new mixins/interfaces to the various projects. One of these rules, IMixin-style interfaces, served us well and is followed by many projects out there but leads to hard-to-maintain code when it isn't clear where things are coming from and going to. Likewise prefixing or lack thereof in several Mixins and their injectors/redirectors/etc makes for hard to decipher logs of exactly where problems are at and, on a more alarming level, general comprehension of the codebase. After discussion and coming to terms with this, @gabizou and @Zidane have decided to iron this out with a policy once and for all.

Mixins

Rules

  • Mixin class names should be prefixed with the Mixin target's name then the word Mixin followed by _ and finally the Mixin config's name.
    • Only one config is exempt from this and that is mixins originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation.
      • Based on this exemption, if you are mixing into net.minecraft.world.chunk.Chunk from core, the mixin would be named ChunkMixin.
      • Based on this exemption, if you are mixing into Chunk from forge, the mixin would be named ChunkMixin_Forge.
  • For multi-target mixins1, names should be prefixed with the most relevant name then the word Mixin followed by _ and finally the Mixin config's name.
    • Only one config is exempt from this and that is mixins originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation.
      • Based on this exemption, if you are mixing into Entity and TileEntity to implement DataHolder from core, the mixin would be DataHolderMixin2.
      • Based on this exemption, if you are mixing into Entity and TileEntity to implement DataHolder from forge, the mixin would be DataHolderMixin_Forge.

Bridges

Bridges bridge the gap between Minecraft classes (ex. net.minecraft.world.chunk.Chunk) and the Sponge implemented code via Mixins (ex. MixinChunk. There are many times where we need to call methods to perform logic off of those classes and can do so via these distinct interfaces. Replaces legacy IMixin intefaces (ex. IMixinChunk).

Rules

  • Bridge class names should be prefixed with the Mixin's target name then the word Bridge followed by _ and finally the Mixin config's name.
    • Only one config is exempt from this and that is bridges originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation.
      • Based on this exemption, if you are writing a bridge for ChunkMixin from core, the bridge would be ChunkBridge.
      • Based on this exemption, if you are writing a bridge for ChunkMixin_Forge from forge, the bridge would be ChunkBridge_Forge.
  • For multi-target bridges, names should be prefixed with the most relevant name then the word Bridge followed by _ and finally the Mixin config's name.
    • Only one config is exempt from this and that is bridges originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation.
      • Based on this exemption, if you are mixing into Entity and TileEntity to implement Creator tracking in core, the bridge would be OwnershipTrackableBridge.
      • Based on this exemption, if you are mixing into Entity and TileEntity to implement Creator tracking in forge, the bridge would be OwnershipTrackableBridge_Forge.
  • Bridge method names should be prefixed with the Mixin config's name followed by the word bridge and then $.
    • Only one config is exempt from this and that is bridges originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation.
      • Based on this exemption, setTransform in EntityBridge from core would be named bridge$setTransform.
      • Based on this exemption, setTransform in EntityBridge_Forge from forge would be named forgeBridge$setTransform.
  • Bridges are not allowed to extend from other Bridges, even if the Bridge is effectively a subclass of another Bridge (ex. ChunkBridge_Forge is effectively a child of ChunkBridge)
    • The reasoning for this is to prevent potential corner cases where a developer inadvertently performs a cast on code that will not exist on the platform currently running it.
      • For example, casting ChunkProviderClient to ChunkProviderServerBridge simply to call a method inherited from ChunkProviderBridge.

Injections

Injections "inject" Sponge logic into classes at explicitly defined targets.

Rules

  • Injection method names should be prefixed with the Mixin config's name followed by an appropriate method name for the context.
    • Only one config is exempt from this and that is injections originating from the core config in SpongeCommon as that is the baseline for the entire Sponge implementation. Instead we make this impl.
      • Based on this exemption, an injection into onUpdate of Entity in EntityMixin in core would be named impl$onUpdate.
      • Based on this exemption, an injection into onUpdate of Entity in EntityMixin in forge would be named forge$onUpdate.
Clone this wiki locally