diff --git a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java index 4e6f1751b..658163c71 100644 --- a/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java +++ b/common/addons/config-ore/src/main/java/com/dfsek/terra/addons/ore/OreAddon.java @@ -7,27 +7,26 @@ package com.dfsek.terra.addons.ore; -import com.dfsek.terra.addons.manifest.api.AddonInitializer; -import com.dfsek.terra.api.Platform; -import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer; +import com.dfsek.terra.addons.manifest.api.monad.Get; +import com.dfsek.terra.addons.manifest.api.monad.Init; import com.dfsek.terra.api.event.events.config.pack.ConfigPackPreLoadEvent; import com.dfsek.terra.api.event.functional.FunctionalEventHandler; -import com.dfsek.terra.api.inject.annotations.Inject; -public class OreAddon implements AddonInitializer { - @Inject - private Platform platform; - - @Inject - private BaseAddon addon; - +public class OreAddon implements MonadAddonInitializer { @Override - public void initialize() { - platform.getEventManager() - .getHandler(FunctionalEventHandler.class) - .register(addon, ConfigPackPreLoadEvent.class) - .then(event -> event.getPack().registerConfigType(new OreConfigType(), addon.key("ORE"), 1)) - .failThrough(); + public Init initialize() { + return Get.eventManager() + .map(eventManager -> eventManager.getHandler(FunctionalEventHandler.class)) + .bind(functionalEventHandler -> + Get.addon() + .map(addon -> functionalEventHandler + .register(addon, ConfigPackPreLoadEvent.class) + .then(event -> event + .getPack() + .registerConfigType(new OreConfigType(), addon.key("ORE"), 1)) + .failThrough() + )); } } diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/MonadAddonInitializer.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/MonadAddonInitializer.java new file mode 100644 index 000000000..594c8bf23 --- /dev/null +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/MonadAddonInitializer.java @@ -0,0 +1,8 @@ +package com.dfsek.terra.addons.manifest.api; + +import com.dfsek.terra.addons.manifest.api.monad.Init; + + +public interface MonadAddonInitializer { + Init initialize(); +} diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Get.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Get.java new file mode 100644 index 000000000..66fa105c9 --- /dev/null +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Get.java @@ -0,0 +1,25 @@ +package com.dfsek.terra.addons.manifest.api.monad; + +import com.dfsek.terra.addons.manifest.impl.InitInfo; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.event.EventManager; + + +public final class Get { + private Get() { + + } + + public static Init eventManager() { + return Init.of(initInfo -> initInfo.platform().getEventManager()); + } + + public static Init addon() { + return Init.of(InitInfo::addon); + } + + public static Init platform() { + return Init.of(InitInfo::platform); + } +} diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Init.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Init.java new file mode 100644 index 000000000..b782712f5 --- /dev/null +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/api/monad/Init.java @@ -0,0 +1,39 @@ +package com.dfsek.terra.addons.manifest.api.monad; + +import com.dfsek.terra.addons.manifest.impl.InitInfo; +import com.dfsek.terra.api.util.function.Functions; +import com.dfsek.terra.api.util.function.monad.Monad; + +import java.util.function.Function; + + +public class Init implements Monad> { + private final Function get; + + public static Init of(Function get) { + return new Init<>(get); + } + + private Init(Function get) { + this.get = get; + } + + public T apply(InitInfo platform) { + return get.apply(platform); + } + + @Override + public Init bind(Function>> map) { + return new Init<>(info -> ((Init) map.apply(apply(info))).apply(info)); + } + + @Override + public Init map(Function fn) { + return (Init) Monad.super.map(fn); + } + + @Override + public Monad> pure(U u) { + return of(Functions.constant(u)); + } +} diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/InitInfo.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/InitInfo.java new file mode 100644 index 000000000..84045ff7d --- /dev/null +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/InitInfo.java @@ -0,0 +1,13 @@ +package com.dfsek.terra.addons.manifest.impl; + +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; + +import java.util.function.Function; + + +public record InitInfo( + Platform platform, + BaseAddon addon +) { +} diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/Initializer.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/Initializer.java new file mode 100644 index 000000000..58df34f0c --- /dev/null +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/Initializer.java @@ -0,0 +1,65 @@ +package com.dfsek.terra.addons.manifest.impl; + +import com.dfsek.terra.addons.manifest.api.AddonInitializer; +import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer; +import com.dfsek.terra.api.Platform; +import com.dfsek.terra.api.addon.BaseAddon; +import com.dfsek.terra.api.inject.Injector; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +public abstract class Initializer { + private Initializer() { + + } + + public static Initializer of(MonadAddonInitializer addon) { + return new MonadInitializer(addon); + } + + public static Initializer of(AddonInitializer addonInitializer) { + return new BasicInitializer(addonInitializer); + } + + public abstract void initialize(InitInfo info); + + private static class MonadInitializer extends Initializer { + private final MonadAddonInitializer addon; + + private MonadInitializer(MonadAddonInitializer addon) { + this.addon = addon; + } + + @Override + public void initialize(InitInfo info) { + addon.initialize().apply(info); + } + } + + + private static class BasicInitializer extends Initializer { + private final AddonInitializer initializer; + + private BasicInitializer(AddonInitializer initializer) { + this.initializer = initializer; + } + + @Override + public void initialize(InitInfo info) { + Injector addonInjector = Injector.get(info.addon()); + addonInjector.addExplicitTarget(BaseAddon.class); + + Injector platformInjector = Injector.get(info.platform()); + platformInjector.addExplicitTarget(Platform.class); + + Injector loggerInjector = Injector.get(LoggerFactory.getLogger(initializer.getClass())); + loggerInjector.addExplicitTarget(Logger.class); + addonInjector.inject(initializer); + platformInjector.inject(initializer); + loggerInjector.inject(initializer); + initializer.initialize(); + } + } +} diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddon.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddon.java index a0c23f284..7e15208b4 100644 --- a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddon.java +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddon.java @@ -26,11 +26,11 @@ import com.dfsek.terra.api.inject.annotations.Inject; public class ManifestAddon implements BaseAddon { private static final Logger logger = LoggerFactory.getLogger(ManifestAddon.class); private final AddonManifest manifest; - private final List initializers; + private final List initializers; @Inject private Platform platform; - public ManifestAddon(AddonManifest manifest, List initializers) { + public ManifestAddon(AddonManifest manifest, List initializers) { this.manifest = manifest; this.initializers = initializers; } @@ -45,23 +45,13 @@ public class ManifestAddon implements BaseAddon { } public void initialize() { - Injector addonInjector = Injector.get(this); - addonInjector.addExplicitTarget(BaseAddon.class); - Injector platformInjector = Injector.get(platform); - platformInjector.addExplicitTarget(Platform.class); logger.debug("Initializing addon {}", getID()); initializers.forEach(initializer -> { - Injector loggerInjector = Injector.get(LoggerFactory.getLogger(initializer.getClass())); - loggerInjector.addExplicitTarget(Logger.class); - logger.debug("Invoking entry point {}", initializer.getClass()); - addonInjector.inject(initializer); - platformInjector.inject(initializer); - loggerInjector.inject(initializer); - initializer.initialize(); + initializer.initialize(new InitInfo(platform, this)); }); } diff --git a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddonLoader.java b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddonLoader.java index 00a54a226..87394e354 100644 --- a/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddonLoader.java +++ b/common/addons/manifest-addon-loader/src/main/java/com/dfsek/terra/addons/manifest/impl/ManifestAddonLoader.java @@ -13,6 +13,9 @@ import ca.solostudios.strata.version.VersionRange; import com.dfsek.tectonic.api.exception.LoadException; import com.dfsek.tectonic.api.loader.ConfigLoader; import com.dfsek.tectonic.yaml.YamlConfiguration; + +import com.dfsek.terra.addons.manifest.api.MonadAddonInitializer; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -72,13 +75,17 @@ public class ManifestAddonLoader implements BootstrapBaseAddon { throw new AddonException("Addon " + manifest.getID() + " has unknown schema version: " + manifest.getSchemaVersion()); } - List initializers = manifest.getEntryPoints().stream().map(entryPoint -> { + List initializers = manifest.getEntryPoints().stream().map(entryPoint -> { try { Object in = loader.loadClass(entryPoint).getConstructor().newInstance(); - if(!(in instanceof AddonInitializer)) { - throw new AddonException(in.getClass() + " does not extend " + AddonInitializer.class); + if(in instanceof AddonInitializer a) { + return Initializer.of(a); } - return (AddonInitializer) in; + + if(in instanceof MonadAddonInitializer m) { + return Initializer.of(m); + } + throw new AddonException(in.getClass() + " is not a valid initializer" ); } catch(InvocationTargetException e) { throw new AddonException("Exception occurred while instantiating addon", e); } catch(NoSuchMethodException | IllegalAccessException | InstantiationException e) { diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/function/Functions.java b/common/api/src/main/java/com/dfsek/terra/api/util/function/Functions.java new file mode 100644 index 000000000..6ed541205 --- /dev/null +++ b/common/api/src/main/java/com/dfsek/terra/api/util/function/Functions.java @@ -0,0 +1,14 @@ +package com.dfsek.terra.api.util.function; + +import java.util.function.Function; + + +public final class Functions { + private Functions() { + + } + + public static Function constant(U value) { + return ignore -> value; + } +} diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/function/functor/Functor.java b/common/api/src/main/java/com/dfsek/terra/api/util/function/functor/Functor.java index f161ee09f..b514f6a1c 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/function/functor/Functor.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/function/functor/Functor.java @@ -3,6 +3,6 @@ package com.dfsek.terra.api.util.function.functor; import java.util.function.Function; -public interface Functor { - Functor map(Function map); +public interface Functor> { + Functor map(Function map); } diff --git a/common/api/src/main/java/com/dfsek/terra/api/util/function/monad/Monad.java b/common/api/src/main/java/com/dfsek/terra/api/util/function/monad/Monad.java index 1cf27a41e..10ab79c0d 100644 --- a/common/api/src/main/java/com/dfsek/terra/api/util/function/monad/Monad.java +++ b/common/api/src/main/java/com/dfsek/terra/api/util/function/monad/Monad.java @@ -1,8 +1,16 @@ package com.dfsek.terra.api.util.function.monad; +import com.dfsek.terra.api.util.function.functor.Functor; + import java.util.function.Function; -public interface Monad { - Monad bind(Function> map); +public interface Monad> extends Functor { + Monad bind(Function> map); + + default Monad map(Function fn) { + return bind(a -> pure(fn.apply(a))); + } + + Monad pure(U u); }