初次提交
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
## SpellDeck — 运行时执行游标
|
||||
## 权威来源:implementation_plan.md §2.2
|
||||
extends RefCounted
|
||||
class_name SpellDeck
|
||||
|
||||
var _nodes: Array = [] # Array[SpellNode]
|
||||
var _cursor: int = 0
|
||||
var _consumed: PackedByteArray = PackedByteArray() # 消费掩码(共鸣 consume_inputs,P6-N29);1=跳过
|
||||
|
||||
func setup(nodes: Array, consumed_indices: Array = []) -> void:
|
||||
_nodes = nodes
|
||||
_cursor = 0
|
||||
_consumed = PackedByteArray()
|
||||
_consumed.resize(_nodes.size()) # 全 0
|
||||
for idx in consumed_indices:
|
||||
if idx >= 0 and idx < _consumed.size():
|
||||
_consumed[idx] = int(1)
|
||||
|
||||
func has_next() -> bool:
|
||||
var c: int = _cursor
|
||||
while c < _nodes.size() and c < _consumed.size() and _consumed[c] != 0:
|
||||
c += 1
|
||||
return c < _nodes.size()
|
||||
|
||||
func pop() -> SpellNode:
|
||||
while _cursor < _nodes.size() and _cursor < _consumed.size() and _consumed[_cursor] != 0:
|
||||
_cursor += 1 # 跳过被共鸣消费的槽位
|
||||
if _cursor >= _nodes.size():
|
||||
return null
|
||||
var node: SpellNode = _nodes[_cursor]
|
||||
_cursor += 1
|
||||
return node
|
||||
|
||||
func peek() -> SpellNode:
|
||||
if _cursor >= _nodes.size():
|
||||
return null
|
||||
return _nodes[_cursor]
|
||||
|
||||
func reset_cursor() -> void:
|
||||
_cursor = 0
|
||||
|
||||
## 跳过直到遇到 SCOPE_CLOSE(深度计数器处理嵌套)
|
||||
func skip_until_scope_end() -> void:
|
||||
var depth := 1
|
||||
while _cursor < _nodes.size():
|
||||
var n: SpellNode = _nodes[_cursor]
|
||||
_cursor += 1
|
||||
if n.type == SpellNode.SpellType.SCOPE_CLOSE:
|
||||
depth -= 1
|
||||
if depth <= 0:
|
||||
return
|
||||
elif n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
|
||||
depth += 1
|
||||
|
||||
## 将游标到下一个 SCOPE_CLOSE 之间的节点列表取出(用于打包 SubPayload)
|
||||
func consume_until_scope_end() -> Array:
|
||||
var result: Array = []
|
||||
var depth := 1
|
||||
while _cursor < _nodes.size():
|
||||
var n: SpellNode = _nodes[_cursor]
|
||||
_cursor += 1
|
||||
if n.type == SpellNode.SpellType.SCOPE_CLOSE:
|
||||
depth -= 1
|
||||
if depth <= 0:
|
||||
break
|
||||
result.append(n)
|
||||
else:
|
||||
if n.type == SpellNode.SpellType.TRIGGER or n.type == SpellNode.SpellType.LOGIC:
|
||||
depth += 1
|
||||
result.append(n)
|
||||
return result
|
||||
|
||||
func get_remaining_count() -> int:
|
||||
return _nodes.size() - _cursor
|
||||
Reference in New Issue
Block a user