-
Notifications
You must be signed in to change notification settings - Fork 1
Add textile-utils-api-v1 #3
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
base: modules
Are you sure you want to change the base?
Conversation
Bikeshed:tm: on new branch
BoogieMonster1O1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The id should definitely not be hardcoded
Registering blocks and items imo should be in registry sync as it would involve remapping the registry to match ids
| "package": "net.textilemc.textile.mixin.recipe", | ||
| "compatibilityLevel": "JAVA_8", | ||
| "mixins": [ | ||
| "RecipeDispatcherMixin" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops... left over from copying that module. Will fix.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
About the ID, would you figure out what is needed for that?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you mean about id? if you mean where it says id-256, that is what vanilla uses in the blockItem registry. See the bottom of the static constructor for Block.class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
He's talking about, that we have to hardcode an ID for our block and that would conflict with any other mod which uses the same ID. We need to use a registry sync so that isn't a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also adding blocks is gonna require batching into terrain.png
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A custom block class could be used to detect if and from where we need to draw from an external png rather than from terrain.png
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sschr15 should be adding a resource loader api, which would probably be something like `FabricLoader.getInstance().getModContainer("mymodid") + "/resources/blah.png"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There’s a lot of features in Block that require dehardcoding
Until there’s resource loader and texture api I’d suggest stalling
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe. Speak on discord in #github for quicker responses.
| @@ -0,0 +1,16 @@ | |||
| package net.textilemc.textile.utils; | |||
|
|
|||
| public class Pair<T, M> { | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn’t guava have Pair?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If not this should probably go in api base
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guava isn't an included library, so we can decide to keep our own, or use Guava here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Loader uses guava iirc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Huh? if it does, then could you ready up a commit for using that Pair instead?
| @@ -0,0 +1,2 @@ | |||
| accessWidener v1 named | |||
| accessible method net/minecraft/block/Block <init> (ILnet/minecraft/block/Material;)V | |||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary access widener
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That AW is necessary for Pair to function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really? It wasn't when I used it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh yeah, I was using a custom block class
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's because you instantiated your Block (Stone) class, I had to instantiate it as a Block as I don't want to hardcode it to be "Stone" or whatnot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is a Block access widener necessary
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps in the future write a more extensive api that has all modded blocks be instances of a FabricBlock, and thus all with same numerical id, but also have a unique String id, which is checked every time the numerical id is checked, but that would require many mixins to fix that, and that is probably later down the rodd
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Look at the top issue. I commented about some ways to do that.
| "environment": "*", | ||
| "accessWidener": "textile-utils-api-v1.accessWidener", | ||
| "mixins": [ | ||
| "textile-utils-api-v1.mixins.json" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn’t have any mixins
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, need to remove that as said before, leftover from copying module.
| version = '1.0.0' | ||
|
|
||
| dependencies { | ||
| implementation project(':textile-api-base') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unnecessary dependency
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is unnecessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually keep this but move Identifier to api base
sschr15
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clean up the listed Mixin-related problems and re-request a review, and I'll approve
Thanks to @amusingimpala for doing this.
BoogieMonster1O1
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, just a few extra changes
| } | ||
|
|
||
| minecraft { | ||
| accessWidener "src/main/resources/textile-utils-api-v1.accessWidener" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? We need to open up Block.id, Item.id and Block.BLOCKS from being final
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doesnt need an access widener
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I’m afraid I still don’t understand what you mean. Do you mean 1) that what is being widened is unnecessary, 2) that although it is needed for compilation it is not needed in production, or 3) something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it is not necessary to use an access widener here. accessors will suffice
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Accessors can modify final variables? I had forgotten that. Okay that makes sense then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. Adding a @Mutable does the trick
|
|
||
| @Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 1), method = "joinWorld(Ljava/lang/String;)V") | ||
| public void removeConflictOlderVersion(CallbackInfo info) { | ||
| mapBlockToDat(new File(new File(mcDir, "saves"), name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use nio
File is gonna block the thread
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mcDir.toPath().resolve("saves").resolve(name)
| return path; | ||
| } | ||
|
|
||
| public CompoundTag toTag(CompoundTag tag) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don’t need a CompoundTag for this. That just wastes bytes
Store it as a StringTag
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the use case of CompoundTag vs Tag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CompoundTag is a maplike tag
Tag is the base class for tags
| @Unique | ||
| private void mapBlockToDat(File saveDir) { | ||
| if (!(new File(saveDir, "block_registry.dat")).exists()) { | ||
| System.out.println("Saving Block Registry to .minecraft/saves/" + name + "/block_registry.dat"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use LOGGER.debug here
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If LOGGER doesn't exist (which it probably doesn't), just create a @Unique private static final Logger LOGGER. Also please (as the above comment says) use paths instead of File objects...
|
|
||
| public class RegistrationManagerEntrypoint implements ModInitializer { | ||
|
|
||
| public static Logger LOGGER = LogManager.getLogger("Textile API"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public static Logger LOGGER = LogManager.getLogger("Textile API"); | |
| public static Logger LOGGER = LogManager.getLogger("Textile Utils API"); |
|
imo since this basically only handles the registration of blocks, the module name should be |
|
I would agree with BoogieMonster, except for Identifier. That should stay in Util |
|
|
honestly anything made as a utility is either
|
|
I might also consider having the id retriever(s) throw a new ArrayOutOfBounds exceptions citing too many blocks if trying to register more than 256 total. |
sschr15
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although Minecraft itself couldn't possibly have used nio libraries, Fabric Loader does, so please use those. Also, Identifier serialization is strange, so I've requested changes there as well.
| @Unique | ||
| private void mapBlockToDat(File saveDir) { | ||
| if (!(new File(saveDir, "block_registry.dat")).exists()) { | ||
| System.out.println("Saving Block Registry to .minecraft/saves/" + name + "/block_registry.dat"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If LOGGER doesn't exist (which it probably doesn't), just create a @Unique private static final Logger LOGGER. Also please (as the above comment says) use paths instead of File objects...
| } | ||
|
|
||
| @Unique | ||
| private void mapBlockToDat(File saveDir) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Path saveDir
| } | ||
| @Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 2), method = "joinWorld(Ljava/lang/String;)V") | ||
| public void removeConflictOlderVersion2(CallbackInfo info) { | ||
| mapBlockToDat(new File(new File(mcDir, "saves"), name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mcDir.toPath().resolve("saves").resolve(name)
|
|
||
| @Inject(at=@At(value = "INVOKE", target = "Lnet/minecraft/client/MinecraftClient;joinWorld(Lnet/minecraft/world/World;Ljava/lang/String;)V", ordinal = 1), method = "joinWorld(Ljava/lang/String;)V") | ||
| public void removeConflictOlderVersion(CallbackInfo info) { | ||
| mapBlockToDat(new File(new File(mcDir, "saves"), name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
mcDir.toPath().resolve("saves").resolve(name)
|
|
||
| @Unique | ||
| private void mapBlockToDat(File saveDir) { | ||
| if (!(new File(saveDir, "block_registry.dat")).exists()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
!Files.exists(saveDir.resolve("block_registry.dat"))
| } | ||
| } | ||
| try { | ||
| Util.writeCompressed(tag, new FileOutputStream(new File(saveDir, "block_registry.dat"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Files.newOutputStream(saveDir.resolve("block_registry.dat")
| System.out.println("Matching old Block Registry read from .minecraft/saves/"+name+"/block_registry.dat"); | ||
| CompoundTag tagFromFile; | ||
| try { | ||
| tagFromFile = Util.readCompressed(new FileInputStream(new File(saveDir, "block_registry.dat"))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Files.newInputStream(saveDir.resolve("block_registry.dat")
| } | ||
| } | ||
| } | ||
| throw new NullPointerException("Could not find block! You should only see this if you removed the mod which it was in, in which case your world will have corrupted!! Please make a new World!!"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps don't throw an NPE, instead send a message to the player on world load to tell the player that a block may be missing?
| public CompoundTag toTag(CompoundTag tag) { | ||
| CompoundTag subtag = new CompoundTag(); | ||
| subtag.putString("namespace", this.getNamespace()); | ||
| subtag.putString("path", this.getPath()); | ||
| tag.put("nameId", subtag); | ||
| return tag; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| public CompoundTag toTag(CompoundTag tag) { | |
| CompoundTag subtag = new CompoundTag(); | |
| subtag.putString("namespace", this.getNamespace()); | |
| subtag.putString("path", this.getPath()); | |
| tag.put("nameId", subtag); | |
| return tag; | |
| public CompoundTag toTag(CompoundTag tag) { | |
| tag.putString("nameId", this.getNamespace() + ':' + this.getPath()); | |
| return tag; |
| public static Identifier fromTag(CompoundTag tag) { | ||
| return new Identifier(tag.getString("namespace"), tag.getString("path")); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
According to the toTag method just above, you save this to a nameId entry. You should then retrieve the identifier the same way.
| public static Identifier fromTag(CompoundTag tag) { | |
| return new Identifier(tag.getString("namespace"), tag.getString("path")); | |
| } | |
| public static Identifier fromTag(CompoundTag tag) { | |
| String[] value = tag.getString("nameId").split(":"); | |
| return new Identifier(value[0], value[1]); | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
serialization should not be done directly to a compound tag. nameId sounds weird.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in fact, the compound tags in fromTag and toTag are meant to be of that object, so the only data you read is the data you’ve serialized
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and since Identifiers don’t use compound tags anymore, this should just be a toString and a tryParse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(so that the caller can choose any key name and so as to not violate the method contract)
Bikeshed:tm: on new branch