Writer 进阶

一个Writer只写一个属性。

属性数组型(PropertyArray)和属性字典型(PropertyDictionary)

绑定了这两种类型的写者, 如果元素是对象 ,则需要定义 子写者

写者与子写者构成了写者树,写者成员的增删会创建与释放子写者,同步元素对象的生灭。 所以需要回调函数定义如何构造子写者。

var _writer := WriterPropertyArray.new(
  target_obj,
  ^":test_array",
  source_data_node,
  WriterPropertyArray.ElementSubWriter.new(
    func(element_data_node: DataNodeInt):
      var result := TestObj.new()
      result.a = element_data_node.value()
      return result
      ,
    func(element_data_node: DataNodeInt, target_object: TestObj) -> Array:
      return [WriterProperty.new(target_object, ^":a", element_data_node)]
      )
)

这个构造函数接受四个参数:目标对象、目标属性、源数据节点、元素子写者。

子写者需要现场构造,接受三个回调:

  1. 目标元素对象申请回调:会传入新生成的源元素数据节点,需要创建目标元素对象并返回。

  2. 子写者构造回调:会传入源元素数据节点和目标元素对象,应返回创建的子写者列表。

  3. 目标元素对象释放回调(可选):如果需要手动释放目标元素对象,则需要定义它。

如果是字典,则对应数组元素的是字典的值。

注意:目标元素对象的申请和释放的过程完全由回调函数定义,回调函数外不会有任何额外的操作。

如果目标元素对象既不是 RefCounted 也不是 Node ,则必须实现释放回调。

申请回调和释放回调也可以实现为池的形式。

var _writer := WriterPropertyArray.new(
  target_obj,
  ^":test_array",
  source_data_node,
  WriterPropertyArray.ElementSubWriter.new(
    func(element_data_node: DataNodeInt):
      var result := get_from_pool()
      result.a = element_data_node.value()
      return result
      ,
    func(element_data_node: DataNodeInt, target_object: TestObj) -> Array:
      return [WriterProperty.new(target_object, ^":a", element_data_node)]
              ,
    func(target_object: TestObj) -> void:
      release_to_pool(target_object)
              )
)

节点型(Node)

节点型同上,只不过不需要指定绑定的属性,因为节点就是绑定节点本身,且自带改变信号。

var _writer := WriterNode.new(
  target_obj,
  source_data_node,
  WriterNode.ChildSubWriter.new(
    func(chlid_data_node: DataNodeInt) -> Node:
      var result := TestSubNode.new()
      result.a = chlid_data_node.value()
      return result
      ,
    func(chlid_data_node: DataNodeInt, target_node: Node) -> Array:
      return [WriterProperty.new(target_node, ^":a", chlid_data_node)]
      )
)

此外,释放回调函数应该有一个bool返回值,提示GDVM是否已经释放了这个子节点。