基于Zig语言对AWTK的MVVM框架在泛型/反射特性之上进行了封装,实现了类似WPF那样方便使用的MVVM框架。因为由Zig编写,故支持64MB内存级别的嵌入式Linux UI开发。AWTK的MVVM框架使用C语言编写,但因为C语言的特性太少,直接使用这个框架的话会非常不方便,比如:要在头文件添加特定格式的注释、属性不支持多层等。使用Zig封装之后,使用的便利性基本就跟WPF的MVVM差不多了。
比如,UI声明大致如下:
<window v-model="UsersVM" >
<label v-data:text="{name}" />
<label v-data:text="{cfg.age}" />
<label v-data:text="{tr(cfg.gender.str)}" />
<button tr_text="大一岁" v-on:click="{addAge}" />
<button tr_text="小一岁" v-on:click="{subAge}" />
<button tr_text="添加" v-on:click="{append}" />
</window>
对应的模型代码大致如下:实现起来是比较直观而且容易的
pub const UsersVM = struct {
name: awtk.String = undefined,
cfg: struct {
age: u8,
gender: user_model.Gender,
} = .{
.age = 0,
.gender = .Male,
},
const Self = @This();
pub fn addAge(self: *Self) !awtk.Notify {
self.cfg.age += 1;
return .PropertyChanged;
}
pub fn canAddAge(self: Self) bool {
return self.cfg.age < 5;
}
pub fn subAge(self: *Self) !awtk.Notify {
self.cfg.age -= 1;
return .PropertyChanged;
}
pub fn canSubAge(self: Self) bool {
return self.cfg.age > 0;
}
pub fn append(self: *Self) !awtk.Notify {
// 逻辑代码实现
return .ItemsChanged;
}
pub fn canAppend(self: Self) bool {
return self.name.len() > 0;
}
};
项目地址在这里:https://gitee.com/ufbycd/awtk-mvvm-zig-example
目前嵌入式Linux已经在D21x平台的D213ECV-DEMO-V4开发板上验证。 另外,Zig的交叉编译也非常方便,上述项目已经内置D21x平台编译支持,编译命令为:
zig build -Dd21x
该命令等效于:
zig build -Dtarget=riscv64-linux-gnu -Dcpu=generic_rv64+i+m+a+f+d+c
可前往项目地址了解更多详情。
离线
上述示例工程的界面效果如下:
其中“性别平衡”的显示比较体现MVVM作为声明式框架的优势,其控件的UI描述是这样的:
<label w="30%" v-data:text="{isGenderBalance ? tr('是') : tr('否')}" />
其模型代码是这样的:
// 虚拟property: isGenderBalance
pub fn getIsGenderBalance(self: Self, _: []const u8, v: *awtk.Value) c.ret_t {
var male_count: u32 = 0;
var female_count: u32 = 0;
for (self.users.models.items) |item| {
if (item.gender == .Male) {
male_count += 1;
} else {
female_count += 1;
}
}
_ = c.value_set_bool(v, male_count == female_count);
return c.RET_OK;
}
代码就这么多,再没其它的了。这是个虚拟属性,当列表内容增加、减少或列表元素的性别发生变化,其值都会更新。
如果在命令式UI上实现此功能,想必需要添加比较多的事件响应函数,而且整个逻辑代码分散在多个地方,繁琐且容易出BUG.
离线
这个有意思。我在用WPF的MVVM 用起来很方便。
不过这个zig语言 头一次听说,不了解
离线
Is this complete?
离线