From 95bd36b90d59b444ddd458654c8fdd57f975e746 Mon Sep 17 00:00:00 2001
From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com>
Date: Tue, 28 Mar 2023 10:58:22 -0700
Subject: [PATCH] TaskEngine and batching changes
- Rename TaskEngine to TaskExecutor
- Make TaskExecutor extend Executor
- Simplify ParallelTaskExecutor
- Move WorkGroup code to separate class
- Fix CPUInstancers being updated too late
- Do not unnecessarily clear memory when preparing DrawBuffer
- Simplify BatchingDrawTracker and DrawBufferSet by storing RenderType
in DrawBuffer
- Move all additional Mojang matrix operations to MatrixUtil and expose
fields using accessors
- Remove Color
- Remove WeakHashSet
---
.../jozufozu/flywheel/backend/Backend.java | 8 +-
.../backend/instancing/InstanceManager.java | 16 +-
.../backend/instancing/InstanceWorld.java | 24 +-
.../instancing/ParallelTaskEngine.java | 283 ----------------
.../instancing/ParallelTaskExecutor.java | 212 ++++++++++++
.../backend/instancing/RenderDispatcher.java | 4 +-
.../backend/instancing/SerialTaskEngine.java | 26 --
.../instancing/SerialTaskExecutor.java | 23 ++
.../backend/instancing/TaskEngine.java | 14 -
.../backend/instancing/TaskExecutor.java | 12 +
.../backend/instancing/WorkGroup.java | 72 ++++
.../batching/BatchingDrawTracker.java | 83 ++---
.../instancing/batching/BatchingEngine.java | 17 +-
.../batching/BatchingTransformManager.java | 2 +-
.../instancing/batching/CPUInstancer.java | 2 +-
.../instancing/batching/DrawBuffer.java | 11 +-
.../instancing/batching/DrawBufferSet.java | 47 +--
.../instancing/batching/TransformCall.java | 14 +-
.../instancing/batching/WaitGroup.java | 34 --
.../instancing/indirect/IndirectEngine.java | 11 +-
.../instancing/InstancingDrawManager.java | 2 +-
.../instancing/InstancingEngine.java | 11 +-
.../jozufozu/flywheel/core/RenderContext.java | 4 +-
.../jozufozu/flywheel/core/model/Mesh.java | 2 +-
.../flywheel/core/structs/ColoredLitPart.java | 10 -
.../transformed/TransformedWriter.java | 6 +-
.../flywheel/core/uniform/ViewProvider.java | 4 +-
.../flywheel/extension/Matrix3fExtension.java | 16 -
.../flywheel/extension/Matrix4fExtension.java | 16 -
.../flywheel/extension/MatrixWrite.java | 32 --
.../jozufozu/flywheel/light/LightUpdater.java | 15 +-
.../light/WeakContainmentMultiMap.java | 10 +-
.../flywheel/mixin/RenderTypeMixin.java | 2 +-
.../mixin/matrix/Matrix3fAccessor.java | 36 ++
.../flywheel/mixin/matrix/Matrix3fMixin.java | 55 ----
.../mixin/matrix/Matrix4fAccessor.java | 57 ++++
.../flywheel/mixin/matrix/Matrix4fMixin.java | 80 -----
.../com/jozufozu/flywheel/util/Color.java | 309 ------------------
.../com/jozufozu/flywheel/util/FlwUtil.java | 7 +
.../jozufozu/flywheel/util/MatrixUtil.java | 116 +++++++
.../jozufozu/flywheel/util/WeakHashSet.java | 122 -------
src/main/resources/flywheel.mixins.json | 4 +-
42 files changed, 665 insertions(+), 1166 deletions(-)
delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java
create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskExecutor.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskEngine.java
create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskExecutor.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/TaskEngine.java
create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/TaskExecutor.java
create mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/WorkGroup.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/backend/instancing/batching/WaitGroup.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/extension/Matrix3fExtension.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/extension/Matrix4fExtension.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/extension/MatrixWrite.java
create mode 100644 src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fAccessor.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
create mode 100644 src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fAccessor.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/util/Color.java
create mode 100644 src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java
delete mode 100644 src/main/java/com/jozufozu/flywheel/util/WeakHashSet.java
diff --git a/src/main/java/com/jozufozu/flywheel/backend/Backend.java b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
index 9aa80daa9..4f0a523ed 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/Backend.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/Backend.java
@@ -4,7 +4,7 @@ import org.jetbrains.annotations.Nullable;
import org.slf4j.Logger;
import com.jozufozu.flywheel.api.FlywheelLevel;
-import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
+import com.jozufozu.flywheel.backend.instancing.ParallelTaskExecutor;
import com.jozufozu.flywheel.config.FlwConfig;
import com.jozufozu.flywheel.core.BackendTypes;
import com.mojang.logging.LogUtils;
@@ -20,7 +20,7 @@ public class Backend {
private static BackendType TYPE;
- private static ParallelTaskEngine EXECUTOR;
+ private static ParallelTaskExecutor EXECUTOR;
private static final Loader LOADER = new Loader();
@@ -35,9 +35,9 @@ public class Backend {
* Get a thread pool for running Flywheel related work in parallel.
* @return A global Flywheel thread pool.
*/
- public static ParallelTaskEngine getTaskEngine() {
+ public static ParallelTaskExecutor getTaskExecutor() {
if (EXECUTOR == null) {
- EXECUTOR = new ParallelTaskEngine("Flywheel");
+ EXECUTOR = new ParallelTaskExecutor("Flywheel");
EXECUTOR.startWorkers();
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
index 319fb9607..d8e88904a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java
@@ -74,7 +74,7 @@ public abstract class InstanceManager {
* Queued updates are processed.
*
*/
- public void tick(TaskEngine taskEngine, double cameraX, double cameraY, double cameraZ) {
+ public void tick(TaskExecutor executor, double cameraX, double cameraY, double cameraZ) {
tick.tick();
processQueuedUpdates();
@@ -84,7 +84,7 @@ public abstract class InstanceManager {
int cZ = (int) cameraZ;
var instances = getStorage().getInstancesForTicking();
- distributeWork(taskEngine, instances, instance -> tickInstance(instance, cX, cY, cZ));
+ distributeWork(executor, instances, instance -> tickInstance(instance, cX, cY, cZ));
}
protected void tickInstance(TickableInstance instance, int cX, int cY, int cZ) {
@@ -106,7 +106,7 @@ public abstract class InstanceManager {
instance.tick();
}
- public void beginFrame(TaskEngine taskEngine, RenderContext context) {
+ public void beginFrame(TaskExecutor executor, RenderContext context) {
frame.tick();
processQueuedAdditions();
@@ -118,22 +118,22 @@ public abstract class InstanceManager {
FrustumIntersection culler = context.culler();
var instances = getStorage().getInstancesForUpdate();
- distributeWork(taskEngine, instances, instance -> updateInstance(instance, culler, cX, cY, cZ));
+ distributeWork(executor, instances, instance -> updateInstance(instance, culler, cX, cY, cZ));
}
- private static void distributeWork(TaskEngine taskEngine, List instances, Consumer action) {
+ private static void distributeWork(TaskExecutor executor, List instances, Consumer action) {
final int size = instances.size();
- final int threadCount = taskEngine.getThreadCount();
+ final int threadCount = executor.getThreadCount();
if (threadCount == 1) {
- taskEngine.submit(() -> instances.forEach(action));
+ executor.execute(() -> instances.forEach(action));
} else {
final int stride = Math.max(size / (threadCount * 2), 1);
for (int start = 0; start < size; start += stride) {
int end = Math.min(start + stride, size);
var sub = instances.subList(start, end);
- taskEngine.submit(() -> sub.forEach(action));
+ executor.execute(() -> sub.forEach(action));
}
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
index 621a5153e..c0b375c71 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceWorld.java
@@ -29,7 +29,7 @@ public class InstanceWorld implements AutoCloseable {
protected final InstanceManager entities;
protected final InstanceManager blockEntities;
- public final ParallelTaskEngine taskEngine;
+ public final ParallelTaskExecutor taskExecutor;
private final InstanceManager effects;
public static InstanceWorld create(LevelAccessor level) {
@@ -51,7 +51,7 @@ public class InstanceWorld implements AutoCloseable {
this.entities = entities;
this.blockEntities = blockEntities;
this.effects = effects;
- this.taskEngine = Backend.getTaskEngine();
+ this.taskExecutor = Backend.getTaskExecutor();
}
public InstanceManager getEntities() {
@@ -87,15 +87,15 @@ public class InstanceWorld implements AutoCloseable {
RenderContext context = event.getContext();
boolean shifted = engine.maintainOriginCoordinate(context.camera());
- taskEngine.syncPoint();
+ taskExecutor.syncPoint();
if (!shifted) {
- blockEntities.beginFrame(taskEngine, context);
- entities.beginFrame(taskEngine, context);
- effects.beginFrame(taskEngine, context);
+ blockEntities.beginFrame(taskExecutor, context);
+ entities.beginFrame(taskExecutor, context);
+ effects.beginFrame(taskExecutor, context);
}
- engine.beginFrame(taskEngine, context);
+ engine.beginFrame(taskExecutor, context);
}
/**
@@ -117,17 +117,17 @@ public class InstanceWorld implements AutoCloseable {
double y = renderViewEntity.getY();
double z = renderViewEntity.getZ();
- blockEntities.tick(taskEngine, x, y, z);
- entities.tick(taskEngine, x, y, z);
- effects.tick(taskEngine, x, y, z);
+ blockEntities.tick(taskExecutor, x, y, z);
+ entities.tick(taskExecutor, x, y, z);
+ effects.tick(taskExecutor, x, y, z);
}
/**
* Draw all instances for the given stage.
*/
public void renderStage(RenderContext context, RenderStage stage) {
- taskEngine.syncPoint();
- engine.renderStage(taskEngine, context, stage);
+ taskExecutor.syncPoint();
+ engine.renderStage(taskExecutor, context, stage);
}
/**
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java
deleted file mode 100644
index f929e6336..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskEngine.java
+++ /dev/null
@@ -1,283 +0,0 @@
-package com.jozufozu.flywheel.backend.instancing;
-
-import java.util.ArrayList;
-import java.util.Deque;
-import java.util.List;
-import java.util.concurrent.ConcurrentLinkedDeque;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicInteger;
-import java.util.function.Consumer;
-import java.util.stream.Stream;
-
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.jozufozu.flywheel.Flywheel;
-import com.jozufozu.flywheel.backend.instancing.batching.WaitGroup;
-
-import net.minecraft.util.Mth;
-
-// https://github.com/CaffeineMC/sodium-fabric/blob/5d364ed5ba63f9067fcf72a078ca310bff4db3e9/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuilder.java
-public class ParallelTaskEngine implements TaskEngine {
- private static final Logger LOGGER = LoggerFactory.getLogger("BatchExecutor");
-
- private final String name;
-
- /**
- * If set to false, the engine will shut down.
- */
- private final AtomicBoolean running = new AtomicBoolean(false);
- private final WaitGroup wg = new WaitGroup();
-
- private final Deque syncTasks = new ConcurrentLinkedDeque<>();
- private final Deque jobQueue = new ConcurrentLinkedDeque<>();
- private final List threads = new ArrayList<>();
-
- private final Object jobNotifier = new Object();
-
- private final int threadCount;
-
- public ParallelTaskEngine(String name) {
- this.name = name;
- threadCount = getOptimalThreadCount();
- }
-
- @Override
- public int getThreadCount() {
- return threadCount;
- }
-
- public WorkGroupBuilder group(String name) {
- return new WorkGroupBuilder(name);
- }
-
- /**
- * Spawns a number of work-stealing threads to process results in the build queue. If the builder is already
- * running, this method does nothing and exits.
- */
- public void startWorkers() {
- if (this.running.getAndSet(true)) {
- return;
- }
-
- if (!this.threads.isEmpty()) {
- throw new IllegalStateException("Threads are still alive while in the STOPPED state");
- }
-
- for (int i = 0; i < this.threadCount; i++) {
-
- Thread thread = new Thread(new WorkerRunnable(), name + " " + i);
- thread.setPriority(Math.max(0, Thread.NORM_PRIORITY - 2));
- thread.start();
-
- this.threads.add(thread);
- }
-
- LOGGER.info("Started {} worker threads", this.threads.size());
- }
-
- public void stopWorkers() {
- if (!this.running.getAndSet(false)) {
- return;
- }
-
- if (this.threads.isEmpty()) {
- throw new IllegalStateException("No threads are alive but the executor is in the RUNNING state");
- }
-
- synchronized (this.jobNotifier) {
- this.jobNotifier.notifyAll();
- }
-
- try {
- for (Thread thread : this.threads) {
- thread.join();
- }
- } catch (InterruptedException ignored) {
- }
-
- this.threads.clear();
-
- this.jobQueue.clear();
- }
-
- /**
- * Submit a task to the pool.
- */
- @Override
- public void submit(@NotNull Runnable command) {
- this.jobQueue.add(command);
- this.wg.add(1);
-
- synchronized (this.jobNotifier) {
- this.jobNotifier.notify();
- }
- }
-
- /**
- * Wait for all running jobs to finish.
- */
- @Override
- public void syncPoint() {
- Runnable job;
-
- // Finish everyone else's work...
- while ((job = this.jobQueue.pollLast()) != null) {
- processTask(job);
- }
-
- // and wait for any stragglers.
- try {
- this.wg.await();
- } catch (InterruptedException ignored) {
- }
-
- while ((job = this.syncTasks.pollLast()) != null) {
- job.run();
- }
- }
-
- @Nullable
- private Runnable getNextTask() {
- Runnable job = this.jobQueue.pollFirst();
-
- if (job == null) {
- synchronized (ParallelTaskEngine.this.jobNotifier) {
- try {
- ParallelTaskEngine.this.jobNotifier.wait();
- } catch (InterruptedException ignored) {
- }
- }
- }
-
- return job;
- }
-
- // TODO: job context
- private void processTask(Runnable job) {
- try {
- job.run();
- } catch (Exception e) {
- Flywheel.LOGGER.error("Error running job", e);
- } finally {
- ParallelTaskEngine.this.wg.done();
- }
- }
-
- /**
- * Returns the "optimal" number of threads to be used for chunk build tasks. This will always return at least one
- * thread.
- */
- private static int getOptimalThreadCount() {
- return Mth.clamp(Math.max(getMaxThreadCount() / 3, getMaxThreadCount() - 6), 1, 10);
- }
-
- private static int getMaxThreadCount() {
- return Runtime.getRuntime().availableProcessors();
- }
-
- private class WorkerRunnable implements Runnable {
-
- private final AtomicBoolean running = ParallelTaskEngine.this.running;
-
- @Override
- public void run() {
- // Run until the chunk builder shuts down
- while (this.running.get()) {
- Runnable job = ParallelTaskEngine.this.getNextTask();
-
- if (job == null) {
- continue;
- }
-
- ParallelTaskEngine.this.processTask(job);
- }
- }
-
- }
-
- public class WorkGroupBuilder {
- final String name;
-
- @Nullable
- Runnable finalizer;
-
- Stream tasks;
-
- public WorkGroupBuilder(String name) {
- this.name = name;
- }
-
- public WorkGroupBuilder addTasks(Stream iterable, Consumer consumer) {
- return addTasks(iterable.map(it -> () -> consumer.accept(it)));
- }
-
- public WorkGroupBuilder addTasks(Stream tasks) {
- if (this.tasks == null) {
- this.tasks = tasks;
- } else {
- this.tasks = Stream.concat(this.tasks, tasks);
- }
- return this;
- }
-
- public WorkGroupBuilder onComplete(Runnable runnable) {
- this.finalizer = runnable;
- return this;
- }
-
- public void submit() {
- if (this.tasks == null) {
- return;
- }
-
- WorkGroup workGroup = new WorkGroup(name, finalizer);
-
- tasks.map(task -> new WorkGroupTask(workGroup, task)).forEach(ParallelTaskEngine.this::submit);
- }
-
- }
-
- private static class WorkGroupTask implements Runnable {
-
- private final WorkGroup parent;
- private final Runnable wrapped;
-
- public WorkGroupTask(WorkGroup parent, Runnable wrapped) {
- this.parent = parent;
- this.wrapped = wrapped;
-
- this.parent.running.incrementAndGet();
- }
-
- @Override
- public void run() {
- this.wrapped.run();
-
- this.parent.oneDown();
- }
- }
-
- private class WorkGroup {
- final String name;
-
- final Runnable finalizer;
-
- final AtomicInteger running = new AtomicInteger(0);
-
- public WorkGroup(String name, @Nullable Runnable finalizer) {
- this.name = name;
- this.finalizer = finalizer;
- }
-
- public void oneDown() {
- if (finalizer != null) {
- if (running.decrementAndGet() == 0) {
- ParallelTaskEngine.this.syncTasks.add(finalizer);
- }
- }
- }
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskExecutor.java
new file mode 100644
index 000000000..95c231000
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/ParallelTaskExecutor.java
@@ -0,0 +1,212 @@
+package com.jozufozu.flywheel.backend.instancing;
+
+import java.util.ArrayList;
+import java.util.Deque;
+import java.util.List;
+import java.util.concurrent.ConcurrentLinkedDeque;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.jetbrains.annotations.Nullable;
+import org.slf4j.Logger;
+
+import com.jozufozu.flywheel.Flywheel;
+import com.mojang.logging.LogUtils;
+
+import net.minecraft.util.Mth;
+
+// https://github.com/CaffeineMC/sodium-fabric/blob/5d364ed5ba63f9067fcf72a078ca310bff4db3e9/src/main/java/me/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuilder.java
+// https://stackoverflow.com/questions/29655531
+public class ParallelTaskExecutor implements TaskExecutor {
+ private static final Logger LOGGER = LogUtils.getLogger();
+
+ private final String name;
+ private final int threadCount;
+
+ /**
+ * If set to false, the executor will shut down.
+ */
+ private final AtomicBoolean running = new AtomicBoolean(false);
+ /**
+ * Synchronized via {@link #tasksCompletedNotifier}.
+ */
+ private int incompleteTaskCounter = 0;
+
+ private final List threads = new ArrayList<>();
+ private final Deque taskQueue = new ConcurrentLinkedDeque<>();
+
+ private final Object taskNotifier = new Object();
+ private final Object tasksCompletedNotifier = new Object();
+
+ public ParallelTaskExecutor(String name) {
+ this.name = name;
+ threadCount = getOptimalThreadCount();
+ }
+
+ @Override
+ public int getThreadCount() {
+ return threadCount;
+ }
+
+ /**
+ * Spawns a number of work-stealing threads to process results in the task queue. If the executor is already
+ * running, this method does nothing and exits.
+ */
+ public void startWorkers() {
+ if (running.getAndSet(true)) {
+ return;
+ }
+
+ if (!threads.isEmpty()) {
+ throw new IllegalStateException("Threads are still alive while in the STOPPED state");
+ }
+
+ for (int i = 0; i < threadCount; i++) {
+ WorkerThread thread = new WorkerThread(name + " Task Executor #" + i);
+ thread.setPriority(Mth.clamp(Thread.NORM_PRIORITY - 2, Thread.MIN_PRIORITY, Thread.MAX_PRIORITY));
+ thread.start();
+
+ threads.add(thread);
+ }
+
+ LOGGER.info("Started {} worker threads", threads.size());
+ }
+
+ public void stopWorkers() {
+ if (!running.getAndSet(false)) {
+ return;
+ }
+
+ if (threads.isEmpty()) {
+ throw new IllegalStateException("No threads are alive but the executor is in the RUNNING state");
+ }
+
+ LOGGER.info("Stopping worker threads");
+
+ // Notify all worker threads to wake up, where they will then terminate
+ synchronized (taskNotifier) {
+ taskNotifier.notifyAll();
+ }
+
+ // Wait for every remaining thread to terminate
+ for (Thread thread : threads) {
+ try {
+ thread.join();
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+
+ threads.clear();
+ taskQueue.clear();
+ synchronized (tasksCompletedNotifier) {
+ incompleteTaskCounter = 0;
+ tasksCompletedNotifier.notifyAll();
+ }
+ }
+
+ @Override
+ public void execute(Runnable task) {
+ if (!running.get()) {
+ throw new IllegalStateException("Executor is stopped");
+ }
+
+ taskQueue.add(task);
+
+ synchronized (tasksCompletedNotifier) {
+ incompleteTaskCounter++;
+ }
+
+ synchronized (taskNotifier) {
+ taskNotifier.notify();
+ }
+ }
+
+ /**
+ * Wait for all running tasks to finish.
+ */
+ @Override
+ public void syncPoint() {
+ Runnable task;
+
+ // Finish everyone else's work...
+ while ((task = taskQueue.pollLast()) != null) {
+ processTask(task);
+ }
+
+ // and wait for any stragglers.
+ synchronized (tasksCompletedNotifier) {
+ while (incompleteTaskCounter > 0) {
+ try {
+ tasksCompletedNotifier.wait();
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+ }
+ }
+
+ @Nullable
+ private Runnable getNextTask() {
+ Runnable task = taskQueue.pollFirst();
+
+ if (task == null) {
+ synchronized (taskNotifier) {
+ try {
+ taskNotifier.wait();
+ } catch (InterruptedException e) {
+ //
+ }
+ }
+ }
+
+ return task;
+ }
+
+ // TODO: task context
+ private void processTask(Runnable task) {
+ try {
+ task.run();
+ } catch (Exception e) {
+ Flywheel.LOGGER.error("Error running task", e);
+ } finally {
+ synchronized (tasksCompletedNotifier) {
+ if (--incompleteTaskCounter == 0) {
+ tasksCompletedNotifier.notifyAll();
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns the "optimal" number of threads to be used for tasks. This will always return at least one thread.
+ */
+ private static int getOptimalThreadCount() {
+ return Mth.clamp(Math.max(getMaxThreadCount() / 3, getMaxThreadCount() - 6), 1, 10);
+ }
+
+ private static int getMaxThreadCount() {
+ return Runtime.getRuntime().availableProcessors();
+ }
+
+ private class WorkerThread extends Thread {
+ private final AtomicBoolean running = ParallelTaskExecutor.this.running;
+
+ public WorkerThread(String name) {
+ super(name);
+ }
+
+ @Override
+ public void run() {
+ // Run until the executor shuts down
+ while (running.get()) {
+ Runnable task = getNextTask();
+
+ if (task == null) {
+ continue;
+ }
+
+ processTask(task);
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderDispatcher.java
index d48d79670..610c9dc4d 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderDispatcher.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/RenderDispatcher.java
@@ -7,9 +7,9 @@ import net.minecraft.client.Camera;
public interface RenderDispatcher {
- void beginFrame(TaskEngine taskEngine, RenderContext context);
+ void beginFrame(TaskExecutor executor, RenderContext context);
- void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage);
+ void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage);
/**
* Maintain the integer origin coordinate to be within a certain distance from the camera in all directions,
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskEngine.java
deleted file mode 100644
index 1a6c8a9b6..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskEngine.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.jozufozu.flywheel.backend.instancing;
-
-import org.jetbrains.annotations.NotNull;
-
-public class SerialTaskEngine implements TaskEngine {
-
- public static final SerialTaskEngine INSTANCE = new SerialTaskEngine();
-
- private SerialTaskEngine() {
- }
-
- @Override
- public void submit(@NotNull Runnable command) {
- command.run();
- }
-
- @Override
- public void syncPoint() {
- // noop
- }
-
- @Override
- public int getThreadCount() {
- return 1;
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskExecutor.java
new file mode 100644
index 000000000..7a97d74ea
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/SerialTaskExecutor.java
@@ -0,0 +1,23 @@
+package com.jozufozu.flywheel.backend.instancing;
+
+public class SerialTaskExecutor implements TaskExecutor {
+ public static final SerialTaskExecutor INSTANCE = new SerialTaskExecutor();
+
+ private SerialTaskExecutor() {
+ }
+
+ @Override
+ public void execute(Runnable task) {
+ task.run();
+ }
+
+ @Override
+ public void syncPoint() {
+ // noop
+ }
+
+ @Override
+ public int getThreadCount() {
+ return 1;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskEngine.java
deleted file mode 100644
index a38f5a5c2..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskEngine.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.jozufozu.flywheel.backend.instancing;
-
-import org.jetbrains.annotations.NotNull;
-
-public interface TaskEngine {
- void submit(@NotNull Runnable command);
-
- /**
- * Wait for all running jobs to finish.
- */
- void syncPoint();
-
- int getThreadCount();
-}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskExecutor.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskExecutor.java
new file mode 100644
index 000000000..c341dab83
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/TaskExecutor.java
@@ -0,0 +1,12 @@
+package com.jozufozu.flywheel.backend.instancing;
+
+import java.util.concurrent.Executor;
+
+public interface TaskExecutor extends Executor {
+ /**
+ * Wait for all running tasks to finish.
+ */
+ void syncPoint();
+
+ int getThreadCount();
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/WorkGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/WorkGroup.java
new file mode 100644
index 000000000..3ea1692c8
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/WorkGroup.java
@@ -0,0 +1,72 @@
+package com.jozufozu.flywheel.backend.instancing;
+
+import java.util.Iterator;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+import java.util.stream.Stream;
+
+import org.jetbrains.annotations.Nullable;
+
+public class WorkGroup {
+ public static void run(Iterator tasks, Executor executor) {
+ tasks.forEachRemaining(executor::execute);
+ }
+
+ public static void run(Iterator tasks, @Nullable Runnable finalizer, Executor executor) {
+ if (finalizer == null) {
+ run(tasks, executor);
+ return;
+ }
+
+ AtomicInteger incompleteTaskCounter = new AtomicInteger(0);
+ tasks.forEachRemaining(task -> {
+ incompleteTaskCounter.incrementAndGet();
+ executor.execute(() -> {
+ task.run();
+ if (incompleteTaskCounter.decrementAndGet() == 0) {
+ executor.execute(finalizer);
+ }
+ });
+ });
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ @Nullable
+ private Runnable finalizer;
+ private Stream tasks;
+
+ public Builder() {
+ }
+
+ public Builder addTasks(Stream iterable, Consumer consumer) {
+ return addTasks(iterable.map(it -> () -> consumer.accept(it)));
+ }
+
+ public Builder addTasks(Stream tasks) {
+ if (this.tasks == null) {
+ this.tasks = tasks;
+ } else {
+ this.tasks = Stream.concat(this.tasks, tasks);
+ }
+ return this;
+ }
+
+ public Builder onComplete(Runnable runnable) {
+ this.finalizer = runnable;
+ return this;
+ }
+
+ public void execute(Executor executor) {
+ if (tasks == null) {
+ return;
+ }
+
+ run(tasks.iterator(), finalizer, executor);
+ }
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingDrawTracker.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingDrawTracker.java
index a36dfc59a..329876a08 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingDrawTracker.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingDrawTracker.java
@@ -1,7 +1,8 @@
package com.jozufozu.flywheel.backend.instancing.batching;
+import java.util.EnumMap;
import java.util.HashSet;
-import java.util.Iterator;
+import java.util.Map;
import java.util.Set;
import com.jozufozu.flywheel.api.RenderStage;
@@ -12,7 +13,15 @@ import com.mojang.blaze3d.vertex.BufferBuilder;
import net.minecraft.client.renderer.RenderType;
public class BatchingDrawTracker {
- private final Set activeTypes = new HashSet<>();
+ private static final RenderStage[] RENDER_STAGES = RenderStage.values();
+
+ private final Map> activeBuffers = new EnumMap<>(RenderStage.class);
+ {
+ for (RenderStage stage : RENDER_STAGES) {
+ activeBuffers.put(stage, new HashSet<>());
+ }
+ }
+
private final BufferBuilder scratch;
public BatchingDrawTracker() {
@@ -22,22 +31,9 @@ public class BatchingDrawTracker {
}
public DrawBuffer getBuffer(RenderType renderType, RenderStage stage) {
- return getBufferSet(renderType).getBuffer(stage);
- }
-
- public DrawBufferSet getBufferSet(RenderType renderType) {
- activeTypes.add(renderType);
- return RenderTypeExtension.getDrawBufferSet(renderType);
- }
-
- /**
- * Draw and reset all DrawBuffers for the given RenderType.
- * @param renderType The RenderType to draw.
- */
- public void draw(RenderType renderType) {
- _draw(renderType);
-
- activeTypes.remove(renderType);
+ DrawBuffer buffer = RenderTypeExtension.getDrawBufferSet(renderType).getBuffer(stage);
+ activeBuffers.get(stage).add(buffer);
+ return buffer;
}
/**
@@ -45,59 +41,44 @@ public class BatchingDrawTracker {
* @param stage The RenderStage to draw.
*/
public void draw(RenderStage stage) {
- Iterator iterator = activeTypes.iterator();
- while (iterator.hasNext()) {
- RenderType renderType = iterator.next();
- DrawBufferSet bufferSet = RenderTypeExtension.getDrawBufferSet(renderType);
- DrawBuffer buffer = bufferSet.deactivateBuffer(stage);
- if (buffer == null) {
- continue;
- }
- if (bufferSet.getActiveStagesView().isEmpty()) {
- iterator.remove();
- }
- _draw(buffer, renderType);
+ Set buffers = activeBuffers.get(stage);
+ for (DrawBuffer buffer : buffers) {
+ _draw(buffer);
+ buffer.reset();
}
+ buffers.clear();
}
/**
* Draw and reset all active DrawBuffers.
*/
public void drawAll() {
- for (RenderType renderType : activeTypes) {
- _draw(renderType);
- }
-
- activeTypes.clear();
- }
-
- private void _draw(RenderType renderType) {
- DrawBufferSet bufferSet = RenderTypeExtension.getDrawBufferSet(renderType);
- for (RenderStage stage : bufferSet.getActiveStagesView()) {
- DrawBuffer buffer = bufferSet.deactivateBuffer(stage);
- _draw(buffer, renderType);
+ for (Set buffers : activeBuffers.values()) {
+ for (DrawBuffer buffer : buffers) {
+ _draw(buffer);
+ buffer.reset();
+ }
+ buffers.clear();
}
}
- private void _draw(DrawBuffer buffer, RenderType renderType) {
+ private void _draw(DrawBuffer buffer) {
if (buffer.hasVertices()) {
BufferBuilderExtension scratch = (BufferBuilderExtension) this.scratch;
buffer.inject(scratch);
- renderType.end(this.scratch, 0, 0, 0);
+ buffer.getRenderType().end(this.scratch, 0, 0, 0);
}
-
- buffer.reset();
}
/**
* Reset all active DrawBuffers.
*/
public void reset() {
- for (RenderType type : activeTypes) {
- RenderTypeExtension.getDrawBufferSet(type)
- .reset();
+ for (Set buffers : activeBuffers.values()) {
+ for (DrawBuffer buffer : buffers) {
+ buffer.reset();
+ }
+ buffers.clear();
}
-
- activeTypes.clear();
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java
index 84f1408be..88c47df7c 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingEngine.java
@@ -8,7 +8,7 @@ import com.jozufozu.flywheel.api.instancer.Instancer;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
-import com.jozufozu.flywheel.backend.instancing.TaskEngine;
+import com.jozufozu.flywheel.backend.instancing.TaskExecutor;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.util.FlwUtil;
@@ -30,19 +30,19 @@ public class BatchingEngine implements Engine {
}
@Override
- public void beginFrame(TaskEngine taskEngine, RenderContext context) {
+ public void beginFrame(TaskExecutor executor, RenderContext context) {
transformManager.flush();
Vec3 cameraPos = context.camera().getPosition();
var stack = FlwUtil.copyPoseStack(context.stack());
stack.translate(-cameraPos.x, -cameraPos.y, -cameraPos.z);
- // TODO: async task engine barriers
- taskEngine.syncPoint();
- submitTasks(taskEngine, stack.last(), context.level());
+ // TODO: async task executor barriers
+ executor.syncPoint();
+ submitTasks(executor, stack.last(), context.level());
}
- public void submitTasks(TaskEngine taskEngine, PoseStack.Pose matrices, ClientLevel level) {
+ public void submitTasks(TaskExecutor executor, PoseStack.Pose matrices, ClientLevel level) {
for (var transformSetEntry : transformManager.getTransformSetsView().entrySet()) {
var stage = transformSetEntry.getKey();
var transformSet = transformSetEntry.getValue();
@@ -53,6 +53,7 @@ public class BatchingEngine implements Engine {
int vertices = 0;
for (var transformCall : transformCalls) {
+ transformCall.setup();
vertices += transformCall.getTotalVertexCount();
}
@@ -65,7 +66,7 @@ public class BatchingEngine implements Engine {
int startVertex = 0;
for (var transformCall : transformCalls) {
- transformCall.submitTasks(taskEngine, buffer, startVertex, matrices, level);
+ transformCall.submitTasks(executor, buffer, startVertex, matrices, level);
startVertex += transformCall.getTotalVertexCount();
}
}
@@ -73,7 +74,7 @@ public class BatchingEngine implements Engine {
}
@Override
- public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
+ public void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage) {
drawTracker.draw(stage);
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingTransformManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingTransformManager.java
index 4540c2018..e93032f79 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingTransformManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/BatchingTransformManager.java
@@ -99,7 +99,7 @@ public class BatchingTransformManager {
public static class TransformSet implements Iterable>>> {
public static final TransformSet EMPTY = new TransformSet(ImmutableListMultimap.of());
- final ListMultimap> transformCalls;
+ private final ListMultimap> transformCalls;
public TransformSet(RenderStage renderStage) {
transformCalls = ArrayListMultimap.create();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java
index 1b4c764c3..e65deb393 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/CPUInstancer.java
@@ -10,7 +10,7 @@ public class CPUInstancer extends AbstractInstancer
super(type);
}
- void setup() {
+ void update() {
if (anyToRemove) {
data.removeIf(InstancedPart::isRemoved);
anyToRemove = false;
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java
index 4a5cc0621..914982d06 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBuffer.java
@@ -11,6 +11,8 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.extension.BufferBuilderExtension;
import com.mojang.blaze3d.vertex.VertexFormat;
+import net.minecraft.client.renderer.RenderType;
+
/**
* A byte buffer that can be used to draw vertices through multiple {@link ReusableVertexList}s.
*
@@ -19,6 +21,7 @@ import com.mojang.blaze3d.vertex.VertexFormat;
public class DrawBuffer {
private static final List ALL = new ArrayList<>();
+ private final RenderType renderType;
private final VertexFormat format;
private final int stride;
private final VertexListProvider provider;
@@ -29,7 +32,8 @@ public class DrawBuffer {
private boolean prepared;
private int vertexCount;
- DrawBuffer(VertexFormat format, int stride, VertexListProvider provider) {
+ DrawBuffer(RenderType renderType, VertexFormat format, int stride, VertexListProvider provider) {
+ this.renderType = renderType;
this.format = format;
this.stride = stride;
this.provider = provider;
@@ -62,7 +66,6 @@ public class DrawBuffer {
buffer = memory.asBuffer();
}
- memory.clear();
prepared = true;
}
@@ -90,6 +93,10 @@ public class DrawBuffer {
bufferBuilder.flywheel$injectForRender(buffer, format, vertexCount);
}
+ public RenderType getRenderType() {
+ return renderType;
+ }
+
public VertexFormat getVertexFormat() {
return format;
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBufferSet.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBufferSet.java
index 15b66b33d..56ccd328a 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBufferSet.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/DrawBufferSet.java
@@ -1,66 +1,33 @@
package com.jozufozu.flywheel.backend.instancing.batching;
-import java.util.Collections;
import java.util.EnumMap;
-import java.util.EnumSet;
import java.util.Map;
-import java.util.Set;
import org.jetbrains.annotations.ApiStatus;
-import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.vertex.VertexListProvider;
import com.mojang.blaze3d.vertex.VertexFormat;
+import net.minecraft.client.renderer.RenderType;
+
public class DrawBufferSet {
+ private final RenderType renderType;
private final VertexFormat format;
private final int stride;
private final VertexListProvider provider;
private final Map buffers = new EnumMap<>(RenderStage.class);
- private final Set activeStages = EnumSet.noneOf(RenderStage.class);
- private final Set activeStagesView = Collections.unmodifiableSet(activeStages);
@ApiStatus.Internal
- public DrawBufferSet(VertexFormat format) {
- this.format = format;
+ public DrawBufferSet(RenderType renderType) {
+ this.renderType = renderType;
+ format = renderType.format();
stride = format.getVertexSize();
provider = VertexListProvider.get(format);
}
- public Set getActiveStagesView() {
- return activeStagesView;
- }
-
public DrawBuffer getBuffer(RenderStage stage) {
- activeStages.add(stage);
- return buffers.computeIfAbsent(stage, $ -> createBuffer());
- }
-
- @Nullable
- public DrawBuffer deactivateBuffer(RenderStage stage) {
- if (activeStages.remove(stage)) {
- return buffers.get(stage);
- }
- return null;
- }
-
- public void reset(RenderStage stage) {
- if (activeStages.remove(stage)) {
- buffers.get(stage).reset();
- }
- }
-
- public void reset() {
- for (RenderStage stage : activeStages) {
- buffers.get(stage).reset();
- }
-
- activeStages.clear();
- }
-
- private DrawBuffer createBuffer() {
- return new DrawBuffer(format, stride, provider);
+ return buffers.computeIfAbsent(stage, $ -> new DrawBuffer(renderType, format, stride, provider));
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformCall.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformCall.java
index 2c0827707..b2cf9c3e3 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformCall.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/TransformCall.java
@@ -7,7 +7,7 @@ import com.jozufozu.flywheel.api.material.Material;
import com.jozufozu.flywheel.api.struct.StructType;
import com.jozufozu.flywheel.api.vertex.MutableVertexList;
import com.jozufozu.flywheel.api.vertex.ReusableVertexList;
-import com.jozufozu.flywheel.backend.instancing.TaskEngine;
+import com.jozufozu.flywheel.backend.instancing.TaskExecutor;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix3f;
import com.mojang.math.Matrix4f;
@@ -37,9 +37,11 @@ public class TransformCall {
return meshVertexCount * instancer.getInstanceCount();
}
- void submitTasks(TaskEngine pool, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
- instancer.setup();
+ void setup() {
+ instancer.update();
+ }
+ void submitTasks(TaskExecutor executor, DrawBuffer buffer, int startVertex, PoseStack.Pose matrices, ClientLevel level) {
int instances = instancer.getInstanceCount();
while (instances > 0) {
@@ -51,7 +53,7 @@ public class TransformCall {
ReusableVertexList sub = buffer.slice(startVertex, vertexCount);
startVertex += vertexCount;
- pool.submit(() -> transformRange(sub, start, end, matrices, level));
+ executor.execute(() -> transformRange(sub, start, end, matrices, level));
}
}
@@ -82,10 +84,10 @@ public class TransformCall {
vertexList.ptr(anchorPtr);
vertexList.vertexCount(totalVertexCount);
material.getVertexTransformer().transform(vertexList, level);
- applyPoseStack(vertexList, matrices);
+ applyMatrices(vertexList, matrices);
}
- private static void applyPoseStack(MutableVertexList vertexList, PoseStack.Pose matrices) {
+ private static void applyMatrices(MutableVertexList vertexList, PoseStack.Pose matrices) {
Vector4f pos = new Vector4f();
Vector3f normal = new Vector3f();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/WaitGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/WaitGroup.java
deleted file mode 100644
index a27f8cbdc..000000000
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/batching/WaitGroup.java
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.jozufozu.flywheel.backend.instancing.batching;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-// https://stackoverflow.com/questions/29655531
-public class WaitGroup {
-
- private final AtomicInteger counter = new AtomicInteger(0);
-
- public synchronized void add(int i) {
- if (i == 0) {
- return;
- }
-
- if (i == 1) {
- this.counter.incrementAndGet();
- } else {
- this.counter.addAndGet(i);
- }
- }
-
- public synchronized void done() {
- if (this.counter.decrementAndGet() == 0) {
- this.notifyAll();
- }
- }
-
- public synchronized void await() throws InterruptedException {
- while (this.counter.get() > 0) {
- this.wait();
- }
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java
index 9c607c579..bca93b860 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java
@@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.indirect;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import org.lwjgl.opengl.GL32;
@@ -14,10 +15,10 @@ import com.jozufozu.flywheel.backend.gl.GlStateTracker;
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
-import com.jozufozu.flywheel.backend.instancing.TaskEngine;
+import com.jozufozu.flywheel.backend.instancing.TaskExecutor;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.model.Model;
-import com.jozufozu.flywheel.util.WeakHashSet;
+import com.jozufozu.flywheel.util.FlwUtil;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera;
@@ -34,7 +35,7 @@ public class IndirectEngine implements Engine {
/**
* The set of instance managers that are attached to this engine.
*/
- private final WeakHashSet> instanceManagers = new WeakHashSet<>();
+ private final Set> instanceManagers = FlwUtil.createWeakHashSet();
protected final ContextShader context;
protected final int sqrMaxOriginDistance;
@@ -52,14 +53,14 @@ public class IndirectEngine implements Engine {
}
@Override
- public void beginFrame(TaskEngine taskEngine, RenderContext context) {
+ public void beginFrame(TaskExecutor executor, RenderContext context) {
try (var restoreState = GlStateTracker.getRestoreState()) {
drawManager.flush();
}
}
@Override
- public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
+ public void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage) {
try (var restoreState = GlStateTracker.getRestoreState()) {
setup();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java
index c6fcf0310..06fdfa886 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingDrawManager.java
@@ -99,7 +99,7 @@ public class InstancingDrawManager {
public static final DrawSet EMPTY = new DrawSet(ImmutableListMultimap.of());
- final ListMultimap drawCalls;
+ private final ListMultimap drawCalls;
public DrawSet(RenderStage renderStage) {
drawCalls = ArrayListMultimap.create();
diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
index 99734c157..7eb5c16b6 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/instancing/InstancingEngine.java
@@ -2,6 +2,7 @@ package com.jozufozu.flywheel.backend.instancing.instancing;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
import org.lwjgl.opengl.GL32;
@@ -15,12 +16,12 @@ import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
import com.jozufozu.flywheel.backend.instancing.Engine;
import com.jozufozu.flywheel.backend.instancing.InstanceManager;
import com.jozufozu.flywheel.backend.instancing.PipelineCompiler;
-import com.jozufozu.flywheel.backend.instancing.TaskEngine;
+import com.jozufozu.flywheel.backend.instancing.TaskExecutor;
import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.model.Model;
import com.jozufozu.flywheel.core.uniform.UniformBuffer;
-import com.jozufozu.flywheel.util.WeakHashSet;
+import com.jozufozu.flywheel.util.FlwUtil;
import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.client.Camera;
@@ -37,7 +38,7 @@ public class InstancingEngine implements Engine {
/**
* The set of instance managers that are attached to this engine.
*/
- private final WeakHashSet> instanceManagers = new WeakHashSet<>();
+ private final Set> instanceManagers = FlwUtil.createWeakHashSet();
protected final ContextShader context;
protected final int sqrMaxOriginDistance;
@@ -55,14 +56,14 @@ public class InstancingEngine implements Engine {
}
@Override
- public void beginFrame(TaskEngine taskEngine, RenderContext context) {
+ public void beginFrame(TaskExecutor executor, RenderContext context) {
try (var restoreState = GlStateTracker.getRestoreState()) {
drawManager.flush();
}
}
@Override
- public void renderStage(TaskEngine taskEngine, RenderContext context, RenderStage stage) {
+ public void renderStage(TaskExecutor executor, RenderContext context, RenderStage stage) {
var drawSet = drawManager.get(stage);
if (drawSet.isEmpty()) {
diff --git a/src/main/java/com/jozufozu/flywheel/core/RenderContext.java b/src/main/java/com/jozufozu/flywheel/core/RenderContext.java
index 4664a052a..f6c99b41a 100644
--- a/src/main/java/com/jozufozu/flywheel/core/RenderContext.java
+++ b/src/main/java/com/jozufozu/flywheel/core/RenderContext.java
@@ -2,7 +2,7 @@ package com.jozufozu.flywheel.core;
import org.jetbrains.annotations.NotNull;
-import com.jozufozu.flywheel.extension.Matrix4fExtension;
+import com.jozufozu.flywheel.util.MatrixUtil;
import com.jozufozu.flywheel.util.joml.FrustumIntersection;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.math.Matrix4f;
@@ -23,7 +23,7 @@ public record RenderContext(LevelRenderer renderer, ClientLevel level, PoseStack
}
public static FrustumIntersection createCuller(Matrix4f viewProjection, float camX, float camY, float camZ) {
- com.jozufozu.flywheel.util.joml.Matrix4f proj = Matrix4fExtension.clone(viewProjection);
+ com.jozufozu.flywheel.util.joml.Matrix4f proj = MatrixUtil.toJoml(viewProjection);
proj.translate(camX, camY, camZ);
diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java
index 12ee9e9cf..bfa7adb55 100644
--- a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java
+++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java
@@ -42,7 +42,7 @@ public interface Mesh {
/**
* Write this mesh into a vertex list. Vertices with index {@literal <}0 or {@literal >=}{@link #getVertexCount()} will not be
- * modified.
+ * read or modified.
* @param vertexList The vertex list to which data is written to.
*/
void write(MutableVertexList vertexList);
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitPart.java b/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitPart.java
index ca75d2f40..050b27d49 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitPart.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/ColoredLitPart.java
@@ -2,7 +2,6 @@ package com.jozufozu.flywheel.core.structs;
import com.jozufozu.flywheel.api.instancer.InstancedPart;
import com.jozufozu.flywheel.api.struct.StructType;
-import com.jozufozu.flywheel.util.Color;
import net.minecraft.client.renderer.LightTexture;
@@ -39,15 +38,6 @@ public abstract class ColoredLitPart extends InstancedPart implements FlatLit {
public static final TransformedWriter INSTANCE = new TransformedWriter();
@@ -9,8 +9,8 @@ public class TransformedWriter extends ColoredLitWriter {
@Override
public void write(final long ptr, final TransformedPart d) {
super.write(ptr, d);
- MatrixWrite.writeUnsafe(d.model, ptr + 8);
- MatrixWrite.writeUnsafe(d.normal, ptr + 72);
+ MatrixUtil.writeUnsafe(d.model, ptr + 8);
+ MatrixUtil.writeUnsafe(d.normal, ptr + 72);
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
index 89175710e..fb10e3fc3 100644
--- a/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
+++ b/src/main/java/com/jozufozu/flywheel/core/uniform/ViewProvider.java
@@ -8,7 +8,7 @@ import com.jozufozu.flywheel.core.Components;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.event.BeginFrameEvent;
-import com.jozufozu.flywheel.extension.MatrixWrite;
+import com.jozufozu.flywheel.util.MatrixUtil;
import net.minecraft.client.multiplayer.ClientLevel;
import net.minecraft.core.Vec3i;
@@ -52,7 +52,7 @@ public class ViewProvider extends UniformProvider {
var vp = context.viewProjection().copy();
vp.multiplyWithTranslation(-camX, -camY, -camZ);
- MatrixWrite.writeUnsafe(vp, ptr);
+ MatrixUtil.writeUnsafe(vp, ptr);
MemoryUtil.memPutFloat(ptr + 64, camX);
MemoryUtil.memPutFloat(ptr + 68, camY);
MemoryUtil.memPutFloat(ptr + 72, camZ);
diff --git a/src/main/java/com/jozufozu/flywheel/extension/Matrix3fExtension.java b/src/main/java/com/jozufozu/flywheel/extension/Matrix3fExtension.java
deleted file mode 100644
index ef8ce3cc6..000000000
--- a/src/main/java/com/jozufozu/flywheel/extension/Matrix3fExtension.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.jozufozu.flywheel.extension;
-
-import com.jozufozu.flywheel.util.joml.Matrix3f;
-
-public interface Matrix3fExtension {
-
- Matrix3f flywheel$store(Matrix3f matrix);
-
- static Matrix3f clone(com.mojang.math.Matrix3f moj) {
- return ((Matrix3fExtension)(Object) moj).flywheel$store(new Matrix3f());
- }
-
- static void store(com.mojang.math.Matrix3f moj, Matrix3f joml) {
- ((Matrix3fExtension)(Object) moj).flywheel$store(joml);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/extension/Matrix4fExtension.java b/src/main/java/com/jozufozu/flywheel/extension/Matrix4fExtension.java
deleted file mode 100644
index ea77ca703..000000000
--- a/src/main/java/com/jozufozu/flywheel/extension/Matrix4fExtension.java
+++ /dev/null
@@ -1,16 +0,0 @@
-package com.jozufozu.flywheel.extension;
-
-import com.jozufozu.flywheel.util.joml.Matrix4f;
-
-public interface Matrix4fExtension {
-
- Matrix4f flywheel$store(Matrix4f matrix);
-
- static Matrix4f clone(com.mojang.math.Matrix4f moj) {
- return ((Matrix4fExtension)(Object) moj).flywheel$store(new Matrix4f());
- }
-
- static void store(com.mojang.math.Matrix4f moj, Matrix4f joml) {
- ((Matrix4fExtension)(Object) moj).flywheel$store(joml);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/extension/MatrixWrite.java b/src/main/java/com/jozufozu/flywheel/extension/MatrixWrite.java
deleted file mode 100644
index 15dead550..000000000
--- a/src/main/java/com/jozufozu/flywheel/extension/MatrixWrite.java
+++ /dev/null
@@ -1,32 +0,0 @@
-package com.jozufozu.flywheel.extension;
-
-import java.nio.ByteBuffer;
-
-import com.mojang.math.Matrix3f;
-import com.mojang.math.Matrix4f;
-
-/**
- * @see com.jozufozu.flywheel.mixin.matrix.Matrix3fMixin
- * @see com.jozufozu.flywheel.mixin.matrix.Matrix4fMixin
- */
-public interface MatrixWrite {
-
- /**
- * Write the contents of this object into sequential memory starting at the given address.
- */
- void flywheel$writeUnsafe(long ptr);
-
- void flywheel$write(ByteBuffer buf);
-
- static void write(Matrix4f matrix, ByteBuffer buf) {
- ((MatrixWrite) (Object) matrix).flywheel$write(buf);
- }
-
- static void writeUnsafe(Matrix4f matrix, long ptr) {
- ((MatrixWrite) (Object) matrix).flywheel$writeUnsafe(ptr);
- }
-
- static void writeUnsafe(Matrix3f matrix, long ptr) {
- ((MatrixWrite) (Object) matrix).flywheel$writeUnsafe(ptr);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java
index 9cce9fd44..5a4998210 100644
--- a/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java
+++ b/src/main/java/com/jozufozu/flywheel/light/LightUpdater.java
@@ -6,8 +6,9 @@ import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.stream.Stream;
import com.jozufozu.flywheel.backend.Backend;
-import com.jozufozu.flywheel.backend.instancing.ParallelTaskEngine;
-import com.jozufozu.flywheel.util.WeakHashSet;
+import com.jozufozu.flywheel.backend.instancing.ParallelTaskExecutor;
+import com.jozufozu.flywheel.backend.instancing.WorkGroup;
+import com.jozufozu.flywheel.util.FlwUtil;
import com.jozufozu.flywheel.util.WorldAttached;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
@@ -27,7 +28,7 @@ import net.minecraft.world.level.LightLayer;
public class LightUpdater {
private static final WorldAttached LEVELS = new WorldAttached<>(LightUpdater::new);
- private final ParallelTaskEngine taskEngine;
+ private final ParallelTaskExecutor taskExecutor;
public static LightUpdater get(LevelAccessor level) {
if (LightUpdated.receivesLightUpdates(level)) {
@@ -41,12 +42,12 @@ public class LightUpdater {
private final LevelAccessor level;
- private final WeakHashSet tickingLightListeners = new WeakHashSet<>();
+ private final Set tickingLightListeners = FlwUtil.createWeakHashSet();
private final WeakContainmentMultiMap sections = new WeakContainmentMultiMap<>();
private final WeakContainmentMultiMap chunks = new WeakContainmentMultiMap<>();
public LightUpdater(LevelAccessor level) {
- taskEngine = Backend.getTaskEngine();
+ taskExecutor = Backend.getTaskExecutor();
this.level = level;
}
@@ -66,14 +67,14 @@ public class LightUpdater {
private void tickParallel() {
Queue listeners = new ConcurrentLinkedQueue<>();
- taskEngine.group("LightUpdater")
+ WorkGroup.builder()
.addTasks(tickingLightListeners.stream(), listener -> {
if (listener.tickLightListener()) {
listeners.add(listener);
}
})
.onComplete(() -> listeners.forEach(this::addListener))
- .submit();
+ .execute(taskExecutor);
}
/**
diff --git a/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java b/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java
index ae6c5ea61..dcba34350 100644
--- a/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java
+++ b/src/main/java/com/jozufozu/flywheel/light/WeakContainmentMultiMap.java
@@ -6,7 +6,7 @@ import java.util.Set;
import java.util.WeakHashMap;
import java.util.function.LongConsumer;
-import com.jozufozu.flywheel.util.WeakHashSet;
+import com.jozufozu.flywheel.util.FlwUtil;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -15,7 +15,7 @@ import it.unimi.dsi.fastutil.longs.LongSet;
public class WeakContainmentMultiMap extends AbstractCollection {
- private final Long2ObjectMap> forward;
+ private final Long2ObjectMap> forward;
private final WeakHashMap reverse;
public WeakContainmentMultiMap() {
@@ -38,7 +38,7 @@ public class WeakContainmentMultiMap extends AbstractCollection {
LongSet containmentSet = reverse.computeIfAbsent(listener, $ -> new LongRBTreeSet());
containmentSet.forEach((LongConsumer) l -> {
- WeakHashSet listeners = forward.get(l);
+ Set listeners = forward.get(l);
if (listeners != null) listeners.remove(listener);
});
@@ -53,7 +53,7 @@ public class WeakContainmentMultiMap extends AbstractCollection {
}
public void put(long sectionPos, T listener) {
- forward.computeIfAbsent(sectionPos, $ -> new WeakHashSet<>()).add(listener);
+ forward.computeIfAbsent(sectionPos, $ -> FlwUtil.createWeakHashSet()).add(listener);
}
@Override
@@ -62,7 +62,7 @@ public class WeakContainmentMultiMap extends AbstractCollection {
if (containmentSet != null) {
containmentSet.forEach((LongConsumer) l -> {
- WeakHashSet listeners = forward.get(l);
+ Set listeners = forward.get(l);
if (listeners != null) listeners.remove(o);
});
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java
index 09e380de1..da170f6f8 100644
--- a/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java
+++ b/src/main/java/com/jozufozu/flywheel/mixin/RenderTypeMixin.java
@@ -18,7 +18,7 @@ public class RenderTypeMixin implements RenderTypeExtension {
@NotNull
public DrawBufferSet flywheel$getDrawBufferSet() {
if (flywheel$drawBufferSet == null) {
- flywheel$drawBufferSet = new DrawBufferSet(((RenderType) (Object) this).format());
+ flywheel$drawBufferSet = new DrawBufferSet((RenderType) (Object) this);
}
return flywheel$drawBufferSet;
}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fAccessor.java
new file mode 100644
index 000000000..cab5194df
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fAccessor.java
@@ -0,0 +1,36 @@
+package com.jozufozu.flywheel.mixin.matrix;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import com.mojang.math.Matrix3f;
+
+@Mixin(Matrix3f.class)
+public interface Matrix3fAccessor {
+ @Accessor("m00")
+ float flywheel$m00();
+
+ @Accessor("m01")
+ float flywheel$m01();
+
+ @Accessor("m02")
+ float flywheel$m02();
+
+ @Accessor("m10")
+ float flywheel$m10();
+
+ @Accessor("m11")
+ float flywheel$m11();
+
+ @Accessor("m12")
+ float flywheel$m12();
+
+ @Accessor("m20")
+ float flywheel$m20();
+
+ @Accessor("m21")
+ float flywheel$m21();
+
+ @Accessor("m22")
+ float flywheel$m22();
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
deleted file mode 100644
index 2690b8f99..000000000
--- a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix3fMixin.java
+++ /dev/null
@@ -1,55 +0,0 @@
-package com.jozufozu.flywheel.mixin.matrix;
-
-import java.nio.ByteBuffer;
-
-import org.lwjgl.system.MemoryUtil;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import com.jozufozu.flywheel.extension.Matrix3fExtension;
-import com.jozufozu.flywheel.extension.MatrixWrite;
-import com.mojang.math.Matrix3f;
-
-@Mixin(Matrix3f.class)
-public abstract class Matrix3fMixin implements MatrixWrite, Matrix3fExtension {
- @Shadow protected float m00;
- @Shadow protected float m01;
- @Shadow protected float m02;
- @Shadow protected float m10;
- @Shadow protected float m11;
- @Shadow protected float m12;
- @Shadow protected float m20;
- @Shadow protected float m21;
- @Shadow protected float m22;
-
- @Override
- public void flywheel$writeUnsafe(long ptr) {
- MemoryUtil.memPutFloat(ptr, m00);
- MemoryUtil.memPutFloat(ptr + 4, m10);
- MemoryUtil.memPutFloat(ptr + 8, m20);
- MemoryUtil.memPutFloat(ptr + 12, m01);
- MemoryUtil.memPutFloat(ptr + 16, m11);
- MemoryUtil.memPutFloat(ptr + 20, m21);
- MemoryUtil.memPutFloat(ptr + 24, m02);
- MemoryUtil.memPutFloat(ptr + 28, m12);
- MemoryUtil.memPutFloat(ptr + 32, m22);
- }
-
- @Override
- public void flywheel$write(ByteBuffer buffer) {
- buffer.putFloat(m00);
- buffer.putFloat(m10);
- buffer.putFloat(m20);
- buffer.putFloat(m01);
- buffer.putFloat(m11);
- buffer.putFloat(m21);
- buffer.putFloat(m02);
- buffer.putFloat(m12);
- buffer.putFloat(m22);
- }
-
- @Override
- public com.jozufozu.flywheel.util.joml.Matrix3f flywheel$store(com.jozufozu.flywheel.util.joml.Matrix3f matrix) {
- return matrix.set(m00, m10, m20, m01, m11, m21, m02, m12, m22);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fAccessor.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fAccessor.java
new file mode 100644
index 000000000..8da1c56f1
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fAccessor.java
@@ -0,0 +1,57 @@
+package com.jozufozu.flywheel.mixin.matrix;
+
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.gen.Accessor;
+
+import com.mojang.math.Matrix4f;
+
+@Mixin(Matrix4f.class)
+public interface Matrix4fAccessor {
+ @Accessor("m00")
+ float flywheel$m00();
+
+ @Accessor("m01")
+ float flywheel$m01();
+
+ @Accessor("m02")
+ float flywheel$m02();
+
+ @Accessor("m03")
+ float flywheel$m03();
+
+ @Accessor("m10")
+ float flywheel$m10();
+
+ @Accessor("m11")
+ float flywheel$m11();
+
+ @Accessor("m12")
+ float flywheel$m12();
+
+ @Accessor("m13")
+ float flywheel$m13();
+
+ @Accessor("m20")
+ float flywheel$m20();
+
+ @Accessor("m21")
+ float flywheel$m21();
+
+ @Accessor("m22")
+ float flywheel$m22();
+
+ @Accessor("m23")
+ float flywheel$m23();
+
+ @Accessor("m30")
+ float flywheel$m30();
+
+ @Accessor("m31")
+ float flywheel$m31();
+
+ @Accessor("m32")
+ float flywheel$m32();
+
+ @Accessor("m33")
+ float flywheel$m33();
+}
diff --git a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java b/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
deleted file mode 100644
index 542e71929..000000000
--- a/src/main/java/com/jozufozu/flywheel/mixin/matrix/Matrix4fMixin.java
+++ /dev/null
@@ -1,80 +0,0 @@
-package com.jozufozu.flywheel.mixin.matrix;
-
-import java.nio.ByteBuffer;
-
-import org.lwjgl.system.MemoryUtil;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import com.jozufozu.flywheel.extension.Matrix4fExtension;
-import com.jozufozu.flywheel.extension.MatrixWrite;
-import com.mojang.math.Matrix4f;
-
-@Mixin(Matrix4f.class)
-public abstract class Matrix4fMixin implements MatrixWrite, Matrix4fExtension {
- @Shadow protected float m00;
- @Shadow protected float m01;
- @Shadow protected float m02;
- @Shadow protected float m03;
- @Shadow protected float m10;
- @Shadow protected float m11;
- @Shadow protected float m12;
- @Shadow protected float m13;
- @Shadow protected float m20;
- @Shadow protected float m21;
- @Shadow protected float m22;
- @Shadow protected float m23;
- @Shadow protected float m30;
- @Shadow protected float m31;
- @Shadow protected float m32;
- @Shadow protected float m33;
-
- @Override
- public void flywheel$writeUnsafe(long ptr) {
- MemoryUtil.memPutFloat(ptr, m00);
- MemoryUtil.memPutFloat(ptr + 4, m10);
- MemoryUtil.memPutFloat(ptr + 8, m20);
- MemoryUtil.memPutFloat(ptr + 12, m30);
- MemoryUtil.memPutFloat(ptr + 16, m01);
- MemoryUtil.memPutFloat(ptr + 20, m11);
- MemoryUtil.memPutFloat(ptr + 24, m21);
- MemoryUtil.memPutFloat(ptr + 28, m31);
- MemoryUtil.memPutFloat(ptr + 32, m02);
- MemoryUtil.memPutFloat(ptr + 36, m12);
- MemoryUtil.memPutFloat(ptr + 40, m22);
- MemoryUtil.memPutFloat(ptr + 44, m32);
- MemoryUtil.memPutFloat(ptr + 48, m03);
- MemoryUtil.memPutFloat(ptr + 52, m13);
- MemoryUtil.memPutFloat(ptr + 56, m23);
- MemoryUtil.memPutFloat(ptr + 60, m33);
- }
-
- @Override
- public void flywheel$write(ByteBuffer buf) {
- buf.putFloat(m00);
- buf.putFloat(m10);
- buf.putFloat(m20);
- buf.putFloat(m30);
- buf.putFloat(m01);
- buf.putFloat(m11);
- buf.putFloat(m21);
- buf.putFloat(m31);
- buf.putFloat(m02);
- buf.putFloat(m12);
- buf.putFloat(m22);
- buf.putFloat(m32);
- buf.putFloat(m03);
- buf.putFloat(m13);
- buf.putFloat(m23);
- buf.putFloat(m33);
- }
-
- @Override
- public com.jozufozu.flywheel.util.joml.Matrix4f flywheel$store(com.jozufozu.flywheel.util.joml.Matrix4f matrix) {
- return matrix.set(
- m00, m10, m20, m30,
- m01, m11, m21, m31,
- m02, m12, m22, m32,
- m03, m13, m23, m33);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/Color.java b/src/main/java/com/jozufozu/flywheel/util/Color.java
deleted file mode 100644
index e6824ec61..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/Color.java
+++ /dev/null
@@ -1,309 +0,0 @@
-package com.jozufozu.flywheel.util;
-
-import java.util.function.UnaryOperator;
-
-import org.jetbrains.annotations.NotNull;
-
-import com.google.common.hash.Hashing;
-import com.mojang.math.Vector3f;
-
-import net.minecraft.util.Mth;
-import net.minecraft.world.phys.Vec3;
-
-@SuppressWarnings("PointlessBitwiseExpression")
-public class Color {
- public final static Color TRANSPARENT_BLACK = new Color(0, 0, 0, 0).setImmutable();
- public final static Color BLACK = new Color(0, 0, 0).setImmutable();
- public final static Color WHITE = new Color(255, 255, 255).setImmutable();
- public final static Color RED = new Color(255, 0, 0).setImmutable();
- public final static Color GREEN = new Color(0, 255, 0).setImmutable();
- public final static Color SPRING_GREEN = new Color(0, 255, 187).setImmutable();
-
- protected boolean mutable = true;
- protected int value;
-
- public Color(int r, int g, int b) {
- this(r, g, b, 0xff);
- }
-
- public Color(int r, int g, int b, int a) {
- value = ((a & 0xff) << 24) |
- ((r & 0xff) << 16) |
- ((g & 0xff) << 8) |
- ((b & 0xff) << 0);
- }
-
- public Color(float r, float g, float b, float a) {
- this(
- (int) (0.5 + 0xff * Mth.clamp(r, 0, 1)),
- (int) (0.5 + 0xff * Mth.clamp(g, 0, 1)),
- (int) (0.5 + 0xff * Mth.clamp(b, 0, 1)),
- (int) (0.5 + 0xff * Mth.clamp(a, 0, 1))
- );
- }
-
- public Color(int rgba) {
- value = rgba;
- }
-
- public Color(int rgb, boolean hasAlpha) {
- if (hasAlpha) {
- value = rgb;
- } else {
- value = rgb | 0xff_000000;
- }
- }
-
- public Color copy() {
- return copy(true);
- }
-
- public Color copy(boolean mutable) {
- if (mutable)
- return new Color(value);
- else
- return new Color(value).setImmutable();
- }
-
- /**
- * Mark this color as immutable. Attempting to mutate this color in the future
- * will instead cause a copy to be created that can me modified.
- */
- public Color setImmutable() {
- this.mutable = false;
- return this;
- }
-
- /**
- * @return the red component in the range 0-255.
- * @see #getRGB
- */
- public int getRed() {
- return (getRGB() >> 16) & 0xff;
- }
-
- /**
- * @return the green component in the range 0-255.
- * @see #getRGB
- */
- public int getGreen() {
- return (getRGB() >> 8) & 0xff;
- }
-
- /**
- * @return the blue component in the range 0-255.
- * @see #getRGB
- */
- public int getBlue() {
- return (getRGB() >> 0) & 0xff;
- }
-
- /**
- * @return the alpha component in the range 0-255.
- * @see #getRGB
- */
- public int getAlpha() {
- return (getRGB() >> 24) & 0xff;
- }
-
- /**
- * @return the red component in the range 0-1f.
- */
- public float getRedAsFloat() {
- return getRed() / 255f;
- }
-
- /**
- * @return the green component in the range 0-1f.
- */
- public float getGreenAsFloat() {
- return getGreen() / 255f;
- }
-
- /**
- * @return the blue component in the range 0-1f.
- */
- public float getBlueAsFloat() {
- return getBlue() / 255f;
- }
-
- /**
- * @return the alpha component in the range 0-1f.
- */
- public float getAlphaAsFloat() {
- return getAlpha() / 255f;
- }
-
- /**
- * Returns the RGB value representing this color
- * (Bits 24-31 are alpha, 16-23 are red, 8-15 are green, 0-7 are blue).
- * @return the RGB value of the color
- */
- public int getRGB() {
- return value;
- }
-
- public Vec3 asVector() {
- return new Vec3(getRedAsFloat(), getGreenAsFloat(), getBlueAsFloat());
- }
-
- public Vector3f asVectorF() {
- return new Vector3f(getRedAsFloat(), getGreenAsFloat(), getBlueAsFloat());
- }
-
- public Color setRed(int r) {
- return ensureMutable().setRedUnchecked(r);
- }
-
- public Color setGreen(int g) {
- return ensureMutable().setGreenUnchecked(g);
- }
-
- public Color setBlue(int b) {
- return ensureMutable().setBlueUnchecked(b);
- }
-
- public Color setAlpha(int a) {
- return ensureMutable().setAlphaUnchecked(a);
- }
-
- public Color setRed(float r) {
- return ensureMutable().setRedUnchecked((int) (0xff * Mth.clamp(r, 0, 1)));
- }
-
- public Color setGreen(float g) {
- return ensureMutable().setGreenUnchecked((int) (0xff * Mth.clamp(g, 0, 1)));
- }
-
- public Color setBlue(float b) {
- return ensureMutable().setBlueUnchecked((int) (0xff * Mth.clamp(b, 0, 1)));
- }
-
- public Color setAlpha(float a) {
- return ensureMutable().setAlphaUnchecked((int) (0xff * Mth.clamp(a, 0, 1)));
- }
-
- public Color scaleAlpha(float factor) {
- return ensureMutable().setAlphaUnchecked((int) (getAlpha() * Mth.clamp(factor, 0, 1)));
- }
-
- public Color mixWith(Color other, float weight) {
- return ensureMutable()
- .setRedUnchecked((int) (getRed() + (other.getRed() - getRed()) * weight))
- .setGreenUnchecked((int) (getGreen() + (other.getGreen() - getGreen()) * weight))
- .setBlueUnchecked((int) (getBlue() + (other.getBlue() - getBlue()) * weight))
- .setAlphaUnchecked((int) (getAlpha() + (other.getAlpha() - getAlpha()) * weight));
- }
-
- public Color darker() {
- int a = getAlpha();
- return ensureMutable().mixWith(BLACK, .25f).setAlphaUnchecked(a);
- }
-
- public Color brighter() {
- int a = getAlpha();
- return ensureMutable().mixWith(WHITE, .25f).setAlphaUnchecked(a);
- }
-
- public Color setValue(int value) {
- return ensureMutable().setValueUnchecked(value);
- }
-
- public Color modifyValue(UnaryOperator function) {
- int newValue = function.apply(value);
- if (newValue == value)
- return this;
-
- return ensureMutable().setValueUnchecked(newValue);
- }
-
- // ********* //
-
- protected Color ensureMutable() {
- if (this.mutable)
- return this;
-
- return new Color(this.value);
- }
-
- protected Color setRedUnchecked(int r) {
- this.value = (this.value & 0xff_00ffff) | ((r & 0xff) << 16);
- return this;
- }
-
- protected Color setGreenUnchecked(int g) {
- this.value = (this.value & 0xff_ff00ff) | ((g & 0xff) << 8);
- return this;
- }
-
- protected Color setBlueUnchecked(int b) {
- this.value = (this.value & 0xff_ffff00) | ((b & 0xff) << 0);
- return this;
- }
-
- protected Color setAlphaUnchecked(int a) {
- this.value = (this.value & 0x00_ffffff) | ((a & 0xff) << 24);
- return this;
- }
-
- protected Color setValueUnchecked(int value) {
- this.value = value;
- return this;
- }
-
- // ********* //
-
- public static Color mixColors(@NotNull Color c1, @NotNull Color c2, float w) {
- return new Color(
- (int) (c1.getRed() + (c2.getRed() - c1.getRed()) * w),
- (int) (c1.getGreen() + (c2.getGreen() - c1.getGreen()) * w),
- (int) (c1.getBlue() + (c2.getBlue() - c1.getBlue()) * w),
- (int) (c1.getAlpha() + (c2.getAlpha() - c1.getAlpha()) * w)
- );
- }
-
- public static int mixColors(int color1, int color2, float w) {
- int a1 = (color1 >> 24);
- int r1 = (color1 >> 16) & 0xFF;
- int g1 = (color1 >> 8) & 0xFF;
- int b1 = color1 & 0xFF;
- int a2 = (color2 >> 24);
- int r2 = (color2 >> 16) & 0xFF;
- int g2 = (color2 >> 8) & 0xFF;
- int b2 = color2 & 0xFF;
-
- return
- ((int) (a1 + (a2 - a1) * w) << 24) +
- ((int) (r1 + (r2 - r1) * w) << 16) +
- ((int) (g1 + (g2 - g1) * w) << 8) +
- ((int) (b1 + (b2 - b1) * w) << 0);
- }
-
- public static Color rainbowColor(int timeStep) {
- int localTimeStep = Math.abs(timeStep) % 1536;
- int timeStepInPhase = localTimeStep % 256;
- int phaseBlue = localTimeStep / 256;
- int red = colorInPhase(phaseBlue + 4, timeStepInPhase);
- int green = colorInPhase(phaseBlue + 2, timeStepInPhase);
- int blue = colorInPhase(phaseBlue, timeStepInPhase);
- return new Color(red, green, blue);
- }
-
- private static int colorInPhase(int phase, int progress) {
- phase = phase % 6;
- if (phase <= 1)
- return 0;
- if (phase == 2)
- return progress;
- if (phase <= 4)
- return 255;
- else
- return 255 - progress;
- }
-
- public static Color generateFromLong(long l) {
- return rainbowColor(Hashing.crc32().hashLong(l).asInt())
- .mixWith(WHITE, 0.5f);
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
index be55e6518..b40e70427 100644
--- a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java
@@ -1,7 +1,10 @@
package com.jozufozu.flywheel.util;
import java.util.Arrays;
+import java.util.Collections;
import java.util.Map;
+import java.util.Set;
+import java.util.WeakHashMap;
import java.util.stream.Stream;
import com.jozufozu.flywheel.mixin.BlockEntityRenderDispatcherAccessor;
@@ -81,4 +84,8 @@ public class FlwUtil {
public static Stream mapValues(Map, R> map) {
return map.values().stream();
}
+
+ public static Set createWeakHashSet() {
+ return Collections.newSetFromMap(new WeakHashMap<>());
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java b/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java
new file mode 100644
index 000000000..dbd1c7b12
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java
@@ -0,0 +1,116 @@
+package com.jozufozu.flywheel.util;
+
+import java.nio.ByteBuffer;
+
+import org.lwjgl.system.MemoryUtil;
+
+import com.jozufozu.flywheel.mixin.matrix.Matrix3fAccessor;
+import com.jozufozu.flywheel.mixin.matrix.Matrix4fAccessor;
+import com.mojang.math.Matrix3f;
+import com.mojang.math.Matrix4f;
+
+public class MatrixUtil {
+ public static void write(Matrix4f matrix, ByteBuffer buf) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ buf.putFloat(m.flywheel$m00());
+ buf.putFloat(m.flywheel$m10());
+ buf.putFloat(m.flywheel$m20());
+ buf.putFloat(m.flywheel$m30());
+ buf.putFloat(m.flywheel$m01());
+ buf.putFloat(m.flywheel$m11());
+ buf.putFloat(m.flywheel$m21());
+ buf.putFloat(m.flywheel$m31());
+ buf.putFloat(m.flywheel$m02());
+ buf.putFloat(m.flywheel$m12());
+ buf.putFloat(m.flywheel$m22());
+ buf.putFloat(m.flywheel$m32());
+ buf.putFloat(m.flywheel$m03());
+ buf.putFloat(m.flywheel$m13());
+ buf.putFloat(m.flywheel$m23());
+ buf.putFloat(m.flywheel$m33());
+ }
+
+ public static void writeUnsafe(Matrix4f matrix, long ptr) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ MemoryUtil.memPutFloat(ptr, m.flywheel$m00());
+ MemoryUtil.memPutFloat(ptr + 4, m.flywheel$m10());
+ MemoryUtil.memPutFloat(ptr + 8, m.flywheel$m20());
+ MemoryUtil.memPutFloat(ptr + 12, m.flywheel$m30());
+ MemoryUtil.memPutFloat(ptr + 16, m.flywheel$m01());
+ MemoryUtil.memPutFloat(ptr + 20, m.flywheel$m11());
+ MemoryUtil.memPutFloat(ptr + 24, m.flywheel$m21());
+ MemoryUtil.memPutFloat(ptr + 28, m.flywheel$m31());
+ MemoryUtil.memPutFloat(ptr + 32, m.flywheel$m02());
+ MemoryUtil.memPutFloat(ptr + 36, m.flywheel$m12());
+ MemoryUtil.memPutFloat(ptr + 40, m.flywheel$m22());
+ MemoryUtil.memPutFloat(ptr + 44, m.flywheel$m32());
+ MemoryUtil.memPutFloat(ptr + 48, m.flywheel$m03());
+ MemoryUtil.memPutFloat(ptr + 52, m.flywheel$m13());
+ MemoryUtil.memPutFloat(ptr + 56, m.flywheel$m23());
+ MemoryUtil.memPutFloat(ptr + 60, m.flywheel$m33());
+ }
+
+ public static void write(Matrix3f matrix, ByteBuffer buf) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ buf.putFloat(m.flywheel$m00());
+ buf.putFloat(m.flywheel$m10());
+ buf.putFloat(m.flywheel$m20());
+ buf.putFloat(m.flywheel$m01());
+ buf.putFloat(m.flywheel$m11());
+ buf.putFloat(m.flywheel$m21());
+ buf.putFloat(m.flywheel$m02());
+ buf.putFloat(m.flywheel$m12());
+ buf.putFloat(m.flywheel$m22());
+ }
+
+ public static void store(Matrix4f matrix, com.jozufozu.flywheel.util.joml.Matrix4f jomlMatrix) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ jomlMatrix.set(
+ m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), m.flywheel$m30(),
+ m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(), m.flywheel$m31(),
+ m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22(), m.flywheel$m32(),
+ m.flywheel$m03(), m.flywheel$m13(), m.flywheel$m23(), m.flywheel$m33()
+ );
+ }
+
+ public static com.jozufozu.flywheel.util.joml.Matrix4f toJoml(Matrix4f matrix) {
+ Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix;
+ return new com.jozufozu.flywheel.util.joml.Matrix4f(
+ m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), m.flywheel$m30(),
+ m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(), m.flywheel$m31(),
+ m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22(), m.flywheel$m32(),
+ m.flywheel$m03(), m.flywheel$m13(), m.flywheel$m23(), m.flywheel$m33()
+ );
+ }
+
+ public static void writeUnsafe(Matrix3f matrix, long ptr) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ MemoryUtil.memPutFloat(ptr, m.flywheel$m00());
+ MemoryUtil.memPutFloat(ptr + 4, m.flywheel$m10());
+ MemoryUtil.memPutFloat(ptr + 8, m.flywheel$m20());
+ MemoryUtil.memPutFloat(ptr + 12, m.flywheel$m01());
+ MemoryUtil.memPutFloat(ptr + 16, m.flywheel$m11());
+ MemoryUtil.memPutFloat(ptr + 20, m.flywheel$m21());
+ MemoryUtil.memPutFloat(ptr + 24, m.flywheel$m02());
+ MemoryUtil.memPutFloat(ptr + 28, m.flywheel$m12());
+ MemoryUtil.memPutFloat(ptr + 32, m.flywheel$m22());
+ }
+
+ public static void store(Matrix3f matrix, com.jozufozu.flywheel.util.joml.Matrix3f jomlMatrix) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ jomlMatrix.set(
+ m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(),
+ m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(),
+ m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22()
+ );
+ }
+
+ public static com.jozufozu.flywheel.util.joml.Matrix3f toJoml(Matrix3f matrix) {
+ Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix;
+ return new com.jozufozu.flywheel.util.joml.Matrix3f(
+ m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(),
+ m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(),
+ m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22()
+ );
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/util/WeakHashSet.java b/src/main/java/com/jozufozu/flywheel/util/WeakHashSet.java
deleted file mode 100644
index 281aaf418..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/WeakHashSet.java
+++ /dev/null
@@ -1,122 +0,0 @@
-package com.jozufozu.flywheel.util;
-
-import java.util.AbstractSet;
-import java.util.Collection;
-import java.util.Iterator;
-import java.util.WeakHashMap;
-
-import net.minecraft.util.Unit;
-
-public class WeakHashSet extends AbstractSet {
-
- WeakHashMap map;
-
- public WeakHashSet() {
- map = new WeakHashMap<>();
- }
-
- /**
- * Constructs a new set containing the elements in the specified
- * collection. The HashMap is created with default load factor
- * (0.75) and an initial capacity sufficient to contain the elements in
- * the specified collection.
- *
- * @param c the collection whose elements are to be placed into this set
- * @throws NullPointerException if the specified collection is null
- */
- public WeakHashSet(Collection extends T> c) {
- map = new WeakHashMap<>(Math.max((int) (c.size() / .75f) + 1, 16));
- addAll(c);
- }
-
- /**
- * Constructs a new, empty set; the backing HashMap instance has
- * the specified initial capacity and the specified load factor.
- *
- * @param initialCapacity the initial capacity of the hash map
- * @param loadFactor the load factor of the hash map
- * @throws IllegalArgumentException if the initial capacity is less
- * than zero, or if the load factor is nonpositive
- */
- public WeakHashSet(int initialCapacity, float loadFactor) {
- map = new WeakHashMap<>(initialCapacity, loadFactor);
- }
-
- /**
- * Constructs a new, empty set; the backing HashMap instance has
- * the specified initial capacity and default load factor (0.75).
- *
- * @param initialCapacity the initial capacity of the hash table
- * @throws IllegalArgumentException if the initial capacity is less
- * than zero
- */
- public WeakHashSet(int initialCapacity) {
- map = new WeakHashMap<>(initialCapacity);
- }
-
- @Override
- public Iterator iterator() {
- return map.keySet()
- .iterator();
- }
-
- @Override
- public int size() {
- return map.size();
- }
-
- @Override
- public boolean add(T t) {
- return map.put(t, Unit.INSTANCE) == null;
- }
-
- @Override
- public boolean remove(Object o) {
- return map.remove(o) != null;
- }
-
- @Override
- public boolean isEmpty() {
- return map.isEmpty();
- }
-
- @Override
- public boolean contains(Object o) {
- return map.containsKey(o);
- }
-
- @Override
- public Object[] toArray() {
- return map.keySet()
- .toArray();
- }
-
- @Override
- public boolean containsAll(Collection> c) {
- return stream().allMatch(map::containsKey);
- }
-
- @Override
- public boolean addAll(Collection extends T> c) {
- boolean out = false;
- for (T t : c) {
- out |= add(t);
- }
- return out;
- }
-
- @Override
- public boolean retainAll(Collection> c) {
- return false;
- }
-
- @Override
- public boolean removeAll(Collection> c) {
- return false;
- }
-
- @Override
- public void clear() {
- map.clear();
- }
-}
diff --git a/src/main/resources/flywheel.mixins.json b/src/main/resources/flywheel.mixins.json
index e190d6a30..502c4882d 100644
--- a/src/main/resources/flywheel.mixins.json
+++ b/src/main/resources/flywheel.mixins.json
@@ -25,8 +25,8 @@
"VertexFormatMixin",
"light.LightUpdateMixin",
"light.NetworkLightUpdateMixin",
- "matrix.Matrix3fMixin",
- "matrix.Matrix4fMixin",
+ "matrix.Matrix3fAccessor",
+ "matrix.Matrix4fAccessor",
"matrix.PoseStackMixin"
],
"injectors": {