package de.take_weiland.mods.commons.meta;
import com.google.common.collect.ImmutableSet;
import de.take_weiland.mods.commons.util.JavaUtils;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Map;
import java.util.Set;
/**
* @author diesieben07
*/
final class EnumProperty<T extends Enum<T>> extends GenericProperty<T> {
private final int shift;
private final int mask;
private final Class<T> clazz;
private final ImmutableSet<T> values;
EnumProperty(int shift, Class<T> clazz) {
this.shift = shift;
this.clazz = clazz;
this.values = ImmutableSet.copyOf(EnumSet.allOf(clazz));
// values.size - 1 is largest ordinal ever used
// highestOneBit of that << 1 is bit right above the MSB of the largest ordinal value
// that - 1 gives a mask for all values
this.mask = (Integer.highestOneBit(values.size() - 1) << 1) - 1;
}
@Override
public T value(int metadata) {
return JavaUtils.byOrdinal(clazz, (metadata >>> shift) & mask);
}
@Override
public int toMeta(T value, int previousMeta) {
return previousMeta | value.ordinal() << shift;
}
@Override
public boolean hasDistinctValues() {
return true;
}
@Override
public Set<T> values() {
return values;
}
@Override
public <V> Map<T, V> createMap() {
return new EnumMap<>(clazz);
}
}