feat(extlua): support external material#99
Conversation
c1e8362 to
8b91af8
Compare
8b91af8 to
bc154bd
Compare
ea71c4d to
502e0f0
Compare
502e0f0 to
5e550cf
Compare
|
我大致看了一下,有这样的改进意见: 目前 extlua 导出了三组 api ,分别是 lua sokol soluna ,这没有问题。其中 lua 和 sokol 是完全独立的,它们的 api 都是由第三方项目设计过的,所以我认为完全没有问题。 需要推敲的是 soluna api 。 它实际上和 sokol api 无关,但其依赖了 lua ,即参数里有 lua_State *L 。我认为可以把这层依赖去掉,让三者完全解耦。 从 sample https://github.com/yuchanns/soluna/blob/502e0f004d0069a5b9c6b6d7f219f182f509e783/extlua/extlua_sample.c 看,其实引入的 L 主要是为了调用 luaL_error 处理错误分支。我觉得可以把这些 api 改成错误值返回,在封装层把错误返回导向 luaL_error ,这样在写扩展材质的时候就不需要调用 lua 的错误处理了。 因为这里有一组回调函数风格的 api ,是由写 ext shader 者调用 soluna api 传入 callback ,而 callback 再调用 soluna api 。当 soluna api 用错误返回的形式,就需要 callback 中检查这些 api 可能的 error 返回值。这一点让此处设计变复杂。 我审查了一下现有代码。似乎大部分错误返回只是用来检查参数错误。似乎改成 C assert 也没什么问题。即使用者应该保证传入正确的参数。这一点还需要仔细审核一下,看有没有例外。 另外,现在的实现中使用了一个 struct stream_guard 用来自动在错误产生后释放内存。一旦上面的模式改成错误返回而不是 lua error ,似乎也不需要了。 |
|
以 sample 为例:
姑且认为 所以,我们应该看
1 也可以用 2 来实现。即检查出错误参数后,让后续 api 无效且无害。frame 执行完整个 callback 调用后,再用 luaL_error 抛出有意义的错误信息。 |
|
已经去掉对 lua_State 的依赖. |
a7606e0 to
6fa0613
Compare
这里说的是后面那个 context 吗?就是用于在 callback 间传递的,使用者的确不关心它是什么。 不过我觉得比起用 void * ,给个类型可能会更好一些,可以避免错误: struct material_stream_context {
void * ctx;
};然后使用 struct material_stream_context 而不是 void * 传递 context 。 |
|
已经把 material stream context, binding, sprite bank 都改成 typed handle 了 |
|
我的意思是这样: 把 void * 换成 soluna_render_bindings * 并不能阻止 C 编译器的隐式转换。C 的规则是可以将 void * 转换为其它指针类型。而 因为是 opaque 数据,只是确定是一个指针的话,最好用 struct material_stream_context {
void * ctx;
};而不是 struct material_stream_context * ,这样使用者写错类型就无法通过编译。 在 sokol 里也用的类似技巧,只不过它用的 int 而不是 void * typedef struct sg_buffer { uint32_t id; } sg_buffer;
typedef struct sg_image { uint32_t id; } sg_image;
typedef struct sg_sampler { uint32_t id; } sg_sampler;
typedef struct sg_shader { uint32_t id; } sg_shader;
typedef struct sg_pipeline { uint32_t id; } sg_pipeline;
typedef struct sg_view { uint32_t id; } sg_view;另外,我觉得这里 typedef 是多余的。其实要求使用者多注明 struct 更明确。(如果和 sokol 风格保持一致,多加一个 typedef 也行) 所以 sg_bindings soluna_material_bindings(soluna_render_bindings *bindings);应该是 sg_bindings soluna_material_bindings(struct soluna_render_bindings bindings);这样参数和返回值都是 opaque 类型,而不是指针。 |
9925320 to
376c4d0
Compare
|
已调整. 技巧知识+1. 之前用 Rust 写 C Bindings 时生成的好像就是这样的 opaque type. |
尝试为 extlua 实现 shader 外挂机制.
extlua_material的配置排序.通过 extlua 进行材质扩展时, 编译需要包含
extlua/{extlua,sokolapi,solunaapi}.c以及extlua/solunaapi.h, 然后使用 sokol api 和 soluna api 进行材质编写:并在 lua 侧进行注册几个指定的方法:
submit,draw和reset然后在
*.game文件里指定加载路径和材质: