Zongzi.Anchor.Strategy behaviour (zongzi v0.3.0)

Copy Markdown

结构锚策略 behaviour。与 Intervention.Declaration(语义 snapshot/resolve)正交。

与 Declaration 的分界

  • Strategy.rebase — 锚还指得准吗?(结构存活,编辑时)
  • Declaration.resolve — base 还对得上 snapshot 吗?(语义有效,渲染/check 时)

自定义结构策略禁止在 rebase 里做:比 pitch 曲线 snapshot、调引擎、应用 delta。 最多读 Context 里的 Note 静态字段(key/lyric/tick)来选宿主。

anchor 形状

Intervention.anchorterm()——形状由本策略负责解释。 默认 NoteTriplet{prev_seq | nil, current_seq, next_seq | nil}。 其他策略可定义自己的形状,必须实现 referenced_seqs/1 以告知 gc 该 intervention 依赖哪些 SeqID。

Summary

Callbacks

可选:从「已死/丢失」的 focus 选出新宿主。

判定 intervention 的结构锚是否存活,必要时改写或重定位。

返回 intervention 锚所引用的全部 SeqID 集合。 供 Timeline.gc/2 判定哪些墓碑仍被引用、不可回收。

Types

decision()

@type decision() ::
  {:ok, :preserve}
  | {:ok, {:rebase, Zongzi.Intervention.t()}}
  | {:ok, {:relocate, Zongzi.Intervention.t(), meta :: map()}}
  | {:conflict, reason()}

reason()

@type reason() ::
  :adjacency_lost
  | :merged_away
  | :no_host
  | :ambiguous_host
  | {:custom, term()}

Callbacks

choose_host(focus, t, t, keyword)

(optional)
@callback choose_host(
  focus :: Zongzi.Timeline.SeqID.t() | nil,
  Zongzi.Timeline.t(),
  Zongzi.Anchor.Context.t(),
  keyword()
) :: {:ok, Zongzi.Timeline.SeqID.t(), map()} | {:conflict, reason()}

可选:从「已死/丢失」的 focus 选出新宿主。

rebase(t, t, t, opts)

@callback rebase(
  Zongzi.Intervention.t(),
  Zongzi.Timeline.t(),
  Zongzi.Anchor.Context.t(),
  opts :: term()
) ::
  decision()

判定 intervention 的结构锚是否存活,必要时改写或重定位。

第四参数 opts 为本策略专属配置(struct 或 map), 由 Intervention.strategy{module(), opts} 元组传入。 不得做语义 snapshot 比对(那是 Declaration.resolve)。

referenced_seqs(t)

@callback referenced_seqs(Zongzi.Intervention.t()) :: [Zongzi.Timeline.SeqID.t()]

返回 intervention 锚所引用的全部 SeqID 集合。 供 Timeline.gc/2 判定哪些墓碑仍被引用、不可回收。

NoteTriplet 返回三元组的三个元素。