Skip to content

Conversation

@TheGlitch76
Copy link
Contributor

Goodbye, CHASM.

I'm probably going to keep hacking on this for a while, but I never know when I'll have time, so if this seems like an improvement over the status quo I'd like to get it merged.


This commit creates a TransformCache API that resembles the solver
plugin API. It currently is only used by the GameProvider. Mods can
not yet register their own transformers.

The idea behind this system is to make it so that there is no
privileged transform system in Loader: a modder could use Mixin, or
another lib like sushi--a sort of
spiritual successor to CHASM--or hand-roll patches with the new
ClassFile API, or whatever else. (this applies to using Loader for
other games too!)

It would also provide a convenient way for plugins to cache transformations
of mods they provide without needing to hand-roll their own system.

Some things to note:

  • The ergonomics for using the API is not great; see
    GameTransformerPlugin in the Minecraft game provider. It's not a goal
    to provide anything other than byte->byte transformation of files, but
    that doesn't mean the main API needs to be filesystem based.
  • There is a phase system copied directly from QSL, with the exception
    that cycles are an immediate crash.
    • The phases are sorted consistently, as long as the same
      transformers are registered they will run in the same order,
      regardless of mods loaded, load order, moon phase, etc.
    • I haven't figured out how I want the ergonomics of the default
      phases to work yet. That will probably be finalized once everything
      is on the cache, including cached mixin (fingers crossed!), and we
      let mods register plugins.

It's not happening. Sorry.

This is step 0 in making the Transform Cache available for
transformer plugins (as opposed to `GameProvider`/game plugins and
`QuiltLoaderPlugin`/solver plugins)
This commit creates a TransformCache API that resembles the solver
plugin API. It currently is only used by the GameProvider. Mods can
not yet register their own transformers.

The idea behind this system is to make it so that there is no
privileged transform system in Loader: a modder could use Mixin, or
another lib like [sushi](https://github.com/CichlidMC/sushi/)--a sort of
spiritual successor to CHASM--or hand-roll patches with the new
ClassFile API, or whatever else. (this applies to using Loader for
other games too!)

It would also provide a convient way for plugins to cache transformations
of mods they provide without needing to hand-roll their own system.

Some things to note:
- The egronomics for using the API is not great; see
GameTransformerPlugin in the Minecraft game provider. It's not a goal
to provide anything other than byte->byte transformation of files, but
that doesn't mean the main API needs to be filesystem based.
- There is a phase system copied directly from QSL, with the exception
that cycles are an immediate crash.
  - The phases are sorted consistently, as long as the same
	transformers are registered they will run in the same order,
	regardless of mods loaded, load order, moon phase, etc.
  - I haven't figured out how I want the ergonomics of the default
	phases to work yet. That will probably be finalized once everything
	is on the cache, including cached mixin (fingers crossed!), and we
	let mods register plugins.
Comment on lines +40 to +60
interface ClassConsumer {
/**
* Consume a class and potentially transform it.
*
* @param mod the mod which "owns" this class file
* @param className the name of the class in dot form (e.g. {@code net.minecraft.client.MinecraftClient$1}
* @return the transformed bytes, or null if nothing was changed. Use {@link TransformCache#hideClass(String, String)} to delete a class.
*/
byte @Nullable [] run(ModLoadOption mod, String className, Path file) throws IOException;
}

@FunctionalInterface
interface ModClassConsumer {
/**
* Consume a class and potentially transform it.
*
* @param className the name of the class in dot form (e.g. {@code net.minecraft.client.MinecraftClient$1}
* @return the transformed bytes, or null if nothing was changed. Use {@link TransformCache#hideClass(String, String)} to delete a class.
*/
byte @Nullable [] run(String className, Path file) throws IOException;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the difference between these two? Just a higher degree of specificity?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you are iterating over one mod you know what the load option is already, though I guess it might be worth leaving it to make using method references easier?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants