@@ -660,42 +660,9 @@ def add_dialog_proc(name, p, context = nil)
660660 end
661661
662662 private def range_subtract ( base_ranges , subtract_ranges )
663- points = [ ]
664- base_ranges . each do |range |
665- points << [ range . begin , 1 , 1 ]
666- points << [ range . end , -1 , 1 ]
667- end
668- subtract_ranges . each do |range |
669- points << [ range . begin , 1 , -1 ]
670- points << [ range . end , -1 , -1 ]
671- end
672- ranges = [ ]
673- base_count = 0
674- subtract_count = 0
675- open = false
676- points . sort . each do |point , diff , mode |
677- if mode == 1
678- base_count += diff
679- else
680- subtract_count += diff
681- end
682- next if open == ( base_count > 0 && subtract_count == 0 )
683- open = !open
684- if open
685- if ranges . last &.end === point
686- ranges [ -1 ] = ( ranges . last . begin ...)
687- else
688- ranges << ( point ...)
689- end
690- else
691- if ranges . last . begin === point
692- ranges . pop
693- else
694- ranges [ -1 ] = ranges . last . begin ...point
695- end
696- end
697- end
698- ranges
663+ indices = base_ranges . flat_map ( &:to_a ) . uniq . sort - subtract_ranges . flat_map ( &:to_a )
664+ chunks = indices . chunk_while { |a , b | a + 1 == b }
665+ chunks . map { |a | a . first ...a . last + 1 }
699666 end
700667
701668 private def dialog_range ( dialog , dialog_y )
@@ -725,8 +692,10 @@ def add_dialog_proc(name, p, context = nil)
725692 end
726693 return if old_dialog_ranges . empty? && new_dialog_ranges . empty?
727694 ranges_to_restore = { }
695+ subtract_cache = { }
728696 old_dialog_ranges . each do |y , old_x_ranges |
729- ranges = range_subtract ( old_x_ranges , new_dialog_ranges [ y ] || [ ] )
697+ new_x_ranges = new_dialog_ranges [ y ] || [ ]
698+ ranges = subtract_cache [ [ old_x_ranges , new_x_ranges ] ] ||= range_subtract ( old_x_ranges , new_x_ranges )
730699 ranges_to_restore [ y ] = ranges if ranges . any?
731700 end
732701
0 commit comments