GDVM (Godot View Model)

by qt911025

0

Godot View Model by GDScript

这是啥

一个 Godot 的插件

一个单向数据绑定工具集,可实现MVVM/MVC

Gdvm不是围绕Godot的UI设计的,它与UI完全无关,所以Godot的任何节点都可以用

支持列表!

惰性求值!

可扩展!

Gdvm现在还处于测试版,API尚未稳定,在1.0发布前的更新都是颠覆性的,慎用!

1.0正式版将在Godot Asset Store正式版发布后发布在Godot Asset Store。届时旧的Godot Asset Library将不再更新。

上手

创建一个空的场景,根节点是Node,并绑定如下脚本。

extends Node

const Utils = Gdvm.Utils
const DataTree = Gdvm.DataTree
const ObserverPackTree = Gdvm.ObserverPackTree
const WriterPackTree = Gdvm.WriterPackTree

const DataNode = Gdvm.DataNode
const DataNodeInt = Gdvm.DataNodeInt

class ObjWithInt:
	signal changed
	var data: int:
		set(value):
			if value != data:
				# 防死循环设计
				data = value
				changed.emit()

func _ready() -> void:
	var obj := ObjWithInt.new()
	var data_tree := DataTree.new(0)
	var observer := ObserverPackTree.new({
		"base": obj,
		"options": ObserverPackTree.opts({
			"path": ":data",
			"changed": func(source: Object, _property_path: NodePath) -> Signal:
				return (source as ObjWithInt).changed
				})
	})
	data_tree.observe(observer)
	var root := data_tree.get_root() as DataNodeInt
	var _writer := WriterPackTree.new(root, {
		"base": obj,
		"options": WriterPackTree.opts({
			"path": ":data"
			})
	})
	prints("Initial data node value:", root.value()) # 0
	prints("Initial target value:", obj.data) # 0
	root.render(1)
	prints("Root rendered node value:", root.value()) # 1
	prints("Root rendered target value:", obj.data) # 1
	obj.data = 2
	prints("Target changed node value:", root.value()) # 2
	prints("Target changed target value:", obj.data) # 2

这个例子也在examples/_7_pure_script里可以看到

简单原理介绍

基础组成要素

Gdvm针对Godot的数据类型,定义了一套DataNode。

DataNode通过结构化组织成树,并添加观察者(Observer)与写者(Writer)绑定,将改动从来源同步到DataNode,并同步到目标数据。

观察者与写者是原子化的,实例化的关系,都是RefCounted,并且关系不拥有对目标对象与DataNode的强引用。绑定的数据一旦消失,关系也自动失效。

同样地,观察者与写者都是RefCounted,解除关系也只需要抛弃关系实例即可。

更复杂的组织

每个基本的DataNode、观察者与写者组织监听关系,规模扩大会让代码十分臃肿。

Gdvm提供了更简洁的配置方式——Binder,通过将三类基础部件构建成三大集合,建立集合与集合之间的监听关系。

Core Binder
DataNode DataTree
Observer ObserverPack
Writer WriterPack

可以建立多重监听关系,让多个不同的DataTree观察同一个数据来源,同一个DataTree可以建立多个不同的写者,同步到多个不同的目标。

Gdvm的适用场景

Gdvm将数据武装到牙齿,为每一个基础数据类型包装了一层复杂的结构,包括信号、缓存值等,会大大提高数据所占据的空间。

对数据量以及效率要求不大时,DataNode本身可以作为数据模型用。而数据量有一定规模后,应该自行定义数据结构与读写锁,只在表现层构建Gdvm来观察它。

Version

0.1.0

Engine

4.4

Category

Tools

Download

Version0.1.0
Download Now

Support

If you need help or have questions about this plugin, please contact the author.

Contact Author