implement MonadAddonInitializer

This commit is contained in:
dfsek
2022-08-15 10:06:29 -07:00
parent 97854e3037
commit 0609a7cf6b
11 changed files with 206 additions and 38 deletions

View File

@@ -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()
));
}
}

View File

@@ -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();
}

View File

@@ -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> eventManager() {
return Init.of(initInfo -> initInfo.platform().getEventManager());
}
public static Init<BaseAddon> addon() {
return Init.of(InitInfo::addon);
}
public static Init<Platform> platform() {
return Init.of(InitInfo::platform);
}
}

View File

@@ -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<T> implements Monad<T, Init<?>> {
private final Function<InitInfo, T> get;
public static <T> Init<T> of(Function<InitInfo, T> get) {
return new Init<>(get);
}
private Init(Function<InitInfo, T> get) {
this.get = get;
}
public T apply(InitInfo platform) {
return get.apply(platform);
}
@Override
public <U> Init<U> bind(Function<T, Monad<U, Init<?>>> map) {
return new Init<>(info -> ((Init<U>) map.apply(apply(info))).apply(info));
}
@Override
public <U> Init<U> map(Function<T, U> fn) {
return (Init<U>) Monad.super.map(fn);
}
@Override
public <U> Monad<U, Init<?>> pure(U u) {
return of(Functions.constant(u));
}
}

View File

@@ -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
) {
}

View File

@@ -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<BaseAddon> addonInjector = Injector.get(info.addon());
addonInjector.addExplicitTarget(BaseAddon.class);
Injector<Platform> platformInjector = Injector.get(info.platform());
platformInjector.addExplicitTarget(Platform.class);
Injector<Logger> loggerInjector = Injector.get(LoggerFactory.getLogger(initializer.getClass()));
loggerInjector.addExplicitTarget(Logger.class);
addonInjector.inject(initializer);
platformInjector.inject(initializer);
loggerInjector.inject(initializer);
initializer.initialize();
}
}
}

View File

@@ -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<AddonInitializer> initializers;
private final List<Initializer> initializers;
@Inject
private Platform platform;
public ManifestAddon(AddonManifest manifest, List<AddonInitializer> initializers) {
public ManifestAddon(AddonManifest manifest, List<Initializer> initializers) {
this.manifest = manifest;
this.initializers = initializers;
}
@@ -45,23 +45,13 @@ public class ManifestAddon implements BaseAddon {
}
public void initialize() {
Injector<BaseAddon> addonInjector = Injector.get(this);
addonInjector.addExplicitTarget(BaseAddon.class);
Injector<Platform> platformInjector = Injector.get(platform);
platformInjector.addExplicitTarget(Platform.class);
logger.debug("Initializing addon {}", getID());
initializers.forEach(initializer -> {
Injector<Logger> 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));
});
}

View File

@@ -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<ManifestAddon> {
throw new AddonException("Addon " + manifest.getID() + " has unknown schema version: " + manifest.getSchemaVersion());
}
List<AddonInitializer> initializers = manifest.getEntryPoints().stream().map(entryPoint -> {
List<Initializer> 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) {

View File

@@ -0,0 +1,14 @@
package com.dfsek.terra.api.util.function;
import java.util.function.Function;
public final class Functions {
private Functions() {
}
public static <T, U> Function<T, U> constant(U value) {
return ignore -> value;
}
}

View File

@@ -3,6 +3,6 @@ package com.dfsek.terra.api.util.function.functor;
import java.util.function.Function;
public interface Functor<T> {
<U> Functor<U> map(Function<T, U> map);
public interface Functor<T, F extends Functor<?, F>> {
<U> Functor<U, F> map(Function<T, U> map);
}

View File

@@ -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<T> {
<U> Monad<U> bind(Function<T, Monad<U>> map);
public interface Monad<T, M extends Monad<?, M>> extends Functor<T, M> {
<U> Monad<U, M> bind(Function<T, Monad<U, M>> map);
default <U> Monad<U, M> map(Function<T, U> fn) {
return bind(a -> pure(fn.apply(a)));
}
<U> Monad<U, M> pure(U u);
}