From 4e152e57054a6093f3aa924390b16a9f4e48c732 Mon Sep 17 00:00:00 2001 From: KrLite <68179735+KrLite@users.noreply.github.com> Date: Tue, 12 Mar 2024 19:03:06 +0800 Subject: [PATCH] entrypoint invoker --- .../krlite/knowledges/KnowledgesClient.java | 55 ++++++----- .../krlite/knowledges/KnowledgesCommon.java | 22 +++-- .../net/krlite/knowledges/KnowledgesHud.java | 3 +- .../impl/BlockRepresentableImpl.java | 2 +- .../impl/EntityRepresentableImpl.java | 2 +- .../config/KnowledgesClientConfig.java | 4 +- .../config/KnowledgesCommonConfig.java | 6 +- ...pl.java => BlockContractProviderImpl.java} | 2 +- ...l.java => EntityContractProviderImpl.java} | 6 +- .../knowledges/manager/ComponentManager.java | 2 +- .../knowledges/manager/ContractManager.java | 2 +- .../knowledges/manager/DataManager.java | 2 +- .../manager/base/EntrypointInvoker.java | 93 +++++++++++++++++++ .../networking/ClientNetworking.java | 9 ++ src/main/resources/fabric.mod.json | 8 +- 15 files changed, 162 insertions(+), 56 deletions(-) rename src/main/java/net/krlite/knowledges/impl/entrypoint/contract/{ContractProviderImpl.java => BlockContractProviderImpl.java} (89%) rename src/main/java/net/krlite/knowledges/impl/entrypoint/contract/{AdditionalEntityTagProviderImpl.java => EntityContractProviderImpl.java} (64%) create mode 100644 src/main/java/net/krlite/knowledges/manager/base/EntrypointInvoker.java diff --git a/src/main/java/net/krlite/knowledges/KnowledgesClient.java b/src/main/java/net/krlite/knowledges/KnowledgesClient.java index 3c96859..e93e925 100644 --- a/src/main/java/net/krlite/knowledges/KnowledgesClient.java +++ b/src/main/java/net/krlite/knowledges/KnowledgesClient.java @@ -6,21 +6,18 @@ import me.shedaniel.autoconfig.serializer.Toml4jConfigSerializer; import net.fabricmc.api.ClientModInitializer; import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents; -import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback; -import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.loader.api.FabricLoader; import net.fabricmc.loader.api.ModContainer; import net.krlite.knowledges.api.entrypoint.ComponentProvider; import net.krlite.knowledges.api.entrypoint.DataProvider; -import net.krlite.knowledges.api.representable.PacketByteBufWritable; import net.krlite.knowledges.config.KnowledgesClientConfig; import net.krlite.knowledges.impl.component.base.InfoComponent; import net.krlite.knowledges.manager.ComponentManager; import net.krlite.knowledges.manager.DataManager; +import net.krlite.knowledges.manager.base.EntrypointInvoker; import net.krlite.knowledges.manager.base.Manager; import net.krlite.knowledges.networking.ClientNetworking; -import net.minecraft.network.PacketByteBuf; import net.minecraft.text.MutableText; import net.minecraft.text.Text; import net.minecraft.util.ActionResult; @@ -31,7 +28,7 @@ import static net.krlite.knowledges.api.core.localization.Localizable.Separator.KEY; public class KnowledgesClient implements ClientModInitializer { - public static final Logger LOGGER = LoggerFactory.getLogger(KnowledgesCommon.ID + ":client"); + public static final Logger LOGGER = LoggerFactory.getLogger(KnowledgesCommon.ID + "-client"); public static final ConfigHolder CONFIG; public static final KnowledgesClientConfig DEFAULT_CONFIG = new KnowledgesClientConfig(); @@ -41,8 +38,8 @@ public class KnowledgesClient implements ClientModInitializer { CONFIG = AutoConfig.getConfigHolder(KnowledgesClientConfig.class); CONFIG.registerLoadListener((configHolder, knowledgesClientConfig) -> { - Manager.fixKeysAndSort(knowledgesClientConfig.components.enabled); - Manager.fixKeysAndSort(knowledgesClientConfig.data.enabled); + Manager.fixKeysAndSort(knowledgesClientConfig.components.available); + Manager.fixKeysAndSort(knowledgesClientConfig.data.available); return ActionResult.PASS; }); @@ -53,29 +50,18 @@ public class KnowledgesClient implements ClientModInitializer { public static final KnowledgesHud HUD = new KnowledgesHud(); - public static Identifier identifier(String path) { - return new Identifier(KnowledgesCommon.ID, path); - } - - public static String localizationKey(String category, String... paths) { - return category + KEY + KnowledgesCommon.ID + KEY + String.join(KEY.toString(), paths); - } - - public static MutableText localize(String category, String... paths) { - return Text.translatable(localizationKey(category, paths)); - } - @Override public void onInitializeClient() { - Manager.fixKeysAndSort(CONFIG.get().components.enabled); - Manager.fixKeysAndSort(CONFIG.get().data.enabled); + Manager.fixKeysAndSort(CONFIG.get().components.available); + Manager.fixKeysAndSort(CONFIG.get().data.available); InfoComponent.Animation.registerEvents(); new ClientNetworking().register(); + /* // Components FabricLoader.getInstance().getEntrypointContainers(KnowledgesCommon.ID, ComponentProvider.class).forEach(entrypoint -> { - ComponentProvider provider = entrypoint.getEntrypoint(); + ComponentProvider provider = entrypoint.getEntrypoint(); var classes = provider.provide(); if (classes.isEmpty()) return; @@ -106,7 +92,7 @@ public void onInitializeClient() { // Data FabricLoader.getInstance().getEntrypointContainers(KnowledgesCommon.ID + ":data", DataProvider.class).forEach(entrypoint -> { - DataProvider provider = entrypoint.getEntrypoint(); + DataProvider provider = entrypoint.getEntrypoint(); var classes = provider.provide(); if (classes.isEmpty()) return; @@ -135,6 +121,11 @@ public void onInitializeClient() { .forEach(data -> DATA.register(namespace, data)); }); + */ + + EntrypointInvoker.COMPONENT.invoke(COMPONENTS::register); + EntrypointInvoker.DATA.invoke(DATA::register); + tidyUpConfig(); CONFIG.save(); @@ -162,16 +153,22 @@ public void onInitializeClient() { })); } + public static Identifier identifier(String path) { + return new Identifier(KnowledgesCommon.ID, path); + } + + public static String localizationKey(String category, String... paths) { + return category + KEY + KnowledgesCommon.ID + KEY + String.join(KEY.toString(), paths); + } + + public static MutableText localize(String category, String... paths) { + return Text.translatable(localizationKey(category, paths)); + } + public static void tidyUpConfig() { if (CONFIG.get().components.autoTidiesUp) COMPONENTS.tidyUp(); if (CONFIG.get().data.autoTidiesUp) DATA.tidyUp(); } - - public static void requestDataFor(PacketByteBufWritable writable, Identifier channel) { - PacketByteBuf buf = PacketByteBufs.create(); - writable.writeToBuf(buf); - ClientPlayNetworking.send(channel, buf); - } } diff --git a/src/main/java/net/krlite/knowledges/KnowledgesCommon.java b/src/main/java/net/krlite/knowledges/KnowledgesCommon.java index 709f8e9..a439d55 100644 --- a/src/main/java/net/krlite/knowledges/KnowledgesCommon.java +++ b/src/main/java/net/krlite/knowledges/KnowledgesCommon.java @@ -10,6 +10,7 @@ import net.krlite.knowledges.api.entrypoint.ContractProvider; import net.krlite.knowledges.config.KnowledgesCommonConfig; import net.krlite.knowledges.config.modmenu.cache.UsernameCache; +import net.krlite.knowledges.manager.base.EntrypointInvoker; import net.krlite.knowledges.manager.base.Manager; import net.krlite.knowledges.manager.ContractManager; import net.krlite.knowledges.networking.ServerNetworking; @@ -19,7 +20,7 @@ public class KnowledgesCommon implements ModInitializer { public static final String NAME = "Knowledges", ID = "knowledges"; - public static final Logger LOGGER = LoggerFactory.getLogger(ID + ":common"); + public static final Logger LOGGER = LoggerFactory.getLogger(ID); public static final ConfigHolder CONFIG; @@ -30,13 +31,13 @@ public class KnowledgesCommon implements ModInitializer { CONFIG = AutoConfig.getConfigHolder(KnowledgesCommonConfig.class); CONFIG.registerLoadListener((configHolder, knowledgesCommonConfig) -> { - Manager.fixKeysAndSort(knowledgesCommonConfig.tags.enabled); + Manager.fixKeysAndSort(knowledgesCommonConfig.contracts.available); return ActionResult.PASS; }); } - public static final ContractManager TAGS = new ContractManager(); + public static final ContractManager CONTRACTS = new ContractManager(); public static final UsernameCache CACHE_USERNAME = new UsernameCache(); @@ -44,13 +45,14 @@ public class KnowledgesCommon implements ModInitializer { public void onInitialize() { CACHE_USERNAME.load(); - Manager.fixKeysAndSort(CONFIG.get().tags.enabled); + Manager.fixKeysAndSort(CONFIG.get().contracts.available); new ServerNetworking().register(); + /* // Tags FabricLoader.getInstance().getEntrypointContainers(ID + ":tags", ContractProvider.class).forEach(entrypoint -> { - ContractProvider provider = entrypoint.getEntrypoint(); + ContractProvider provider = entrypoint.getEntrypoint(); var classes = provider.provide(); if (classes.isEmpty()) return; @@ -60,7 +62,7 @@ public void onInitialize() { LOGGER.info(String.format( "Registering %d %s for %s...", classes.size(), - classes.size() <= 1 ? "tag" : "tags", + classes.size() <= 1 ? "contract" : "contracts", name )); @@ -76,14 +78,18 @@ public void onInitialize() { ), throwable); } }) - .forEach(tag -> TAGS.register(namespace, tag)); + .forEach(tag -> CONTRACTS.register(namespace, tag)); }); + */ + + EntrypointInvoker.CONTRACT.invoke(CONTRACTS::register); + tidyUpConfig(); CONFIG.save(); } public static void tidyUpConfig() { - TAGS.tidyUp(); + CONTRACTS.tidyUp(); } } diff --git a/src/main/java/net/krlite/knowledges/KnowledgesHud.java b/src/main/java/net/krlite/knowledges/KnowledgesHud.java index 03ab413..4dcce79 100644 --- a/src/main/java/net/krlite/knowledges/KnowledgesHud.java +++ b/src/main/java/net/krlite/knowledges/KnowledgesHud.java @@ -8,6 +8,7 @@ import net.krlite.knowledges.api.representable.impl.BlockRepresentableImpl; import net.krlite.knowledges.api.representable.impl.EntityRepresentableImpl; import net.krlite.knowledges.mixin.client.InGameHudInvoker; +import net.krlite.knowledges.networking.ClientNetworking; import net.krlite.knowledges.networking.base.KnowledgesNetworking; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.DrawContext; @@ -123,7 +124,7 @@ public void tick(MinecraftClient client) { } if (channel != null) { - KnowledgesClient.requestDataFor(representable, channel); + ClientNetworking.requestDataFor(representable, channel); } } } diff --git a/src/main/java/net/krlite/knowledges/api/representable/impl/BlockRepresentableImpl.java b/src/main/java/net/krlite/knowledges/api/representable/impl/BlockRepresentableImpl.java index a3ac502..051025d 100644 --- a/src/main/java/net/krlite/knowledges/api/representable/impl/BlockRepresentableImpl.java +++ b/src/main/java/net/krlite/knowledges/api/representable/impl/BlockRepresentableImpl.java @@ -68,7 +68,7 @@ public static void onRequest(PacketByteBuf buf, ServerPlayerEntity player, Consu Optional blockEntity = representable.blockEntity(); if (blockEntity.isEmpty()) return; - var tags = KnowledgesCommon.TAGS.byBlock(representable.block()); + var tags = KnowledgesCommon.CONTRACTS.byBlock(representable.block()); if (tags.isEmpty()) return; NbtCompound compound = representable.data(); diff --git a/src/main/java/net/krlite/knowledges/api/representable/impl/EntityRepresentableImpl.java b/src/main/java/net/krlite/knowledges/api/representable/impl/EntityRepresentableImpl.java index 37c3c94..e6e03aa 100644 --- a/src/main/java/net/krlite/knowledges/api/representable/impl/EntityRepresentableImpl.java +++ b/src/main/java/net/krlite/knowledges/api/representable/impl/EntityRepresentableImpl.java @@ -35,7 +35,7 @@ public static void onRequest(PacketByteBuf buf, ServerPlayerEntity player, Consu Entity entity = representable.entity(); if (entity == null) return; - var tags = KnowledgesCommon.TAGS.byEntity(representable.entity()); + var tags = KnowledgesCommon.CONTRACTS.byEntity(representable.entity()); if (tags.isEmpty()) return; NbtCompound compound = representable.data(); diff --git a/src/main/java/net/krlite/knowledges/config/KnowledgesClientConfig.java b/src/main/java/net/krlite/knowledges/config/KnowledgesClientConfig.java index 6a59ae9..3f39783 100644 --- a/src/main/java/net/krlite/knowledges/config/KnowledgesClientConfig.java +++ b/src/main/java/net/krlite/knowledges/config/KnowledgesClientConfig.java @@ -90,7 +90,7 @@ public static class InfoFluid { public boolean ignoresOtherFluids = false; } - public Map enabled = new TreeMap<>(); + public Map available = new TreeMap<>(); } @Config(name = "data") @@ -104,6 +104,6 @@ public static class NoteBlockInformation { public NoteBlockInformationData.MusicalAlphabet musicalAlphabet = NoteBlockInformationData.MusicalAlphabet.ENGLISH; } - public Map enabled = new TreeMap<>(); + public Map available = new TreeMap<>(); } } diff --git a/src/main/java/net/krlite/knowledges/config/KnowledgesCommonConfig.java b/src/main/java/net/krlite/knowledges/config/KnowledgesCommonConfig.java index 61e3bb7..091d1e5 100644 --- a/src/main/java/net/krlite/knowledges/config/KnowledgesCommonConfig.java +++ b/src/main/java/net/krlite/knowledges/config/KnowledgesCommonConfig.java @@ -9,12 +9,12 @@ @Config(name = "knowledges") public class KnowledgesCommonConfig extends PartitioningSerializer.GlobalData{ - public Tags tags = new Tags(); + public Tags contracts = new Tags(); - @Config(name = "tags") + @Config(name = "contracts") public static class Tags implements ConfigData { public boolean autoTidiesUp = false; - public Map enabled = new TreeMap<>(); + public Map available = new TreeMap<>(); } } diff --git a/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/ContractProviderImpl.java b/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/BlockContractProviderImpl.java similarity index 89% rename from src/main/java/net/krlite/knowledges/impl/entrypoint/contract/ContractProviderImpl.java rename to src/main/java/net/krlite/knowledges/impl/entrypoint/contract/BlockContractProviderImpl.java index 895c65f..babcca5 100644 --- a/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/ContractProviderImpl.java +++ b/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/BlockContractProviderImpl.java @@ -8,7 +8,7 @@ import java.util.List; -public class ContractProviderImpl implements BlockContract.Provider { +public class BlockContractProviderImpl implements BlockContract.Provider { @Override public @NotNull List> provide() { return List.of( diff --git a/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/AdditionalEntityTagProviderImpl.java b/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/EntityContractProviderImpl.java similarity index 64% rename from src/main/java/net/krlite/knowledges/impl/entrypoint/contract/AdditionalEntityTagProviderImpl.java rename to src/main/java/net/krlite/knowledges/impl/entrypoint/contract/EntityContractProviderImpl.java index e5ae96b..9c6d2ac 100644 --- a/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/AdditionalEntityTagProviderImpl.java +++ b/src/main/java/net/krlite/knowledges/impl/entrypoint/contract/EntityContractProviderImpl.java @@ -1,15 +1,15 @@ package net.krlite.knowledges.impl.entrypoint.contract; -import net.krlite.knowledges.api.contract.AdditionalEntityTag; +import net.krlite.knowledges.api.contract.EntityContract; import net.krlite.knowledges.impl.contract.entity.AnimalOwnerContract; import net.krlite.knowledges.impl.contract.entity.ChickenEggContract; import org.jetbrains.annotations.NotNull; import java.util.List; -public class AdditionalEntityTagProviderImpl implements AdditionalEntityTag.Provider { +public class EntityContractProviderImpl implements EntityContract.Provider { @Override - public @NotNull List> provide() { + public @NotNull List> provide() { return List.of( AnimalOwnerContract.class, ChickenEggContract.class diff --git a/src/main/java/net/krlite/knowledges/manager/ComponentManager.java b/src/main/java/net/krlite/knowledges/manager/ComponentManager.java index d7c297e..8f9cd32 100644 --- a/src/main/java/net/krlite/knowledges/manager/ComponentManager.java +++ b/src/main/java/net/krlite/knowledges/manager/ComponentManager.java @@ -8,7 +8,7 @@ public class ComponentManager extends Manager { public ComponentManager() { - super(() -> KnowledgesClient.CONFIG.get().components.enabled); + super(() -> KnowledgesClient.CONFIG.get().components.available); } public void render(RenderProxy renderProxy, Representable representable) { diff --git a/src/main/java/net/krlite/knowledges/manager/ContractManager.java b/src/main/java/net/krlite/knowledges/manager/ContractManager.java index a309570..caac8ea 100644 --- a/src/main/java/net/krlite/knowledges/manager/ContractManager.java +++ b/src/main/java/net/krlite/knowledges/manager/ContractManager.java @@ -12,7 +12,7 @@ public class ContractManager extends Manager> { public ContractManager() { - super(() -> KnowledgesCommon.CONFIG.get().tags.enabled); + super(() -> KnowledgesCommon.CONFIG.get().contracts.available); } @Override diff --git a/src/main/java/net/krlite/knowledges/manager/DataManager.java b/src/main/java/net/krlite/knowledges/manager/DataManager.java index 2a4fe44..7035e1e 100644 --- a/src/main/java/net/krlite/knowledges/manager/DataManager.java +++ b/src/main/java/net/krlite/knowledges/manager/DataManager.java @@ -14,7 +14,7 @@ public class DataManager extends Manager> { public DataManager() { - super(() -> KnowledgesClient.CONFIG.get().data.enabled); + super(() -> KnowledgesClient.CONFIG.get().data.available); } @Override diff --git a/src/main/java/net/krlite/knowledges/manager/base/EntrypointInvoker.java b/src/main/java/net/krlite/knowledges/manager/base/EntrypointInvoker.java new file mode 100644 index 0000000..70e7980 --- /dev/null +++ b/src/main/java/net/krlite/knowledges/manager/base/EntrypointInvoker.java @@ -0,0 +1,93 @@ +package net.krlite.knowledges.manager.base; + +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.ModContainer; +import net.krlite.knowledges.KnowledgesCommon; +import net.krlite.knowledges.api.core.localization.Localizable; +import net.krlite.knowledges.api.entrypoint.ComponentProvider; +import net.krlite.knowledges.api.entrypoint.ContractProvider; +import net.krlite.knowledges.api.entrypoint.DataProvider; +import net.krlite.knowledges.api.entrypoint.base.Provider; + +import java.util.function.BiConsumer; + +public enum EntrypointInvoker { + COMPONENT(true, ComponentProvider.class, "component"), + DATA(true, DataProvider.class, "data", "data", "data"), + CONTRACT(false, ContractProvider.class, "contract"); + + @FunctionalInterface + interface Registerable> { + BiConsumer consumer(); + + default void register(EntrypointInvoker invoker, Class clazz) { + FabricLoader.getInstance().getEntrypointContainers(invoker.entrypointPath(), clazz).forEach(entrypoint -> { + T provider = entrypoint.getEntrypoint(); + var classes = provider.provide(); + if (classes.isEmpty()) return; + + ModContainer mod = entrypoint.getProvider(); + String namespace = mod.getMetadata().getId(), name = mod.getMetadata().getName(); + + KnowledgesCommon.LOGGER.info(String.format( + "Registering %d %s for %s...", + classes.size(), + classes.size() <= 1 ? invoker.single : invoker.plural, + name + )); + + classes.stream() + .distinct() + .map(c -> { + try { + return (T) c.getDeclaredConstructor().newInstance(); + } catch (Throwable throwable) { + throw new RuntimeException(String.format( + "Failed to register %s for %s: constructor not found!", + invoker.single, + c.getName() + ), throwable); + } + }) + .forEach(t -> consumer().accept(namespace, t)); + }); + } + } + + private final boolean isClientSide; + private final String path; + private final String single, plural; + private final Class clazz; + + EntrypointInvoker(boolean isClientSide, Class clazz, String path, String single, String plural) { + this.isClientSide = isClientSide; + this.clazz = clazz; + this.path = path; + this.single = single; + this.plural = plural; + } + + EntrypointInvoker(boolean isClientSide, Class clazz, String path) { + this(isClientSide, clazz, path, path, path + "s"); + } + + public String path() { + return path; + } + + public String entrypointPath() { + return KnowledgesCommon.ID + Localizable.Separator.REALM + path(); + } + + public boolean isClientSide() { + return isClientSide; + } + + public > void invoke(BiConsumer consumer) { + try { + ((Registerable) () -> consumer).register(this, (Class) clazz); + } catch (Exception e) { + KnowledgesCommon.LOGGER.error("Failed invoking register methods for class {}!", clazz); + } + } +} diff --git a/src/main/java/net/krlite/knowledges/networking/ClientNetworking.java b/src/main/java/net/krlite/knowledges/networking/ClientNetworking.java index af88c46..a4799f9 100644 --- a/src/main/java/net/krlite/knowledges/networking/ClientNetworking.java +++ b/src/main/java/net/krlite/knowledges/networking/ClientNetworking.java @@ -2,15 +2,24 @@ import net.fabricmc.fabric.api.client.networking.v1.ClientPlayConnectionEvents; import net.fabricmc.fabric.api.client.networking.v1.ClientPlayNetworking; +import net.fabricmc.fabric.api.networking.v1.PacketByteBufs; import net.fabricmc.fabric.api.networking.v1.PacketSender; import net.krlite.knowledges.KnowledgesClient; +import net.krlite.knowledges.api.representable.PacketByteBufWritable; import net.krlite.knowledges.networking.base.KnowledgesNetworking; import net.minecraft.client.MinecraftClient; import net.minecraft.client.network.ClientPlayNetworkHandler; import net.minecraft.nbt.NbtCompound; import net.minecraft.network.PacketByteBuf; +import net.minecraft.util.Identifier; public class ClientNetworking implements KnowledgesNetworking { + public static void requestDataFor(PacketByteBufWritable writable, Identifier channel) { + PacketByteBuf buf = PacketByteBufs.create(); + writable.writeToBuf(buf); + ClientPlayNetworking.send(channel, buf); + } + @Override public void register() { ClientPlayNetworking.registerGlobalReceiver(KnowledgesNetworking.PACKET_RECEIVE_DATA, new ReceiveData()); diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index d8ca771..48b8a71 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -28,15 +28,15 @@ "modmenu": [ "net.krlite.knowledges.config.modmenu.KnowledgesModMenuImpl" ], - "knowledges": [ + "knowledges:component": [ "net.krlite.knowledges.impl.entrypoint.ComponentProviderImpl" ], "knowledges:data": [ "net.krlite.knowledges.impl.entrypoint.DataProviderImpl" ], - "knowledges:tags": [ - "net.krlite.knowledges.impl.entrypoint.tag.ContractProviderImpl", - "net.krlite.knowledges.impl.entrypoint.tag.AdditionalEntityTagProviderImpl" + "knowledges:contract": [ + "net.krlite.knowledges.impl.entrypoint.contract.BlockContractProviderImpl", + "net.krlite.knowledges.impl.entrypoint.contract.EntityContractProviderImpl" ] }, "mixins": [