Last active
April 8, 2020 19:49
-
-
Save Sollace/4bc682784670e85ad5b944fb5ea3e819 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import net.minecraft.client.model.ModelPart; | |
import net.minecraft.client.render.VertexConsumer; | |
import net.minecraft.client.util.math.MatrixStack; | |
import javax.annotation.Nullable; | |
import java.util.Iterator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import java.util.NoSuchElementException; | |
import java.util.Objects; | |
import java.util.function.Consumer; | |
import java.util.function.Supplier; | |
@SuppressWarnings("unchecked") | |
public abstract class RenderList<T> implements Iterable<T> { | |
private static final RenderConsumer<ModelPart> MODEL_PART_CONSUMER = ModelPart::render; | |
public static RenderList<ModelPart> of(Iterable<ModelPart> list) { | |
return of(list, MODEL_PART_CONSUMER); | |
} | |
public static <T> RenderList<T> of(Iterable<T> list, RenderConsumer<T> consumer) { | |
return new Impl<>(toArray(list), consumer); | |
} | |
public static RenderList<ModelPart> create(Supplier<Iterable<ModelPart>> factory) { | |
return create(factory, MODEL_PART_CONSUMER); | |
} | |
public static <T> RenderList<T> create(Supplier<Iterable<T>> factory, RenderConsumer<T> consumer) { | |
return new Lazy<>(() -> toArray(factory.get()), consumer); | |
} | |
private static <T> Object[] toArray(Iterable<T> list) { | |
if (list instanceof RenderList) { | |
return ((RenderList<T>)list).values(); | |
} | |
@SuppressWarnings("serial") | |
List<T> items = new LinkedList<T>() { | |
@Override | |
public boolean add(T t) { | |
return super.add(Objects.requireNonNull(t)); | |
} | |
}; | |
list.forEach(items::add); | |
return items.toArray(); | |
} | |
private final RenderConsumer<T> consumer; | |
private RenderList(RenderConsumer<T> consumer) { | |
this.consumer = consumer; | |
} | |
abstract Object[] values(); | |
public void render(MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha) { | |
Object[] values = values(); | |
for (int i = 0; i < values.length; i++) { | |
consumer.render((T)values[i], matrices, vertices, light, overlay, red, green, blue, alpha); | |
} | |
} | |
public RenderList<T> concat(Iterable<T> other) { | |
return new Lazy<>(() -> { | |
Object[] myArr = values(); | |
Object[] otherArr = toArray(other); | |
Object[] combined = new Object[myArr.length + otherArr.length]; | |
System.arraycopy(myArr, 0, combined, 0, myArr.length); | |
System.arraycopy(otherArr, 0, combined, myArr.length, otherArr.length); | |
return combined; | |
}, consumer); | |
} | |
@Override | |
public void forEach(Consumer<? super T> action) { | |
Objects.requireNonNull(action); | |
Object[] values = values(); | |
for (int i = 0; i < values.length; i++) { | |
action.accept((T)values[i]); | |
} | |
} | |
@Override | |
public Iterator<T> iterator() { | |
return new Iterator<T>() { | |
private int index; | |
private final Object[] values = values(); | |
@Override | |
public boolean hasNext() { | |
return index < values.length; | |
} | |
@Override | |
public T next() { | |
if (++index < values.length) { | |
return (T)values[index]; | |
} | |
throw new NoSuchElementException(); | |
} | |
}; | |
} | |
private static final class Lazy<T> extends RenderList<T> { | |
private final Supplier<Object[]> factory; | |
@Nullable | |
Object[] values; | |
Lazy(Supplier<Object[]> factory, RenderConsumer<T> consumer) { | |
super(consumer); | |
this.factory = factory; | |
} | |
@Override | |
Object[] values() { | |
if (values == null) { | |
values = factory.get(); | |
} | |
return values; | |
} | |
} | |
private static final class Impl<T> extends RenderList<T> { | |
private final Object[] values; | |
Impl(Object[] values, RenderConsumer<T> consumer) { | |
super(consumer); | |
this.values = values; | |
} | |
@Override | |
Object[] values() { | |
return values; | |
} | |
} | |
public interface RenderConsumer<T> { | |
void render(T obj, MatrixStack matrices, VertexConsumer vertices, int light, int overlay, float red, float green, float blue, float alpha); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment