Carpet

Carpet

2M Downloads

Class that, as a map key, checks instanceof in given objects

altrisi opened this issue ยท 1 comments

commented

Not so long ago, in #772 (comment) you mentioned about using a Map to replace ValueConversions#guess.

Today I've got for you a complete hack that I made in a minute and you are completely free to dismiss which allows such functionality:

package carpet.utils;

/**
 * <p>Allows for getting a key by having an instance of the class this object was instantiated with.</p>
 * 
 * <p>Known working map implementations: {@link it.unimi.dsi.fastutil.objects.Object2ObjectArrayMap}. 
 * Others may not behave the same way (checking equals in existing key)</p>
 * 
 * <p>To prevent IDE warnings about unlinkely arguments types in get function, use {@link Object} as key generic.</p>
 *
 */
public class InstanceOfMapKey
{
    private final Class<?> clazz;
    
    public InstanceOfMapKey(Class<?> clazz)
    {
        this.clazz = clazz;
    }
    
    @Override
    public boolean equals(Object obj)
    {
        return clazz.isInstance(obj);
    }
    
    @Override
    public int hashCode() // May allow compat with hash implementations, but won't be useful at all
    {
        return 1;
    }
}

Add an || obj == clazz to the equals method to allow it to work if you pass it a class.

You would use this something like:

private static final Map<Object, Function<...>> toValueMap = new Object2ObjectArrayMap<>();
static
{
    toValueMap.put(new InstanceOfMapKey(Entity.class), e -> new EntityValue(e));
    ..
}

public static Value guess(Object o) {
   var converter = toValueMap.get(o);
   if (converter == null) throw new UnsupportedOperationException();
   return converter.apply(o);
}

Only tested to work with Object2ObjectArrayMap from fastutil, IIRC doesn't work with Java's HashMap, performance is probably awful, may be quite better to wait for JEP 406 (Pattern Matching for switch).

Please don't use it just wanted to share it somewhere.

commented

Now seriously, I would not use it. But just to let you know it exists and is kind-of possible. Probably breaks all and any conventions and contracts, but it can be done.

I'd wait for JEP 406 since it's "proposed to target" Java 17, and I don't think Mojang will stay in a non-LTS Java version.