class_name NoteSpawner extends NoteView signal notes_spawned(beat: float) @export var lanes: Dictionary[int, Lane] @export var pool: NotePool ## Spawn all the notes that should exist on this beat. func update(beat: float) -> void: var old_begin: int = _begin var old_end: int = _end _update_view_relative_to_notes(notes, beat) # Updates _begin and _end. if _previous_beat <= beat: _set_note_visuals(old_end, _end) _remove_note_visuals(old_begin, _begin) else: _remove_note_visuals(_end, old_end) _set_note_visuals(_begin, old_begin) _previous_beat = beat notes_spawned.emit(beat) # ======== IMPLEMENTATION ======== # var _note_visuals: Dictionary[int, NoteVisual] # [Note ID, Note Visual] var _last_lane_holds: Dictionary[int, HoldNote] func _set_notes(p_notes: NoteArray) -> void: super._set_notes(p_notes) for note in _note_visuals.values(): if note == null: continue pool.return_note(note) # TODO Finish implementation. # Spawn or delete nodes in the range. func _set_note_visuals(index_begin: int, index_end: int) -> void: for note_id: int in range(index_begin, index_end): match notes.type_at(note_id): Note.TYPE.TAP: _set_visual_for_tap_at(note_id) Note.TYPE.HOLD_START: _set_visual_for_hold_start_at(note_id) Note.TYPE.HOLD_END: _set_visual_for_hold_end_at(note_id) func _remove_note_visuals(index_begin: int, index_end: int) -> void: for note_id: int in range(index_begin, index_end): match notes.type_at(note_id): Note.TYPE.TAP: _remove_visual_for_tap_at(note_id) Note.TYPE.HOLD_START: _remove_visual_for_hold_start_at(note_id) Note.TYPE.HOLD_END: _remove_visual_for_hold_end_at(note_id) func _set_visual_for_tap_at(note_id: int) -> void: var lane_id: int = notes.lane_at(note_id) var lane: Lane = lanes[lane_id] var note: TapNote = pool.get_tap() lane.add_child(note) _note_visuals[note_id] = note func _set_visual_for_hold_start_at(note_id: int) -> void: var lane_id: int = notes.lane_at(note_id) var lane: Lane = lanes[lane_id] var note: HoldNote = pool.get_hold() lane.add_child(note) _note_visuals[note_id] = note _last_lane_holds[lane_id] = note func _set_visual_for_hold_end_at(note_id: int) -> void: var lane_id: int = notes.lane_at(note_id) var lane: Lane = lanes[lane_id] var note: HoldNote = _last_lane_holds[lane_id] if note == null: note = pool.get_hold() lane.add_child(note) _note_visuals[note_id] = note _last_lane_holds[lane_id] = null func _remove_visual_for_tap_at(note_id: int) -> void: pass func _remove_visual_for_hold_start_at(note_id: int) -> void: pass func _remove_visual_for_hold_end_at(note_id: int) -> void: pass