parts, ShaderConstants constants) {
+ this.parts = parts;
this.type = type;
+ this.constants = constants;
int handle = GL20.glCreateShader(type.glEnum);
GlCompat.safeShaderSource(handle, source);
GL20.glCompileShader(handle);
-// File dir = new File(Minecraft.getInstance().gameDirectory, "flywheel_sources");
-// dir.mkdirs();
-// File file = new File(dir, name.toString().replaceAll("[:/]", "_"));
-// try (FileWriter writer = new FileWriter(file)) {
-// writer.write(source);
-// } catch (Exception e) {
-// e.printStackTrace();
-// }
+ dumpSource(source, type);
// String log = GL20.glGetShaderInfoLog(handle);
//
@@ -38,7 +41,7 @@ public class GlShader extends GlObject {
// }
if (GL20.glGetShaderi(handle, GL20.GL_COMPILE_STATUS) != GL20.GL_TRUE) {
- throw new ShaderLoadingException("Could not compile " + name + ". See log for details.");
+ throw new ShaderLoadingException("Could not compile " + getName() + ". See log for details.");
}
setHandle(handle);
@@ -49,4 +52,22 @@ public class GlShader extends GlObject {
GL20.glDeleteShader(handle);
}
+ public String getName() {
+ return parts.stream()
+ .map(ResourceLocation::toString)
+ .map(s -> s.replaceAll("/", "_")
+ .replaceAll(":", "\\$"))
+ .collect(Collectors.joining(";")) + ';' + Integer.toHexString(constants.hashCode());
+ }
+
+ private void dumpSource(String source, ShaderType type) {
+ File dir = new File(Minecraft.getInstance().gameDirectory, "flywheel_sources");
+ dir.mkdirs();
+ File file = new File(dir, type.getFileName(getName()));
+ try (FileWriter writer = new FileWriter(file)) {
+ writer.write(source);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderType.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderType.java
index 2b10e7578..ca42adc46 100644
--- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderType.java
+++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/ShaderType.java
@@ -3,21 +3,27 @@ package com.jozufozu.flywheel.backend.gl.shader;
import org.lwjgl.opengl.GL20;
public enum ShaderType {
- VERTEX("vertex", "VERTEX_SHADER", GL20.GL_VERTEX_SHADER),
- FRAGMENT("fragment", "FRAGMENT_SHADER", GL20.GL_FRAGMENT_SHADER),
+ VERTEX("vertex", "VERTEX_SHADER", "vert", GL20.GL_VERTEX_SHADER),
+ FRAGMENT("fragment", "FRAGMENT_SHADER", "frag", GL20.GL_FRAGMENT_SHADER),
;
public final String name;
public final String define;
+ public final String extension;
public final int glEnum;
- ShaderType(String name, String define, int glEnum) {
+ ShaderType(String name, String define, String extension, int glEnum) {
this.name = name;
this.define = define;
+ this.extension = extension;
this.glEnum = glEnum;
}
public String getDefineStatement() {
return "#define " + define + "\n";
}
+
+ public String getFileName(String baseName) {
+ return baseName + "." + extension;
+ }
}
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 32d2751c2..3a2ebdbae 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
@@ -20,7 +20,6 @@ import com.jozufozu.flywheel.core.CoreShaderInfoMap.CoreShaderInfo;
import com.jozufozu.flywheel.core.GameStateRegistry;
import com.jozufozu.flywheel.core.RenderContext;
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
-import com.jozufozu.flywheel.core.compile.ProgramContext;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.core.vertex.Formats;
import com.jozufozu.flywheel.util.Textures;
@@ -155,7 +154,7 @@ public class InstancingEngine implements Engine {
alphaDiscard = 0;
}
- P program = context.getProgram(new ProgramContext(Formats.POS_TEX_NORMAL, instanceType.getInstanceShader(), material.getVertexShader(), material.getFragmentShader(), alphaDiscard, coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
+ P program = context.getProgram(new ProgramCompiler.Context(Formats.POS_TEX_NORMAL, instanceType.getInstanceShader(), material.getVertexShader(), material.getFragmentShader(), alphaDiscard, coreShaderInfo.fogType(), GameStateRegistry.takeSnapshot()));
program.bind();
program.uploadUniforms(camX, camY, camZ, viewProjection, level);
diff --git a/src/main/java/com/jozufozu/flywheel/core/Contexts.java b/src/main/java/com/jozufozu/flywheel/core/Contexts.java
index ea12a3231..87092d959 100644
--- a/src/main/java/com/jozufozu/flywheel/core/Contexts.java
+++ b/src/main/java/com/jozufozu/flywheel/core/Contexts.java
@@ -1,13 +1,13 @@
package com.jozufozu.flywheel.core;
import com.jozufozu.flywheel.Flywheel;
+import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.core.compile.ProgramCompiler;
import com.jozufozu.flywheel.core.crumbling.CrumblingProgram;
import com.jozufozu.flywheel.core.shader.NormalDebugStateProvider;
import com.jozufozu.flywheel.core.shader.WorldProgram;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.Resolver;
-import com.jozufozu.flywheel.event.GatherContextEvent;
+import com.jozufozu.flywheel.core.source.SourceChecks;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
@@ -17,16 +17,23 @@ public class Contexts {
public static ProgramCompiler WORLD;
public static ProgramCompiler CRUMBLING;
- public static void flwInit(GatherContextEvent event) {
+ public static void init() {
GameStateRegistry.register(NormalDebugStateProvider.INSTANCE);
- FileResolution worldVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.WORLD, ".vert"));
- FileResolution worldFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.WORLD, ".frag"));
- FileResolution crumblingVertex = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"));
- FileResolution crumblingFragment = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"));
+ var checkFrag = SourceChecks.checkFunctionArity("flw_contextFragment", 0);
+ var checkVert = SourceChecks.checkFunctionArity("flw_contextVertex", 0);
- WORLD = ProgramCompiler.create(WorldProgram::new, worldVertex, worldFragment);
- CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, crumblingVertex, crumblingFragment);
+ var worldVertex = FileResolution.get(ResourceUtil.subPath(Names.WORLD, ".vert"))
+ .validateWith(checkVert);
+ var worldFragment = FileResolution.get(ResourceUtil.subPath(Names.WORLD, ".frag"))
+ .validateWith(checkFrag);
+ var crumblingVertex = FileResolution.get(ResourceUtil.subPath(Names.CRUMBLING, ".vert"))
+ .validateWith(checkVert);
+ var crumblingFragment = FileResolution.get(ResourceUtil.subPath(Names.CRUMBLING, ".frag"))
+ .validateWith(checkFrag);
+
+ WORLD = ProgramCompiler.create(WorldProgram::new, worldVertex, worldFragment, GLSLVersion.V330);
+ CRUMBLING = ProgramCompiler.create(CrumblingProgram::new, crumblingVertex, crumblingFragment, GLSLVersion.V330);
}
public static class Names {
diff --git a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java b/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java
index 67a5c2b44..7d797a5bb 100644
--- a/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java
+++ b/src/main/java/com/jozufozu/flywheel/core/GameStateRegistry.java
@@ -51,8 +51,4 @@ public class GameStateRegistry {
}
return shaderConstants;
}
-
- public static void _clear() {
- PROVIDERS.clear();
- }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/CompileUtil.java b/src/main/java/com/jozufozu/flywheel/core/compile/CompileUtil.java
index b97152197..19784f7fb 100644
--- a/src/main/java/com/jozufozu/flywheel/core/compile/CompileUtil.java
+++ b/src/main/java/com/jozufozu/flywheel/core/compile/CompileUtil.java
@@ -2,9 +2,14 @@ package com.jozufozu.flywheel.core.compile;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+import org.jetbrains.annotations.NotNull;
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
+import com.jozufozu.flywheel.core.source.SourceFile;
public class CompileUtil {
@@ -45,4 +50,11 @@ public class CompileUtil {
return 1;
}
+
+ @NotNull
+ public static String generateDebugName(SourceFile... stages) {
+ return Stream.of(stages)
+ .map(SourceFile::toString)
+ .collect(Collectors.joining(" -> "));
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java
index 92ddf67a3..bd88b465c 100644
--- a/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java
+++ b/src/main/java/com/jozufozu/flywheel/core/compile/FragmentCompiler.java
@@ -1,7 +1,6 @@
package com.jozufozu.flywheel.core.compile;
import java.util.Objects;
-import java.util.Optional;
import com.google.common.collect.ImmutableList;
import com.jozufozu.flywheel.backend.gl.GLSLVersion;
@@ -12,92 +11,57 @@ import com.jozufozu.flywheel.core.shader.ShaderConstants;
import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.source.FileIndexImpl;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.ShaderLoadingException;
import com.jozufozu.flywheel.core.source.SourceFile;
-import com.jozufozu.flywheel.core.source.error.ErrorReporter;
-import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
-import com.jozufozu.flywheel.core.source.parse.Variable;
+/**
+ * Handles compilation and deletion of fragment shaders.
+ */
public class FragmentCompiler extends Memoizer {
private final FileResolution contextShader;
+ private final GLSLVersion glslVersion;
- public FragmentCompiler(FileResolution contextShader) {
+ public FragmentCompiler(FileResolution contextShader, GLSLVersion glslVersion) {
this.contextShader = contextShader;
+ this.glslVersion = glslVersion;
}
@Override
protected GlShader _create(Context key) {
StringBuilder finalSource = new StringBuilder();
- finalSource.append(CompileUtil.generateHeader(GLSLVersion.V150, ShaderType.FRAGMENT));
+ finalSource.append(CompileUtil.generateHeader(glslVersion, ShaderType.FRAGMENT));
- key.getShaderConstants().writeInto(finalSource);
+ ShaderConstants shaderConstants = key.getShaderConstants();
+ shaderConstants.writeInto(finalSource);
finalSource.append('\n');
FileIndexImpl index = new FileIndexImpl();
- //
+ // MATERIAL
SourceFile materialShader = key.materialShader;
-
- Optional maybeMaterialFragment = materialShader.findFunction("flw_materialFragment");
-
- if (maybeMaterialFragment.isEmpty()) {
- ErrorReporter.generateMissingFunction(materialShader, "flw_materialFragment", "\"flw_materialFragment\" function not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderFunction materialFragment = maybeMaterialFragment.get();
- ImmutableList params = materialFragment.getParameters();
-
- if (params.size() != 0) {
- ErrorReporter.generateSpanError(materialFragment.getArgs(), "\"flw_materialFragment\" function must not have any arguments");
- throw new ShaderLoadingException();
- }
-
materialShader.generateFinalSource(index, finalSource);
- //
+ // CONTEXT
SourceFile contextShaderSource = contextShader.getFile();
-
- Optional maybeContextFragment = contextShaderSource.findFunction("flw_contextFragment");
-
- if (maybeContextFragment.isEmpty()) {
- ErrorReporter.generateMissingFunction(contextShaderSource, "flw_contextFragment", "\"flw_contextFragment\" function not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderFunction contextFragment = maybeContextFragment.get();
- params = contextFragment.getParameters();
-
- if (params.size() != 0) {
- ErrorReporter.generateSpanError(contextFragment.getArgs(), "\"flw_contextFragment\" function must not have any arguments");
- throw new ShaderLoadingException();
- }
-
contextShaderSource.generateFinalSource(index, finalSource);
- //
+ // MAIN
finalSource.append(generateFooter());
- return new GlShader(contextShader.getFile().name, ShaderType.FRAGMENT, finalSource.toString());
+ return new GlShader(finalSource.toString(), ShaderType.FRAGMENT, ImmutableList.of(materialShader.name, contextShaderSource.name), shaderConstants);
}
protected String generateFooter() {
- StringBuilder footer = new StringBuilder();
-
- footer.append("""
+ return """
void main() {
flw_materialFragment();
flw_contextFragment();
}
- """
- );
-
- return footer.toString();
+ """;
}
@Override
@@ -107,34 +71,12 @@ public class FragmentCompiler extends Memoizer shaders = new ObjectArrayList<>();
-
public ProgramAssembler(ResourceLocation name) {
this.name = name;
this.program = glCreateProgram();
@@ -49,13 +47,7 @@ public class ProgramAssembler {
return this;
}
- public ProgramAssembler deleteLinkedShaders() {
- shaders.forEach(GlShader::delete);
- return this;
- }
-
public ProgramAssembler attachShader(GlShader glShader) {
- shaders.add(glShader);
glAttachShader(this.program, glShader.handle());
return this;
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java
index 7792704dd..ed135bf6e 100644
--- a/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java
+++ b/src/main/java/com/jozufozu/flywheel/core/compile/ProgramCompiler.java
@@ -3,7 +3,11 @@ package com.jozufozu.flywheel.core.compile;
import java.util.ArrayList;
import java.util.List;
+import com.jozufozu.flywheel.api.vertex.VertexType;
+import com.jozufozu.flywheel.backend.gl.GLSLVersion;
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
+import com.jozufozu.flywheel.core.CoreShaderInfoMap;
+import com.jozufozu.flywheel.core.shader.StateSnapshot;
import com.jozufozu.flywheel.core.source.FileResolution;
import com.jozufozu.flywheel.event.ReloadRenderersEvent;
@@ -14,8 +18,11 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent;
* This class is responsible for compiling programs on the fly. An instance of this class will keep a cache of
* compiled programs, and will only compile a program if it is not already in the cache.
*
+ *
+ * A ProgramCompiler is also responsible for deleting programs and shaders on renderer reload.
+ *
*/
-public class ProgramCompiler extends Memoizer {
+public class ProgramCompiler extends Memoizer {
private static final List> ALL_COMPILERS = new ArrayList<>();
@@ -39,8 +46,8 @@ public class ProgramCompiler extends Memoizer The type of program to compile.
* @return A program compiler.
*/
- public static ProgramCompiler
create(GlProgram.Factory
factory, FileResolution vertexContextShader, FileResolution fragmentContextShader) {
- return new ProgramCompiler<>(factory, new VertexCompiler(vertexContextShader), new FragmentCompiler(fragmentContextShader));
+ public static
ProgramCompiler
create(GlProgram.Factory
factory, FileResolution vertexContextShader, FileResolution fragmentContextShader, GLSLVersion glslVersion) {
+ return new ProgramCompiler<>(factory, new VertexCompiler(vertexContextShader, glslVersion), new FragmentCompiler(fragmentContextShader, glslVersion));
}
/**
@@ -49,7 +56,7 @@ public class ProgramCompiler
extends Memoizer extends Memoizer extends Memoizer params = layoutVertex.getParameters();
-
- if (params.size() != 0) {
- ErrorReporter.generateSpanError(layoutVertex.getArgs(), "\"flw_layoutVertex\" function must not have any arguments");
- throw new ShaderLoadingException();
- }
+ // LAYOUT
+ var layoutShader = key.vertexType.getLayoutShader().getFile();
layoutShader.generateFinalSource(index, finalSource);
- //
-
- SourceFile instanceShader = key.instanceShader;
-
- Optional maybeInstanceVertex = instanceShader.findFunction("flw_instanceVertex");
-
- if (maybeInstanceVertex.isEmpty()) {
- ErrorReporter.generateMissingFunction(instanceShader, "flw_instanceVertex", "\"flw_instanceVertex\" function not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderFunction instanceVertex = maybeInstanceVertex.get();
- params = instanceVertex.getParameters();
-
- if (params.size() != 1) {
- ErrorReporter.generateSpanError(instanceVertex.getArgs(), "\"flw_instanceVertex\" function must have exactly 1 argument");
- throw new ShaderLoadingException();
- }
-
- Span instanceName = params.get(0).type;
- Optional maybeInstance = instanceShader.findStruct(instanceName);
-
- if (maybeInstance.isEmpty()) {
- ErrorReporter.generateMissingStruct(instanceShader, instanceName, "instance struct not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderStruct instance = maybeInstance.get();
+ // INSTANCE
+ var instanceShader = key.instanceShader;
instanceShader.generateFinalSource(index, finalSource);
- //
-
- SourceFile materialShader = key.materialShader;
-
- Optional maybeMaterialVertex = materialShader.findFunction("flw_materialVertex");
-
- if (maybeMaterialVertex.isEmpty()) {
- ErrorReporter.generateMissingFunction(materialShader, "flw_materialVertex", "\"flw_materialVertex\" function not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderFunction materialVertex = maybeMaterialVertex.get();
- params = materialVertex.getParameters();
-
- if (params.size() != 0) {
- ErrorReporter.generateSpanError(materialVertex.getArgs(), "\"flw_materialVertex\" function must not have any arguments");
- throw new ShaderLoadingException();
- }
+ // MATERIAL
+ var materialShader = key.materialShader;
materialShader.generateFinalSource(index, finalSource);
- //
-
- SourceFile contextShaderSource = contextShader.getFile();
-
- Optional maybeContextVertex = contextShaderSource.findFunction("flw_contextVertex");
-
- if (maybeContextVertex.isEmpty()) {
- ErrorReporter.generateMissingFunction(contextShaderSource, "flw_contextVertex", "\"flw_contextVertex\" function not defined");
- throw new ShaderLoadingException();
- }
-
- ShaderFunction contextVertex = maybeContextVertex.get();
- params = contextVertex.getParameters();
-
- if (params.size() != 0) {
- ErrorReporter.generateSpanError(contextVertex.getArgs(), "\"flw_contextVertex\" function must not have any arguments");
- throw new ShaderLoadingException();
- }
+ // CONTEXT
+ var contextShaderSource = contextShader.getFile();
contextShaderSource.generateFinalSource(index, finalSource);
- //
+ // MAIN
- finalSource.append(generateFooter(key.vertexType, instance));
+ var instanceStruct = instanceShader.findFunction("flw_instanceVertex")
+ .flatMap(f -> f.getParameterType(0)
+ .findStruct())
+ .orElseThrow();
+ finalSource.append(generateFooter(key.vertexType, instanceStruct));
- return new GlShader(instanceShader.name, ShaderType.VERTEX, finalSource.toString());
+ return new GlShader(finalSource.toString(), ShaderType.VERTEX, ImmutableList.of(layoutShader.name, instanceShader.name, materialShader.name, contextShaderSource.name), shaderConstants);
}
protected String generateFooter(VertexType vertexType, ShaderStruct instance) {
@@ -203,45 +131,12 @@ public class VertexCompiler extends Memoizer {
value.delete();
}
- public static class Context {
- /**
- * The vertex type to use.
- */
- private final VertexType vertexType;
-
- /**
- * The instance shader source.
- */
- private final SourceFile instanceShader;
-
- /**
- * The vertex material shader source.
- */
- private final SourceFile materialShader;
-
- /**
- * The shader constants to apply.
- */
- private final StateSnapshot ctx;
-
- public Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, StateSnapshot ctx) {
- this.vertexType = vertexType;
- this.instanceShader = instanceShader;
- this.materialShader = materialShader;
- this.ctx = ctx;
- }
-
- @Override
- public boolean equals(Object o) {
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- var that = (Context) o;
- return vertexType == that.vertexType && instanceShader == that.instanceShader && materialShader == that.materialShader && ctx.equals(that.ctx);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(vertexType, instanceShader, materialShader, ctx);
- }
+ /**
+ * @param vertexType The vertex type to use.
+ * @param instanceShader The instance shader source.
+ * @param materialShader The vertex material shader source.
+ * @param ctx The shader constants to apply.
+ */
+ public record Context(VertexType vertexType, SourceFile instanceShader, SourceFile materialShader, StateSnapshot ctx) {
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java b/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java
index d1fc82780..6a0e366ee 100644
--- a/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java
+++ b/src/main/java/com/jozufozu/flywheel/core/material/MaterialShaders.java
@@ -2,8 +2,7 @@ package com.jozufozu.flywheel.core.material;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.Resolver;
-import com.jozufozu.flywheel.event.GatherContextEvent;
+import com.jozufozu.flywheel.core.source.SourceChecks;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
@@ -13,10 +12,16 @@ public class MaterialShaders {
public static FileResolution DEFAULT_FRAGMENT;
public static FileResolution SHADED_VERTEX;
- public static void flwInit(GatherContextEvent event) {
- DEFAULT_VERTEX = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.DEFAULT, ".vert"));
- DEFAULT_FRAGMENT = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.DEFAULT, ".frag"));
- SHADED_VERTEX = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.SHADED, ".vert"));
+ public static void init() {
+ var checkVert = SourceChecks.checkFunctionArity("flw_materialVertex", 0);
+ var checkFrag = SourceChecks.checkFunctionArity("flw_materialFragment", 0);
+
+ DEFAULT_VERTEX = FileResolution.get(ResourceUtil.subPath(Names.DEFAULT, ".vert"))
+ .validateWith(checkVert);
+ DEFAULT_FRAGMENT = FileResolution.get(ResourceUtil.subPath(Names.DEFAULT, ".frag"))
+ .validateWith(checkFrag);
+ SHADED_VERTEX = FileResolution.get(ResourceUtil.subPath(Names.SHADED, ".vert"))
+ .validateWith(checkVert);
}
public static class Names {
diff --git a/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java b/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java
index ed56ab006..ece98bd05 100644
--- a/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java
+++ b/src/main/java/com/jozufozu/flywheel/core/shader/ShaderConstants.java
@@ -3,6 +3,7 @@ package com.jozufozu.flywheel.core.shader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
/**
* A class for manipulating a list of {@code #define} directives.
@@ -52,4 +53,17 @@ public class ShaderConstants {
acc.append('\n');
}
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ ShaderConstants that = (ShaderConstants) o;
+ return Objects.equals(definitions, that.definitions);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(definitions);
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/FileIndexImpl.java b/src/main/java/com/jozufozu/flywheel/core/source/FileIndexImpl.java
index 90aefb176..fcab6d684 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/FileIndexImpl.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/FileIndexImpl.java
@@ -33,7 +33,7 @@ public class FileIndexImpl implements FileIndex {
@Override
public boolean exists(SourceFile sourceFile) {
- return files.indexOf(sourceFile) != -1;
+ return files.contains(sourceFile);
}
@Override
@@ -68,10 +68,7 @@ public class FileIndexImpl implements FileIndex {
@Nullable
private ErrorBuilder parseCompilerError(String line) {
try {
- ErrorBuilder error = ErrorBuilder.fromLogLine(this, line);
- if (error != null) {
- return error;
- }
+ return ErrorBuilder.fromLogLine(this, line);
} catch (Exception ignored) {
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java
index 23bb7f617..8b4503391 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/FileResolution.java
@@ -1,11 +1,13 @@
package com.jozufozu.flywheel.core.source;
import java.util.ArrayList;
+import java.util.HashMap;
import java.util.List;
-import java.util.function.Consumer;
+import java.util.Map;
+import java.util.function.BiConsumer;
-import com.jozufozu.flywheel.backend.Backend;
import com.jozufozu.flywheel.core.source.error.ErrorBuilder;
+import com.jozufozu.flywheel.core.source.error.ErrorReporter;
import com.jozufozu.flywheel.core.source.span.Span;
import net.minecraft.resources.ResourceLocation;
@@ -21,17 +23,73 @@ import net.minecraft.resources.ResourceLocation;
*/
public class FileResolution {
+ private static final Map ALL = new HashMap<>();
+ private static boolean tooLate = false;
+
/**
- * Extra info about where this resolution is required. Includes ProgramSpecs and shader Spans.
+ * Extra info about where this resolution is required. Includes shader Spans.
*/
- private final List> extraCrashInfoProviders = new ArrayList<>();
+ private final List neededAt = new ArrayList<>();
+ private final List> checks = new ArrayList<>();
+
private final ResourceLocation fileLoc;
+
private SourceFile file;
FileResolution(ResourceLocation fileLoc) {
this.fileLoc = fileLoc;
}
+ public static FileResolution get(ResourceLocation file) {
+ if (!tooLate) {
+ return ALL.computeIfAbsent(file, FileResolution::new);
+ } else {
+ // Lock the map after resolution has run.
+ FileResolution fileResolution = ALL.get(file);
+
+ // ...so crash immediately if the file isn't found.
+ if (fileResolution == null) {
+ throw new ShaderLoadingException("could not find source for file: " + file);
+ }
+
+ return fileResolution;
+ }
+ }
+
+ /**
+ * Try and resolve all referenced source files, printing errors if any aren't found.
+ */
+ public static void run(ErrorReporter errorReporter, SourceFinder sources) {
+ for (FileResolution resolution : ALL.values()) {
+ resolution.resolveAndCheck(errorReporter, sources);
+ }
+
+ tooLate = true;
+ }
+
+ private void resolveAndCheck(ErrorReporter errorReporter, SourceFinder sources) {
+ file = sources.findSource(fileLoc);
+
+ if (file == null) {
+ ErrorBuilder builder = errorReporter.error(String.format("could not find source for file %s", fileLoc));
+ for (Span location : neededAt) {
+ builder.pointAtFile(location.getSourceFile())
+ .pointAt(location, 1);
+ }
+ } else {
+ runChecks(errorReporter);
+ }
+
+ // Let the GC do its thing
+ neededAt.clear();
+ }
+
+ private void runChecks(ErrorReporter errorReporter) {
+ for (var check : checks) {
+ check.accept(errorReporter, file);
+ }
+ }
+
public ResourceLocation getFileLoc() {
return fileLoc;
}
@@ -53,45 +111,13 @@ public class FileResolution {
* @param span A span where this file is referenced.
*/
public FileResolution addSpan(Span span) {
- extraCrashInfoProviders.add(builder -> builder.pointAtFile(span.getSourceFile())
- .pointAt(span, 1));
+ neededAt.add(span);
return this;
}
- public void addSpec(ResourceLocation name) {
- extraCrashInfoProviders.add(builder -> builder.extra("needed by spec: " + name + ".json"));
- }
-
- /**
- * Check to see if this file actually resolves to something.
- *
- *
- * Called after all files are loaded. If we can't find the file here, it doesn't exist.
- *
- *
- * @return True if this file is resolved.
- */
- boolean resolve(SourceFinder sources) {
- file = sources.findSource(fileLoc);
-
- if (file == null) {
- ErrorBuilder builder = ErrorBuilder.error(String.format("could not find source for file %s", fileLoc));
- for (Consumer consumer : extraCrashInfoProviders) {
- consumer.accept(builder);
- }
- Backend.LOGGER.error(builder.build());
-
- return false;
- }
-
- // Let the GC do its thing
- extraCrashInfoProviders.clear();
- return true;
- }
-
- void invalidate() {
- extraCrashInfoProviders.clear();
- file = null;
+ public FileResolution validateWith(BiConsumer check) {
+ checks.add(check);
+ return this;
}
@Override
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/Resolver.java b/src/main/java/com/jozufozu/flywheel/core/source/Resolver.java
deleted file mode 100644
index 9abea7354..000000000
--- a/src/main/java/com/jozufozu/flywheel/core/source/Resolver.java
+++ /dev/null
@@ -1,70 +0,0 @@
-package com.jozufozu.flywheel.core.source;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import net.minecraft.resources.ResourceLocation;
-
-/**
- * Manages deferred file resolution.
- *
- *
- * Interns all file names in shader sources and program specs, deduplicating the final lookups and allowing for more
- * dev-friendly error reporting.
- *
- *
- * @see FileResolution
- */
-public class Resolver {
-
- public static final Resolver INSTANCE = new Resolver();
-
- private final Map resolutions = new HashMap<>();
- private boolean hasRun = false;
-
- public FileResolution get(ResourceLocation file) {
- if (!hasRun) {
- return resolutions.computeIfAbsent(file, FileResolution::new);
- } else {
- // Lock the map after resolution has run.
- FileResolution fileResolution = resolutions.get(file);
-
- // ...so crash immediately if the file isn't found.
- if (fileResolution == null) {
- throw new RuntimeException("could not find source for file: " + file);
- }
-
- return fileResolution;
- }
- }
-
- /**
- * Try and resolve all referenced source files, printing errors if any aren't found.
- */
- public void run(SourceFinder sources) {
- boolean needsCrash = false;
- for (FileResolution resolution : resolutions.values()) {
- if (!resolution.resolve(sources)) {
- needsCrash = true;
- }
- }
-
- if (needsCrash) {
- throw new ShaderLoadingException("Failed to resolve all source files, see log for details");
- }
-
- hasRun = true;
- }
-
- /**
- * Invalidates all FileResolutions.
- *
- *
- * Called on resource reload.
- *
- */
- public void invalidate() {
- resolutions.values().forEach(FileResolution::invalidate);
- hasRun = false;
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/ShaderLoadingException.java b/src/main/java/com/jozufozu/flywheel/core/source/ShaderLoadingException.java
index 36ca1dc73..e09dfa99b 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/ShaderLoadingException.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/ShaderLoadingException.java
@@ -2,9 +2,6 @@ package com.jozufozu.flywheel.core.source;
public class ShaderLoadingException extends RuntimeException {
- public ShaderLoadingException() {
- }
-
public ShaderLoadingException(String message) {
super(message);
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java
index 8e657fe86..502d19bb2 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/ShaderSources.java
@@ -9,6 +9,7 @@ import java.util.Map;
import org.jetbrains.annotations.Nullable;
import com.google.common.collect.Lists;
+import com.jozufozu.flywheel.core.source.error.ErrorReporter;
import com.jozufozu.flywheel.util.ResourceUtil;
import com.jozufozu.flywheel.util.StringUtil;
@@ -20,14 +21,14 @@ import net.minecraft.server.packs.resources.ResourceManager;
* The main object for loading and parsing source files.
*/
public class ShaderSources implements SourceFinder {
- public static final String SHADER_DIR = "flywheel/shaders/";
+ public static final String SHADER_DIR = "flywheel/";
public static final ArrayList EXTENSIONS = Lists.newArrayList(".vert", ".vsh", ".frag", ".fsh", ".glsl");
private final Map shaderSources = new HashMap<>();
public final Index index;
- public ShaderSources(ResourceManager manager) {
+ public ShaderSources(ErrorReporter errorReporter, ResourceManager manager) {
Collection allShaders = manager.listResources(SHADER_DIR, s -> {
for (String ext : EXTENSIONS) {
if (s.endsWith(ext)) return true;
@@ -41,7 +42,7 @@ public class ShaderSources implements SourceFinder {
ResourceLocation name = ResourceUtil.removePrefixUnchecked(location, SHADER_DIR);
- shaderSources.put(name, new SourceFile(this, name, source));
+ shaderSources.put(name, new SourceFile(errorReporter, this, name, source));
} catch (IOException e) {
//
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java
new file mode 100644
index 000000000..a8247a33e
--- /dev/null
+++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceChecks.java
@@ -0,0 +1,57 @@
+package com.jozufozu.flywheel.core.source;
+
+import java.util.Optional;
+import java.util.function.BiConsumer;
+
+import org.jetbrains.annotations.Nullable;
+
+import com.google.common.collect.ImmutableList;
+import com.jozufozu.flywheel.core.source.error.ErrorReporter;
+import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
+import com.jozufozu.flywheel.core.source.parse.Variable;
+
+public class SourceChecks {
+
+ public static BiConsumer checkFunctionArity(String name, int arity) {
+ return (errorReporter, file) -> checkFunctionArity(errorReporter, file, name, arity);
+ }
+
+ public static BiConsumer checkFunctionParameterTypeExists(String name, int arity, int param) {
+ return (errorReporter, file) -> {
+ var func = checkFunctionArity(errorReporter, file, name, arity);
+
+ if (func == null) {
+ return;
+ }
+
+ var maybeStruct = func.getParameterType(param)
+ .findStruct();
+
+ if (maybeStruct.isEmpty()) {
+ errorReporter.generateMissingStruct(file, func.getParameterType(param), "struct not defined");
+ }
+ };
+ }
+
+ /**
+ * @return {@code null} if the function doesn't exist, or if the function has the wrong arity.
+ */
+ @Nullable
+ private static ShaderFunction checkFunctionArity(ErrorReporter errorReporter, SourceFile file, String name, int arity) {
+ Optional maybeFunc = file.findFunction(name);
+
+ if (maybeFunc.isEmpty()) {
+ errorReporter.generateMissingFunction(file, name, "\"" + name + "\" function not defined");
+ return null;
+ }
+
+ ShaderFunction func = maybeFunc.get();
+ ImmutableList params = func.getParameters();
+ if (params.size() != arity) {
+ errorReporter.generateFunctionArgumentCountError(name, arity, func.getArgs());
+ return null;
+ }
+
+ return func;
+ }
+}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java
index 35004c0d1..c76a08e88 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java
@@ -11,9 +11,11 @@ import java.util.regex.Matcher;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
+import com.jozufozu.flywheel.core.source.error.ErrorReporter;
import com.jozufozu.flywheel.core.source.parse.Import;
import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
import com.jozufozu.flywheel.core.source.parse.ShaderStruct;
+import com.jozufozu.flywheel.core.source.parse.Variable;
import com.jozufozu.flywheel.core.source.span.ErrorSpan;
import com.jozufozu.flywheel.core.source.span.Span;
import com.jozufozu.flywheel.core.source.span.StringSpan;
@@ -55,7 +57,7 @@ public class SourceFile {
*/
public final ImmutableList imports;
- public SourceFile(ShaderSources parent, ResourceLocation name, String source) {
+ public SourceFile(ErrorReporter errorReporter, ShaderSources parent, ResourceLocation name, String source) {
this.parent = parent;
this.name = name;
this.source = source;
@@ -64,7 +66,7 @@ public class SourceFile {
List elisions = new ArrayList<>();
- this.imports = parseImports(elisions);
+ this.imports = parseImports(errorReporter, elisions);
this.functions = parseFunctions();
this.structs = parseStructs();
@@ -233,7 +235,7 @@ public class SourceFile {
* Records the contents of the directive into an {@link Import} object, and marks the directive for elision.
* @param elisions
*/
- private ImmutableList parseImports(List elisions) {
+ private ImmutableList parseImports(ErrorReporter errorReporter, List elisions) {
Matcher uses = Import.PATTERN.matcher(source);
Set importedFiles = new HashSet<>();
@@ -245,9 +247,9 @@ public class SourceFile {
String fileName = file.get();
if (importedFiles.add(fileName)) {
- Import import1 = Import.create(Resolver.INSTANCE, use, file);
- if (import1 != null) {
- imports.add(import1);
+ var checked = Import.create(errorReporter, use, file);
+ if (checked != null) {
+ imports.add(checked);
}
}
@@ -280,4 +282,15 @@ public class SourceFile {
public String toString() {
return name.toString();
}
+
+ @Override
+ public boolean equals(Object o) {
+ // SourceFiles are only equal by reference.
+ return this == o;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorReporter.java b/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorReporter.java
index 9da3055ea..859ec71e2 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorReporter.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/error/ErrorReporter.java
@@ -1,5 +1,6 @@
package com.jozufozu.flywheel.core.source.error;
+import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@@ -13,58 +14,78 @@ import com.jozufozu.flywheel.util.FlwUtil;
public class ErrorReporter {
- public static void generateSpanError(Span span, String message) {
- SourceFile file = span.getSourceFile();
+ private final List reportedErrors = new ArrayList<>();
- String error = ErrorBuilder.error(message)
- .pointAtFile(file)
- .pointAt(span, 2)
- .build();
-
- Backend.LOGGER.error(error);
- }
-
- public static void generateFileError(SourceFile file, String message) {
- String error = ErrorBuilder.error(message)
- .pointAtFile(file)
- .build();
-
- Backend.LOGGER.error(error);
- }
-
- public static void generateMissingStruct(SourceFile file, Span vertexName, CharSequence msg) {
+ public void generateMissingStruct(SourceFile file, Span vertexName, CharSequence msg) {
generateMissingStruct(file, vertexName, msg, "");
}
- public static void generateMissingStruct(SourceFile file, Span vertexName, CharSequence msg, CharSequence hint) {
+ public void generateMissingStruct(SourceFile file, Span vertexName, CharSequence msg, CharSequence hint) {
Optional span = file.parent.index.getStructDefinitionsMatching(vertexName)
.stream()
.findFirst()
.map(ShaderStruct::getName);
- ErrorBuilder error = ErrorBuilder.error(msg)
+ this.error(msg)
.pointAtFile(file)
.pointAt(vertexName, 1)
.hintIncludeFor(span.orElse(null), hint);
-
- Backend.LOGGER.error(error.build());
}
- public static void generateMissingFunction(SourceFile file, CharSequence functionName, CharSequence msg) {
+ public void generateMissingFunction(SourceFile file, CharSequence functionName, CharSequence msg) {
generateMissingFunction(file, functionName, msg, "");
}
- public static void generateMissingFunction(SourceFile file, CharSequence functionName, CharSequence msg, CharSequence hint) {
+ public void generateMissingFunction(SourceFile file, CharSequence functionName, CharSequence msg, CharSequence hint) {
Optional span = file.parent.index.getFunctionDefinitionsMatching(functionName)
.stream()
.findFirst()
.map(ShaderFunction::getName);
- ErrorBuilder error = ErrorBuilder.error(msg)
+ this.error(msg)
.pointAtFile(file)
.hintIncludeFor(span.orElse(null), hint);
+ }
- Backend.LOGGER.error(error.build());
+ public ErrorBuilder generateFunctionArgumentCountError(String name, int requiredArguments, Span span) {
+ var msg = '"' + name + "\" function must ";
+
+ if (requiredArguments == 0) {
+ msg += "not have any arguments";
+ } else {
+ msg += "have exactly " + requiredArguments + " argument" + (requiredArguments == 1 ? "" : "s");
+ }
+
+ return generateSpanError(span, msg);
+ }
+
+ public ErrorBuilder generateSpanError(Span span, String message) {
+ SourceFile file = span.getSourceFile();
+
+ return error(message)
+ .pointAtFile(file)
+ .pointAt(span, 2);
+ }
+
+ public ErrorBuilder generateFileError(SourceFile file, String message) {
+ return error(message)
+ .pointAtFile(file);
+ }
+
+ public ErrorBuilder error(CharSequence msg) {
+ var out = ErrorBuilder.error(msg);
+ reportedErrors.add(out);
+ return out;
+ }
+
+ public boolean hasErrored() {
+ return !reportedErrors.isEmpty();
+ }
+
+ public void dump() {
+ for (var error : reportedErrors) {
+ Backend.LOGGER.error(error.build());
+ }
}
public static void printLines(CharSequence source) {
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java b/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java
index 90273e7f8..860617dac 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/parse/Import.java
@@ -6,7 +6,6 @@ import java.util.regex.Pattern;
import org.jetbrains.annotations.Nullable;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.Resolver;
import com.jozufozu.flywheel.core.source.SourceFile;
import com.jozufozu.flywheel.core.source.error.ErrorReporter;
import com.jozufozu.flywheel.core.source.span.Span;
@@ -26,16 +25,16 @@ public class Import extends AbstractShaderElement {
}
@Nullable
- public static Import create(Resolver resolver, Span self, Span file) {
+ public static Import create(ErrorReporter errorReporter, Span self, Span file) {
ResourceLocation fileLocation;
try {
fileLocation = new ResourceLocation(file.get());
} catch (ResourceLocationException e) {
- ErrorReporter.generateSpanError(file, "malformed source location");
+ errorReporter.generateSpanError(file, "malformed source location");
return null;
}
- return new Import(self, resolver.get(fileLocation), file);
+ return new Import(self, FileResolution.get(fileLocation), file);
}
public FileResolution getResolution() {
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/parse/ShaderFunction.java b/src/main/java/com/jozufozu/flywheel/core/source/parse/ShaderFunction.java
index b7e735589..134d0214f 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/parse/ShaderFunction.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/parse/ShaderFunction.java
@@ -52,6 +52,10 @@ public class ShaderFunction extends AbstractShaderElement {
return name + "(" + String.join(", ", args) + ")";
}
+ public Span getParameterType(int index) {
+ return parameters.get(index).type;
+ }
+
public ImmutableList getParameters() {
return parameters;
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java b/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java
index 61961a979..81b8e848a 100644
--- a/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java
+++ b/src/main/java/com/jozufozu/flywheel/core/source/span/Span.java
@@ -1,8 +1,11 @@
package com.jozufozu.flywheel.core.source.span;
+import java.util.Optional;
import java.util.regex.Matcher;
import com.jozufozu.flywheel.core.source.SourceFile;
+import com.jozufozu.flywheel.core.source.parse.ShaderFunction;
+import com.jozufozu.flywheel.core.source.parse.ShaderStruct;
/**
* A segment of code in a {@link SourceFile}.
@@ -121,4 +124,18 @@ public abstract class Span implements CharSequence {
public static Span fromMatcher(Span superSpan, Matcher m) {
return superSpan.subSpan(m.start(), m.end());
}
+
+ public Optional findStruct() {
+ if (isErr()) {
+ return Optional.empty();
+ }
+ return in.findStruct(this);
+ }
+
+ public Optional findFunction() {
+ if (isErr()) {
+ return Optional.empty();
+ }
+ return in.findFunction(this);
+ }
}
diff --git a/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java b/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java
index 41507dd0a..fdc5e4768 100644
--- a/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java
+++ b/src/main/java/com/jozufozu/flywheel/core/structs/InstanceShaders.java
@@ -2,8 +2,7 @@ package com.jozufozu.flywheel.core.structs;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.Resolver;
-import com.jozufozu.flywheel.event.GatherContextEvent;
+import com.jozufozu.flywheel.core.source.SourceChecks;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
@@ -12,9 +11,13 @@ public class InstanceShaders {
public static FileResolution MODEL;
public static FileResolution ORIENTED;
- public static void flwInit(GatherContextEvent event) {
- MODEL = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.MODEL, ".vert"));
- ORIENTED = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.ORIENTED, ".vert"));
+ public static void init() {
+ var check = SourceChecks.checkFunctionParameterTypeExists("flw_instanceVertex", 1, 0);
+
+ MODEL = FileResolution.get(ResourceUtil.subPath(Names.MODEL, ".vert"))
+ .validateWith(check);
+ ORIENTED = FileResolution.get(ResourceUtil.subPath(Names.ORIENTED, ".vert"))
+ .validateWith(check);
}
public static class Names {
diff --git a/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java b/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java
index 31fd55b64..ff3b8de25 100644
--- a/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java
+++ b/src/main/java/com/jozufozu/flywheel/core/vertex/LayoutShaders.java
@@ -2,8 +2,7 @@ package com.jozufozu.flywheel.core.vertex;
import com.jozufozu.flywheel.Flywheel;
import com.jozufozu.flywheel.core.source.FileResolution;
-import com.jozufozu.flywheel.core.source.Resolver;
-import com.jozufozu.flywheel.event.GatherContextEvent;
+import com.jozufozu.flywheel.core.source.SourceChecks;
import com.jozufozu.flywheel.util.ResourceUtil;
import net.minecraft.resources.ResourceLocation;
@@ -12,9 +11,14 @@ public class LayoutShaders {
public static FileResolution BLOCK;
public static FileResolution POS_TEX_NORMAL;
- public static void flwInit(GatherContextEvent event) {
- BLOCK = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.BLOCK, ".vert"));
- POS_TEX_NORMAL = Resolver.INSTANCE.get(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert"));
+ public static void init() {
+ var check = SourceChecks.checkFunctionArity("flw_layoutVertex", 0);
+
+ BLOCK = FileResolution.get(ResourceUtil.subPath(Names.BLOCK, ".vert"))
+ .validateWith(check);
+
+ POS_TEX_NORMAL = FileResolution.get(ResourceUtil.subPath(Names.POS_TEX_NORMAL, ".vert"))
+ .validateWith(check);
}
public static class Names {
diff --git a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
index 056966700..c2c5d806d 100644
--- a/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
+++ b/src/main/java/com/jozufozu/flywheel/event/ForgeEvents.java
@@ -6,6 +6,7 @@ import com.jozufozu.flywheel.light.LightUpdater;
import com.jozufozu.flywheel.util.WorldAttached;
import net.minecraft.client.Minecraft;
+import net.minecraft.client.player.LocalPlayer;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.client.event.RenderGameOverlayEvent;
import net.minecraftforge.event.TickEvent;
@@ -32,8 +33,10 @@ public class ForgeEvents {
@SubscribeEvent
public static void tickLight(TickEvent.ClientTickEvent e) {
- if (e.phase == TickEvent.Phase.END && Backend.isGameActive())
- LightUpdater.get(Minecraft.getInstance().level).tick();
+ if (e.phase == TickEvent.Phase.END && Backend.isGameActive()) {
+ LightUpdater.get(Minecraft.getInstance().level)
+ .tick();
+ }
}
}
diff --git a/src/main/java/com/jozufozu/flywheel/event/GatherContextEvent.java b/src/main/java/com/jozufozu/flywheel/event/GatherContextEvent.java
deleted file mode 100644
index ffbc76341..000000000
--- a/src/main/java/com/jozufozu/flywheel/event/GatherContextEvent.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package com.jozufozu.flywheel.event;
-
-import net.minecraftforge.eventbus.api.Event;
-import net.minecraftforge.fml.event.IModBusEvent;
-
-public class GatherContextEvent extends Event implements IModBusEvent {
-
- private final boolean firstLoad;
-
- public GatherContextEvent(boolean firstLoad) {
- this.firstLoad = firstLoad;
- }
-
- /**
- * @return true iff it is the first time the event is fired.
- */
- public boolean isFirstLoad() {
- return firstLoad;
- }
-}
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/api/fragment.glsl b/src/main/resources/assets/flywheel/flywheel/api/fragment.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/api/fragment.glsl
rename to src/main/resources/assets/flywheel/flywheel/api/fragment.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/api/vertex.glsl b/src/main/resources/assets/flywheel/flywheel/api/vertex.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/api/vertex.glsl
rename to src/main/resources/assets/flywheel/flywheel/api/vertex.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/context/common.vert b/src/main/resources/assets/flywheel/flywheel/context/common.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/context/common.vert
rename to src/main/resources/assets/flywheel/flywheel/context/common.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/context/crumbling.frag b/src/main/resources/assets/flywheel/flywheel/context/crumbling.frag
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/context/crumbling.frag
rename to src/main/resources/assets/flywheel/flywheel/context/crumbling.frag
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/context/crumbling.vert b/src/main/resources/assets/flywheel/flywheel/context/crumbling.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/context/crumbling.vert
rename to src/main/resources/assets/flywheel/flywheel/context/crumbling.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/context/world.frag b/src/main/resources/assets/flywheel/flywheel/context/world.frag
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/context/world.frag
rename to src/main/resources/assets/flywheel/flywheel/context/world.frag
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/context/world.vert b/src/main/resources/assets/flywheel/flywheel/context/world.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/context/world.vert
rename to src/main/resources/assets/flywheel/flywheel/context/world.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/instance/model.vert b/src/main/resources/assets/flywheel/flywheel/instance/model.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/instance/model.vert
rename to src/main/resources/assets/flywheel/flywheel/instance/model.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/instance/oriented.vert b/src/main/resources/assets/flywheel/flywheel/instance/oriented.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/instance/oriented.vert
rename to src/main/resources/assets/flywheel/flywheel/instance/oriented.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/layout/block.vert b/src/main/resources/assets/flywheel/flywheel/layout/block.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/layout/block.vert
rename to src/main/resources/assets/flywheel/flywheel/layout/block.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/layout/pos_tex_normal.vert b/src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/layout/pos_tex_normal.vert
rename to src/main/resources/assets/flywheel/flywheel/layout/pos_tex_normal.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/material/default.frag b/src/main/resources/assets/flywheel/flywheel/material/default.frag
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/material/default.frag
rename to src/main/resources/assets/flywheel/flywheel/material/default.frag
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/material/default.vert b/src/main/resources/assets/flywheel/flywheel/material/default.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/material/default.vert
rename to src/main/resources/assets/flywheel/flywheel/material/default.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/material/shaded.vert b/src/main/resources/assets/flywheel/flywheel/material/shaded.vert
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/material/shaded.vert
rename to src/main/resources/assets/flywheel/flywheel/material/shaded.vert
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/color.glsl b/src/main/resources/assets/flywheel/flywheel/util/color.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/color.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/color.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/diffuse.glsl b/src/main/resources/assets/flywheel/flywheel/util/diffuse.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/diffuse.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/diffuse.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/fog.glsl b/src/main/resources/assets/flywheel/flywheel/util/fog.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/fog.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/fog.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/light.glsl b/src/main/resources/assets/flywheel/flywheel/util/light.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/light.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/light.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/matrix.glsl b/src/main/resources/assets/flywheel/flywheel/util/matrix.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/matrix.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/matrix.glsl
diff --git a/src/main/resources/assets/flywheel/flywheel/shaders/util/quaternion.glsl b/src/main/resources/assets/flywheel/flywheel/util/quaternion.glsl
similarity index 100%
rename from src/main/resources/assets/flywheel/flywheel/shaders/util/quaternion.glsl
rename to src/main/resources/assets/flywheel/flywheel/util/quaternion.glsl