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

String → Identifier #238

Closed
wants to merge 13 commits into from
Closed

String → Identifier #238

wants to merge 13 commits into from

Conversation

ExE-Boss
Copy link
Member

@ExE-Boss ExE-Boss commented Jan 7, 2017

@SoniEx2 has pretty much abandoned his PR, so I’m taking over.
For a detailed description of what this does, see #227.

To do list:

  • Get rid of String serialization.
  • Redesign this whole thing from scratch. (Seriously, the current implementation is very bloated)
    • Get rid of IdentifierFactory (or whatever I called it) and replace it with the Storable interface.

Completed:

  • Implement StringIdentifier, ClassIdentifier and UUIDIdentifier (SoniEx2)
  • Implement NamespacedStringIdentifier and EnumIdentifier
    • IDs can’t be null. That throws a NullPointerException.
  • Switch Core to use Identifier everywhere
    • Currently kept an implicit StringStringIdentifier method in FactoryManager
      Should we keep it or not?
  • Write tests
  • Fix wrappers
    • Test in Minecraft 1.7 and 1.8

Closes #227

@ExE-Boss ExE-Boss added breaking change This is going to break stuff in progress Pull requests that are not yet ready to be merged and issues that are being worked on. labels Jan 7, 2017
@ExE-Boss ExE-Boss added this to the v0.1.0 milestone Jan 7, 2017
@ExE-Boss ExE-Boss self-assigned this Jan 7, 2017
@codecov-io
Copy link

codecov-io commented Jan 7, 2017

Current coverage is 14.26% (diff: 28.48%)

Merging #238 into master will decrease coverage by 0.01%

@@             master       #238   diff @@
==========================================
  Files           393        398     +5   
  Lines         10984      11076    +92   
  Methods           0          0          
  Messages          0          0          
  Branches       1580       1585     +5   
==========================================
+ Hits           1569       1580    +11   
- Misses         9329       9405    +76   
- Partials         86         91     +5   

Powered by Codecov. Last update fc4146f...16cf3a9

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

null IDs?!

You may disagree but I believe this thing should NPE everywhere.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

You need to learn how to use a damn immutable object.

And a constructor for such an immutable object.

@ExE-Boss ExE-Boss requested a review from RX14 January 8, 2017 05:33
@Victorious3
Copy link
Contributor

Victorious3 commented Jan 8, 2017

Ive yet to understand why you'd need these. Interned strings are enough of an identifier to me...

You know, something like this:

interface Identifier {
    public static String of(String str) { return String.intern(str); }
    public static String of(UUID uuid) { return String.intern(uuid.toString()); }
    public static String of(Class<?> clazz) { return String.intern(clazz.getName()); }
}

Or if you don't like this because of the pitfall that you have to call Identifier.of() to make sure that it is an interned String...

class Identifier {
    private String interned;
    private Identifier(String id) { this.interned = String.intern(id); }

    @Override
    public boolean equals(Object o) {
        // Look at how simple equality becomes
        if (o instanceof Identifier) 
            return ((Identifier)o).interned == this.interned;
        return false;
    }

    @Override
    public int hashCode() { return interned.hashCode(); }

    public static Identifier of(String str) { return new Identifier(str); }
    public static Identifier of(UUID uuid) { return new Identifier(uuid.toString()); }
    public static Identifier of(Class<?> clazz) { return new Identifier(clazz.getName()); }
}

Downside of that is that you can't compare them with == but that's otherwise "normal" in java anyways. Forget about all of that "serializing back to specific Identifier type" crud. Calling Class.forName or UUID.fromString respectively should be enough to expect of someone to do, if really needed. Not once have I seen such a case so far. What you do here is excessive over-engineering.

@Override
public abstract boolean equals(Object other);

