Skip to content

Commit

Permalink
Add architectury api mod event buses bridge
Browse files Browse the repository at this point in the history
  • Loading branch information
Su5eD committed Oct 7, 2023
1 parent e2d6aa3 commit 02aa769
Show file tree
Hide file tree
Showing 19 changed files with 399 additions and 19 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,10 @@ A Forge port of the Fabric [Reach Entity Attributes](https://github.com/JamiesWh
library, implemented alongside Forge's own reach attributes. Allows for compatiblity with Fabric mods that require it,
but wouldn't otherwise be compatible due to the heavy forge mixin conflicts of the original version.

### Architectury API Bridge

Registers mod event buses of Fabric mods to Architectury Forge to avoid registry init issues.

## Get help

If you're having trouble using Connector Extras or believe it is not functioning correctly, ask us
Expand Down
38 changes: 38 additions & 0 deletions architectury-bridge/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
plugins {
id("dev.architectury.loom")
}

val versionMc: String by rootProject
val versionForge: String by rootProject

loom {
forge {
mixinConfig("connectorextras_architectury_bridge.mixins.json")
}
mixin {
defaultRefmapName.set("mixins.connectorextras_architectury_bridge.refmap.json")
}
}

repositories {
maven {
name = "Sinytra"
url = uri("https://maven.su5ed.dev/releases")
}
maven {
name = "Architectury"
url = uri("https://maven.architectury.dev")
}
maven {
name = "Cursemaven"
url = uri("https://cursemaven.com")
}
}

dependencies {
mappings(loom.officialMojangMappings())
forge(group = "net.minecraftforge", name = "forge", version = "$versionMc-$versionForge")

modImplementation(group = "curse.maven", name = "sinytra-connector-890127", version = "4774408")
modImplementation(group = "dev.architectury", name = "architectury-forge", version = "9.1.12")
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.su5ed.sinytra.connectorextras.archbridge;

import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.loading.LoadingModList;

@Mod(ArchitecturyBridge.MODID)
public class ArchitecturyBridge {
public static final String MODID = "connectorextras_architectury_bridge";
private static final String ARCH_MODID = "architectury";

public ArchitecturyBridge() {
if (isEnabled()) {
ArchitecturyBridgeSetup.init();
}
}

public static boolean isEnabled() {
return LoadingModList.get().getModFileById(ARCH_MODID) != null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package dev.su5ed.sinytra.connectorextras.archbridge;

import dev.architectury.platform.forge.EventBuses;
import dev.su5ed.sinytra.connector.loader.ConnectorEarlyLoader;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.fml.ModList;
import net.minecraftforge.fml.javafmlmod.FMLModContainer;
import net.minecraftforge.fml.loading.LoadingModList;
import net.minecraftforge.fml.loading.moddiscovery.ModInfo;

import java.util.HashMap;
import java.util.Map;

public final class ArchitecturyBridgeSetup {
private static final Map<String, LazyEventBus> BUSES = new HashMap<>();

public static void setup() {
for (ModInfo mod : LoadingModList.get().getMods()) {
String modid = mod.getModId();
if (ConnectorEarlyLoader.isConnectorMod(modid)) {
LazyEventBus bus = new LazyEventBus();
BUSES.put(modid, bus);
EventBuses.registerModEventBus(modid, bus);
}
}
}

public static void init() {
ModList.get().forEachModContainer((modid, container) -> {
if (container instanceof FMLModContainer fmlModContainer) {
apply(modid, fmlModContainer.getEventBus());
}
});
}

private static void apply(String modid, IEventBus bus) {
LazyEventBus lateEventBus = BUSES.get(modid);
if (lateEventBus != null) {
lateEventBus.setBus(bus);
BUSES.remove(modid);
}
}

private ArchitecturyBridgeSetup() {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
package dev.su5ed.sinytra.connectorextras.archbridge;

import net.minecraftforge.eventbus.api.*;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class LazyEventBus implements IEventBus {
private final List<Object> toRegister = new ArrayList<>();
private IEventBus bus;

public void setBus(IEventBus bus) {
if (this.bus != null) {
throw new IllegalStateException();
}
this.bus = bus;
this.toRegister.forEach(bus::register);
this.toRegister.clear();
}

@Override
public void register(Object target) {
if (this.bus != null) {
this.bus.register(target);
} else {
this.toRegister.add(target);
}
}

@Override
public <T extends Event> void addListener(Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addListener(consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends Event> void addListener(EventPriority priority, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addListener(priority, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends Event> void addListener(EventPriority priority, boolean receiveCancelled, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addListener(priority, receiveCancelled, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends Event> void addListener(EventPriority priority, boolean receiveCancelled, Class<T> eventType, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addListener(priority, receiveCancelled, eventType, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addGenericListener(genericClassFilter, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, EventPriority priority, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addGenericListener(genericClassFilter, priority, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, EventPriority priority, boolean receiveCancelled, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addGenericListener(genericClassFilter, priority, receiveCancelled, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public <T extends GenericEvent<? extends F>, F> void addGenericListener(Class<F> genericClassFilter, EventPriority priority, boolean receiveCancelled, Class<T> eventType, Consumer<T> consumer) {
if (this.bus != null) {
this.bus.addGenericListener(genericClassFilter, priority, receiveCancelled, eventType, consumer);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public void unregister(Object object) {
if (this.bus != null) {
this.bus.unregister(object);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public boolean post(Event event) {
if (this.bus != null) {
return this.bus.post(event);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public boolean post(Event event, IEventBusInvokeDispatcher wrapper) {
if (this.bus != null) {
return this.bus.post(event, wrapper);
} else {
throw new UnsupportedOperationException();
}
}

@Override
public void shutdown() {
if (this.bus != null) {
this.bus.shutdown();
} else {
throw new UnsupportedOperationException();
}
}

@Override
public void start() {
if (this.bus != null) {
this.bus.start();
} else {
throw new UnsupportedOperationException();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.su5ed.sinytra.connectorextras.archbridge.mixin;

import dev.su5ed.sinytra.connectorextras.archbridge.ArchitecturyBridge;
import dev.su5ed.sinytra.connectorextras.archbridge.ArchitecturyBridgeSetup;
import net.minecraft.client.Minecraft;
import net.minecraft.client.main.GameConfig;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(value = Minecraft.class, priority = 100)
public abstract class MinecraftMixin {
@Inject(method = "<init>", at = @At(value = "INVOKE", target = "Ljava/lang/Thread;currentThread()Ljava/lang/Thread;"), remap = false)
private void archbridgeEarlyInit(GameConfig gameConfig, CallbackInfo ci) {
if (ArchitecturyBridge.isEnabled()) {
ArchitecturyBridgeSetup.setup();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package dev.su5ed.sinytra.connectorextras.archbridge.mixin;

import dev.su5ed.sinytra.connectorextras.archbridge.ArchitecturyBridge;
import dev.su5ed.sinytra.connectorextras.archbridge.ArchitecturyBridgeSetup;
import net.minecraft.server.Main;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;

@Mixin(value = Main.class, priority = 100)
public abstract class ServerMainMixin {
@Inject(method = "main", at = @At(value = "INVOKE", target = "Lnet/minecraftforge/server/loading/ServerModLoader;load()V"), remap = false)
private static void archbridgeEarlyInit(CallbackInfo ci) {
if (ArchitecturyBridge.isEnabled()) {
ArchitecturyBridgeSetup.setup();
}
}
}
33 changes: 33 additions & 0 deletions architectury-bridge/src/main/resources/META-INF/mods.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
modLoader="javafml"
loaderVersion="[47,)"
license="MIT"
issueTrackerURL="https://github.com/Sinytra/ConnectorExtras/issues"

[[mods]]
modId="connectorextras_architectury_bridge"
version="${file.jarVersion}"
displayName="Connector Architectury Bridge"
authors="Su5eD"
displayURL="https://github.com/Sinytra/ConnectorExtras"
description='''
Bridges Architectury API for Fabric mods on Forge
'''
displayTest = 'IGNORE_ALL_VERSION'
[[dependencies.connectorextras_architectury_bridge]]
modId="forge"
mandatory=true
versionRange="[47,)"
ordering="NONE"
side="BOTH"
[[dependencies.connectorextras_architectury_bridge]]
modId="minecraft"
mandatory=true
versionRange="[1.20.1,1.21)"
ordering="NONE"
side="BOTH"
[[dependencies.connectorextras_architectury_bridge]]
modId="connectormod"
mandatory=true
versionRange="[1.0.0-beta.18, )"
ordering="NONE"
side="BOTH"
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"required": true,
"minVersion": "0.8.4",
"refmap": "mixins.connectorextras_architectury_bridge.refmap.json",
"package": "dev.su5ed.sinytra.connectorextras.archbridge.mixin",
"compatibilityLevel": "JAVA_17",
"client": [
"MinecraftMixin"
],
"server": [
"ServerMainMixin"
],
"injectors": {
"defaultRequire": 1
}
}
6 changes: 6 additions & 0 deletions architectury-bridge/src/main/resources/pack.mcmeta
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"pack": {
"description": "The default data for connectorextras_architectury_bridge",
"pack_format": 15
}
}
Loading

0 comments on commit 02aa769

Please sign in to comment.