awtk-mvvm
awtk-mvvm copied to clipboard
实现MVVM框架的首选应该是支持反射(reflection)的语言,如rust、zig
用awtk-mvvm框架做了一个项目,用C语言做下来感觉很烦琐:头文件要加特定格式的注释、有时要手写view_mode更麻烦。 现在很多声明式UI框架都是用支持反射的语言来实现,这样model实现起来就很简洁,awtk-mvvm也应该如此。
最近研究了下zig的反射,发现很有意思。如下例子:
- 一个内置函数
@field(v, field.name)
就搞定了tkcobject
的get_prop
和set_prop
- 这个反射是在编译时进行的,如果
field.name
不存在会通不过编译 - 由于不需要在运行时进行字符串查找判断从而性能也很不错
const std = @import("std");
const Header = struct {
magic: u32,
title: []const u8,
};
const View = struct {
width: i32,
heigh: i32,
header: *Header,
};
pub fn main() void {
var header = Header{.magic=123, .title="abc"};
const view = View{.width=800, .heigh=480, .header=&header};
const aView = &view;
reflect(view);
reflect(aView);
}
fn reflect(v: anytype) void {
const typeName = @typeName(@TypeOf(v));
std.debug.print("type {s}:\n", .{typeName});
// 指针类型名以'*'字符开头
comptime var T = if(typeName[0] == '*') @TypeOf(v.*) else @TypeOf(v);
const info = @typeInfo(T);
inline for (info.Struct.fields) |field| {
std.debug.print(
" field {s} is type {s} with value: {any}\n",
.{
field.name,
@typeName(field.type),
@field(v, field.name),
}
);
}
}
输出为:
type reflection.View:
field width is type i32 with value: 800
field heigh is type i32 with value: 480
field header is type *reflection.Header with value: reflection.Header{ .magic = 123, .title = { 97, 98, 99 } }
type *const reflection.View:
field width is type i32 with value: 800
field heigh is type i32 with value: 480
field header is type *reflection.Header with value: reflection.Header{ .magic = 123, .title = { 97, 98, 99 } }
挺好。就是缺乏群众基础,嵌入式程序员只爱C语言。
挺好。就是缺乏群众基础,嵌入式程序员只爱C语言。
C语言是有群众基础,但痛点多。比如,构建系统麻烦,好多人可能看到AWTK要用scons、还要不少东西要配置、移植、剪裁就不愿意用了。 Zig无论是简易性、学习成本还是跟C的交互、解决C语言的痛点都很优秀,只可惜离1.0版本还很远,不然会是嵌入式声明式UI框架的绝佳选择。 所以我认为,Zig成熟稳定之后,肯定会有用它实现的嵌入式声明式UI框架。君不见rust这么难学slint都能搞得起来。
现阶段不将awtk-mvvm推倒重做,似乎可以类似jerryscript的支持那样,用函数view_model_factory_register_generic
注册一个创建zig实现的model的工厂函数就可以支持zig了?! 值得研究。