如何在Java工具函数中用可变参数替代Consumer处理多Uniform着色器注册?
解决方案
你可以通过将Uniform的获取逻辑封装为独立的Consumer<ShaderInstance>,结合可变参数实现适配不同数量Uniform的注册工具函数,同时满足参数为有效final的要求。
1. 优化工具函数实现
修改工具类的registerShader方法,让它接收一个处理ShaderInstance赋值的主Consumer,再加上可变数量的处理Uniform赋值的Consumer:
// Utility class public static void registerShader(RegisterShadersEvent event, String path, Consumer<ShaderInstance> shaderHandler, Consumer<ShaderInstance>... uniformHandlers) { event.registerShader(ShaderInstance.create(path), shader -> { // 先完成ShaderInstance的赋值 shaderHandler.accept(shader); // 逐个处理所有Uniform的获取与赋值 for (Consumer<ShaderInstance> handler : uniformHandlers) { handler.accept(shader); } }); }
2. 调用示例
在主类中调用时,只需根据着色器的Uniform数量传入对应的lambda表达式即可,所有引用的变量只要是有效final(即不被重新赋值)就能满足要求:
3个Uniform的场景
public ShaderInstance shader; public ShaderUniform uniformOne, uniformTwo, uniformThree; @EventListener public void onRegister(RegisterShaderEvent event) { UtilityClass.registerShader(event, "path/to/my_shader.fsh", // 处理ShaderInstance的赋值 s -> shader = s, // 处理第一个Uniform s -> uniformOne = s.getUniform("One"), // 处理第二个Uniform s -> uniformTwo = s.getUniform("Two"), // 处理第三个Uniform s -> uniformThree = s.getUniform("Three") ); }
1个Uniform的场景
public ShaderInstance anotherShader; public ShaderUniform singleUniform; @EventListener public void onAnotherRegister(RegisterShaderEvent event) { UtilityClass.registerShader(event, "path/to/another_shader.fsh", s -> anotherShader = s, s -> singleUniform = s.getUniform("Single") ); }
3. 关键说明
- 有效final合规性:lambda表达式引用的类成员变量本身无需声明final;如果是局部变量,只要不重新赋值(即保持有效final状态),就完全符合你的要求。
- 扩展性:无论着色器有1个还是5个Uniform,只需在调用时增加对应的lambda表达式即可,无需修改工具函数本身。
- 简化代码:避免了重复编写
event.registerShader的模板代码,将核心逻辑(赋值)抽离出来,更易维护。
内容的提问来源于stack exchange,提问作者SnakerBone
相关产品推荐
相关产品推荐

