Skip to content

Commit

Permalink
add mark and at
Browse files Browse the repository at this point in the history
  • Loading branch information
UlyssesZh committed Sep 5, 2024
1 parent fae4763 commit fc3c98b
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 18 deletions.
6 changes: 3 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
sscharter (0.6.2)
sscharter (0.7.0)
concurrent-ruby (~> 1.3)
em-websocket (~> 0.5)
filewatcher (~> 2.0)
Expand All @@ -14,7 +14,7 @@ GEM
specs:
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
concurrent-ruby (1.3.3)
concurrent-ruby (1.3.4)
em-websocket (0.5.3)
eventmachine (>= 0.12.9)
http_parser.rb (~> 0)
Expand All @@ -24,7 +24,7 @@ GEM
http_parser.rb (0.8.0)
launchy (2.5.2)
addressable (~> 2.8)
minitest (5.24.1)
minitest (5.25.1)
module_methods (0.1.0)
public_suffix (6.0.1)
rake (13.2.1)
Expand Down
73 changes: 60 additions & 13 deletions lib/sscharter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ def initialize name
@name = name
init_chart_info
init_state
init_bookmarks
end

def init_chart_info
Expand All @@ -337,8 +338,11 @@ def init_chart_info
@events = []
end

def init_bookmarks
@bookmarks = {}
end

def init_state
@current_offset = nil
@current_beat = nil
@bpm_changes = nil
@tip_point_mode_stack = [:none]
Expand Down Expand Up @@ -399,9 +403,8 @@ def difficulty_sup difficulty_sup

def offset offset
raise ArgumentError, 'offset must be a number' unless offset.is_a? Numeric
@current_offset = offset.to_f
@current_beat = 0r
@bpm_changes = BpmChangeList.new @current_offset
@bpm_changes = BpmChangeList.new offset.to_f
end

def bpm bpm
Expand Down Expand Up @@ -449,24 +452,68 @@ def time_at beat = @current_beat
alias_method "tp_#{mode}", "tip_point_#{mode}"
end

def backup_beat
{current_beat: @current_beat, bpm_changes: @bpm_changes}
end

def restore_beat backup
@current_beat = backup[:current_beat]
@bpm_changes = backup[:bpm_changes]
end

def group preserve_beat: true, &block
raise ArgumentError, 'no block given' unless block
@groups.push result = []
unless preserve_beat
last_beat = @current_beat
last_offset = @current_offset
last_bpm_changes = @bpm_changes
end
beat_backup = backup_beat unless preserve_beat
instance_eval &block
unless preserve_beat
@current_beat = last_beat
@current_offset = last_offset
@bpm_changes = last_bpm_changes
end
restore_beat beat_backup unless preserve_beat
@groups.delete_if { result.equal? _1 }
result
end

def backup_state
{
current_beat: @current_beat,
bpm_changes: @bpm_changes,
tip_point_mode_stack: @tip_point_mode_stack.dup,
current_tip_point_stack: @current_tip_point_stack.dup,
current_tip_point_group_stack: @current_tip_point_group_stack.dup,
current_duplicate: @current_duplicate,
tip_point_start_to_add_stack: @tip_point_start_to_add_stack.dup,
groups: @groups.dup
}
end

def restore_state backup
@current_beat = backup[:current_beat]
@bpm_changes = backup[:bpm_changes]
@tip_point_mode_stack = backup[:tip_point_mode_stack]
@current_tip_point_stack = backup[:current_tip_point_stack]
@current_tip_point_group_stack = backup[:current_tip_point_group_stack]
@current_duplicate = backup[:current_duplicate]
@tip_point_start_to_add_stack = backup[:tip_point_start_to_add_stack]
@groups = backup[:groups]
nil
end

def mark name
@bookmarks[name] = backup_state
name
end

def at name, preserve_beat: false, update_mark: false, &block
raise ArgumentError, 'no block given' unless block
raise ArgumentError, "unknown bookmark #{name}" unless bookmark = @bookmarks[name]
backup = backup_state
restore_state bookmark
result = group &block
mark name if update_mark
beat_backup = backup_beat if preserve_beat
restore_state backup
restore_beat beat_backup if preserve_beat
result
end

def tip_point mode, *args, preserve_beat: true, **opts, &block
@tip_point_mode_stack.push mode
if mode == :none
Expand Down
2 changes: 1 addition & 1 deletion lib/sscharter/version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@

module Sunniesnow
class Charter
VERSION = "0.6.2"
VERSION = "0.7.0"
end
end
58 changes: 57 additions & 1 deletion test/test_sscharter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,6 @@ def test_offset_and_beat
assert_raises(Charter::OffsetError) { chart.event :placeholder }

chart.offset offset = rand
assert_equal offset, chart.instance_variable_get(:@current_offset)
assert_equal 0r, chart.instance_variable_get(:@current_beat)
chart.beat 10
assert_equal 10r, chart.instance_variable_get(:@current_beat)
Expand Down Expand Up @@ -595,4 +594,61 @@ def test_remove_and_duplicate
assert_equal chart.events, [*group1, *group2]
end

def test_mark
chart = Charter.open __method__
chart.offset offset = rand
chart.bpm bpm = rand * 300

note1 = note2 = current_beat = last_beat = nil
group1 = chart.tp_chain rand, rand, rand do
note1 = t rand(100), rand(100)
last_beat = b 1
mark :test1
end
group2 = chart.at :test1, preserve_beat: true do
note2 = t rand(100), rand(100)
current_beat = b 1
end
note3 = chart.t rand(100), rand(100)
assert_equal group1.length, 3
assert_equal group2, [note2]
assert_equal note1[:tip_point], note2[:tip_point]
assert_equal note2.beat, last_beat
assert_equal note3.beat, current_beat

note4 = nil
chart.mark :test2
group4 = chart.at :test2 do
note4 = t rand(100), rand(100)
b 1
end
note5 = chart.t rand(100), rand(100)
assert_equal group4, [note4]
assert_equal note4.beat, current_beat
assert_equal note5.beat, current_beat
end

def test_mark_and_tp_drop
chart = Charter.open __method__
chart.offset offset = rand
chart.bpm bpm = rand * 300

note1 = note2 = note3 = nil
group1 = chart.tp_drop rand, rand, rand do
note1 = t rand(100), rand(100)
b 1
mark :test1
end
group2 = chart.at :test1 do
note2 = t rand(100), rand(100)
b 1
end
group3 = chart.tp_chain rand, rand, rand do
note3 = t rand(100), rand(100)
b 1
end
assert_equal group1.length, 4
assert_equal [note1, note2, note3].map { _1[:tip_point] }.uniq.length, 3
end

end

0 comments on commit fc3c98b

Please sign in to comment.