protected static final <T extends Identifier> boolean equalsImpl(Identifier _this, Object other, Class<T> superclass, Function<T,Object> getter) {
Copy link
Contributor

Choose a reason for hiding this comment

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

self instead of _this? Is there a convention on this like clazz?

Copy link
Member Author

Choose a reason for hiding this comment

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

Done now.

/**
* @author ExE Boss
*/
public enum EnumExample {
Copy link
Contributor

Choose a reason for hiding this comment

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

This change shouldn't be in this PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

This change was done to allow testing of EnumIdentifier using my EnumExample class.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, okay.

@RX14
Copy link
Contributor

RX14 commented Jan 8, 2017

@Victorious3 wouldn't interned strings technically work with ==? I wouldn't recommend it because it might be a bit flakey but if they are interned shouldn't they be the "same" string.

@Victorious3
Copy link
Contributor

Victorious3 commented Jan 8, 2017

@RX14 Yes they do see my 0815 implementation. Hence why I said interned strings are all you need for identifers. And

Identifier.of("foo") == Identifier.of(new String(new char[] {'f', 'o', 'o'})));

Not if you go with the simple wrapper class approach tho. Which is more safe because you wont accidentally forget to call Identifier.of somewhere

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

@Victorious3 The issue is Identifier.of("net.minecraft.block.Block") == Identifier.of(net.minecraft.block.Block.class). That should NEVER be able to happen.

BUT OTHER THAN THAT, THEY SHOULD ACT LIKE THE String CLASS: THEY SHOULD BE IMMUTABLE. Imagine you have an Identifier in 20 different places, including hashmap keys and stuff, then you accidentally call .load() on it. For one it'd break the hashmap contract. And it's just plain insane!

@ExE-Boss Could you at least TALK TO ME ABOUT IT before doing something completely messed up?!

@RX14
Copy link
Contributor

RX14 commented Jan 8, 2017

@SoniEx2 How about you calm the fuck down and suggest improvements nicely instead of shouting at people. It won't make them take your input more seriously.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

@RX14 I'll happily shout at someone who's touching code I wrote without any idea of what the code should do.

@RX14
Copy link
Contributor

RX14 commented Jan 8, 2017

@SoniEx2 Well, if you keep doing it you won't be commenting on this issue tracker any more. You talk nicely or don't talk at all.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

@RX14 Fine.

Part of the reason I made the PR was so I could put different kinds of identifiers in the same HashMap without having them conflict. Something I couldn't do with strings.

A NamespacedStringIdentifier should contain an inner static class called NamespacedStringData, and that class should be used as the identifier type. The equals and hashCode methods should be final, since otherwise equals wouldn't be symmetric. This is also why we can't/shouldn't have null IDs.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

And string is useless for older Minecraft versions.

@Victorious3
Copy link
Contributor

@SoniEx2 This is Nova CORE it doesn't CARE about "Minecraft Versions"

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

And the Minecraft wrappers are directly integrated into NOVA Core (kinda why they're in the same repo instead of being in their own repos).

@Victorious3
Copy link
Contributor

@SoniEx2 If you manage to name one problem that this overbloated PR supposedly solves, then go for it. You are shooting with cannons at ants. I'm for simplicity and ease of use and things like NamespacedStringIdentifier certainly don`t fall into that category.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

Please make Mojang remove Minecraft's ResourceLocation. It's bloated.

@Victorious3
Copy link
Contributor

@SoniEx2 Besides this being completely off point, ResourceLocation is NOT an identifier. It serves the purpose of being able to locate files within the jar or resource packs which use completely different file paths.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

@Victorious3 It is actually NO different from a NamespacedStringIdentifier. It identifies block names, item names, etc.

@Victorious3
Copy link
Contributor

@SoniEx2 You are impossible to talk to. Closed until further notice from @ExE-Boss

@Victorious3 Victorious3 closed this Jan 8, 2017
@RX14 RX14 removed the in progress Pull requests that are not yet ready to be merged and issues that are being worked on. label Jan 8, 2017
@RX14 RX14 reopened this Jan 8, 2017
@RX14 RX14 added the in progress Pull requests that are not yet ready to be merged and issues that are being worked on. label Jan 8, 2017
@RX14
Copy link
Contributor

RX14 commented Jan 8, 2017

@Victorious3 While I share your opinion, that doesn't mean I won't remove you from the project or issue tracker if you continue to be rude.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

You just need to talk to some java pros about it. Maybe even @calclavia (altho I'm not sure how "pro" they are).

@ExE-Boss
Copy link
Member Author

ExE-Boss commented Jan 8, 2017

On the NOVA discord server, I’ve discussed this with RX14 and we decided the following:

I would continue working on my version of the Identifier API and once all the versions of the Identifier API are fully implemented, we will compare them and decide which implementation is the best and end up using that.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

I need something I can use with HashMaps and stuff. I cannot use this implementation, and strings are unsuitable due to their conflicting nature.

@Victorious3
Copy link
Contributor

@SoniEx2 You dont throw two different types of Objects into the same map. Just dont do it. Then you are fine.

@ExE-Boss ExE-Boss removed this from the v0.1.0 milestone Jan 8, 2017
@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 8, 2017

I can throw String and Class and UUID all into the same Map just fine. They don't conflict with eachother.

I want it to also work for Identifiers.

It has its uses.

(Also, part of the reason I made the PR was so mods could extend Identifier and create their own Identifiers for their own purposes. Like using Identifier for a programming language/compiler. That is where being able to mix Identifiers together in a Map is a really useful feature to have. I agree that @ExE-Boss 's version is bloated. It's also unsuitable for my use-case. Unlike my version.)

@Victorious3
Copy link
Contributor

Victorious3 commented Jan 8, 2017

I can throw String and Class and UUID all into the same Map just fine. They don't conflict with eachother.

And then its a Map<Object, Object> hell no.

Like using Identifier for a programming language/compiler.

Mhm. Sounds like something I'd do every day.

@Victorious3
Copy link
Contributor

@loordgek And so might any other object that implements hashcode and equals. Yet you wouldn't call them identifiers.

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 15, 2017

I miss @calclavia, the only professional/sane java dev we had on this POS.

@loordgek
Copy link

@SoniEx2 can you stop crying ranting plz

@calclavia
Copy link
Member

@ExE-Boss What's the NOVA discord server? I'd like to join just to see what you guys are up to.

@ExE-Boss
Copy link
Member Author

@calclavia The server is https://discord.gg/Sh63S4H

@SoniEx2
Copy link
Contributor

SoniEx2 commented Jan 15, 2017

@loordgek Never. If you don't like it, why do you keep doing things that cause it?

@RX14
Copy link
Contributor

RX14 commented Jan 15, 2017

@SoniEx2 goodbye

@RX14 RX14 closed this Feb 24, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking change This is going to break stuff in progress Pull requests that are not yet ready to be merged and issues that are being worked on.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants