Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Creating FabricComputeCraftAPI with turtle/pocket upgrade serializer registration methods #1457

Closed
wants to merge 2 commits into from

Conversation

SirEdvin
Copy link
Contributor

So, this is continuation of #1432, specific turtle and pocket upgrade serializer API for registration, that will help get rid of postpone registration.

For now, due to postpone registration I am not able to have links to registered serializers in minecraft mod code and postpone registration a significant mess right now.

@SirEdvin
Copy link
Contributor Author

So, locally test passing, I am not sure why they failing in CI, probably related to #1373 or I just running test incorrect locally

@SquidDev SquidDev added enhancement An extension of a feature or a new feature. area-Minecraft This affects CC's Minecraft-specific content. labels May 30, 2023
@SquidDev
Copy link
Member

Thank you for looking at this! We hit this in Plethora a while back, and I bodged around it and forgot to look into handling this properly. CCing @Lemmmy here, as this change will probably affect you too.

So the original intent with the API was that by just exposing a ResourceKey, it would be easy to use with any registry system (vanilla's, Forge's DeferredRegistry, whatever multi-loader abstraction people are using).

I do feel a little eeeeeh about this change, as now it means the API is now different between mod loaders. There are some possible alternatives I can think of:

  • Replace TurtleUpgradeSerialiser.REGISTRY_ID with a TurtleUpgradeSerialiser.registryId() method. This behaves the same as the field access, but ensures the registry exists. I feel a little uneasy about this, as it means you're performing side effects in class initialisers (or getters), but plenty of other mods do that, so it's probably not the end of the world.

  • Add a custom Fabric entry point that other mods can hook into (much like JEI or modmenu do).
    This will be run during CC:T's init, so guarantees the registry exists.

    This could optionally be used for registering all CC-related functionality (so mods don't need to do if(isModLoaded("computercraft")) registerComputerCraft()), but that's less relevant for dedicated CC add-on mods :).

I don't really have any strong thoughts here - I don't maintain any CC add-ons after all, so happy to go with whatever folks think will be easiest, be that this PR or one of the other options!

@SirEdvin
Copy link
Contributor Author

SirEdvin commented May 30, 2023

I am not sure, if I did this correct or not, but even now registration for serializers is a little different between platforms, because as I understand, common approach for use registries in forge is to create mod-specific ones, like here, so I personally don't see any issue here.

So I still using reference for TurtleUpgradeSerialiser.REGISTRY_ID, but for multiloading env code is pretty much different and requires some xplat proxy wrapper.

@SquidDev
Copy link
Member

Yeah, I think that depends on how you deal with abstracting over registries in general. In CC:T, I use a DeferredRegistry-style pattern for both loaders, so turtle serialisers are just registered the same as any other block/item:

public static class TurtleSerialisers {
static final RegistrationHelper<TurtleUpgradeSerialiser<?>> REGISTRY = PlatformHelper.get().createRegistrationHelper(TurtleUpgradeSerialiser.REGISTRY_ID);
public static final RegistryEntry<TurtleUpgradeSerialiser<TurtleSpeaker>> SPEAKER =
REGISTRY.register("speaker", () -> TurtleUpgradeSerialiser.simpleWithCustomItem(TurtleSpeaker::new));
public static final RegistryEntry<TurtleUpgradeSerialiser<TurtleCraftingTable>> WORKBENCH =
REGISTRY.register("workbench", () -> TurtleUpgradeSerialiser.simpleWithCustomItem(TurtleCraftingTable::new));
public static final RegistryEntry<TurtleUpgradeSerialiser<TurtleModem>> WIRELESS_MODEM_NORMAL =
REGISTRY.register("wireless_modem_normal", () -> TurtleUpgradeSerialiser.simpleWithCustomItem((id, item) -> new TurtleModem(id, item, false)));
public static final RegistryEntry<TurtleUpgradeSerialiser<TurtleModem>> WIRELESS_MODEM_ADVANCED =
REGISTRY.register("wireless_modem_advanced", () -> TurtleUpgradeSerialiser.simpleWithCustomItem((id, item) -> new TurtleModem(id, item, true)));
public static final RegistryEntry<TurtleUpgradeSerialiser<TurtleTool>> TOOL = REGISTRY.register("tool", () -> TurtleToolSerialiser.INSTANCE);
}

@SirEdvin
Copy link
Contributor Author

I suppose, that for exposing registry() a lot of cross-platform internal code of CC:T need to be exposed as part of API, which doesn't seem to me as a good solution. Also, still, for Forge version, modder will still use DefferedRegistry not registry() from Serializer.

But for being able to mimic DefferedRegistry registry API pattern in common code I can suggest to make TURTLE_UPGRADE_SERIALISERS and POCKET_UPGRADE_SERIALISERS accessible from FabricAPI, so modder can decide which approach they what to use - registration functions or mimic registry wrapping with some extra logic.
In this case, registration function can be just removed.

@SquidDev
Copy link
Member

SquidDev commented Jun 3, 2023

Add a custom Fabric entry point that other mods can hook into (much like JEI or modmenu do).
This will be run during CC:T's init, so guarantees the registry exists.

I had a look at this, but I'm not convinced about this model. This means then you're calling the CC entrypoint before some mods have been initialised. This is is probably fine (most Fabric mods do half their work in static initialisers), but feels a little ugly too.

It is a bit sad really. I feel Fabric normally has a nicer API design than Forge, but I do prefer Forge's explicitness here.

Replace TurtleUpgradeSerialiser.REGISTRY_ID with a TurtleUpgradeSerialiser.registryId() method. This behaves the same as the field access, but ensures the registry exists.

This is the approach I ended up going with in f0abb83. This should mean you can replace REGISTRY_ID with .registryId() and things will Just Work:tm:.

@SquidDev SquidDev closed this Jun 3, 2023
@SirEdvin
Copy link
Contributor Author

SirEdvin commented Jun 3, 2023

Ah, this what you mean by registryId() function. Again my reading issues.
Thanks for resolving this!

@SquidDev
Copy link
Member

SquidDev commented Jun 3, 2023

Yeah, I don't think I explained that very well! I had a very clear image of what it'd look like in my head, but then explained the implementation rather than how it'd actually help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-Minecraft This affects CC's Minecraft-specific content. enhancement An extension of a feature or a new feature.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants