Class: Canopus::Minimap
- Inherits:
-
Object
- Object
- Canopus::Minimap
- Defined in:
- lib/canopus/minimap.rb,
sig/minimap.rbs
Overview
Bounded, edit-aware row textures shared by every pane showing a buffer.
Constant Summary collapse
- GENERATION_LIMIT =
24- ENTRY_LIMIT =
2_048- VARIANT_LIMIT =
4- LINE_BYTES =
4_096
Instance Attribute Summary collapse
-
#generated ⇒ Integer
readonly
Returns the value of attribute generated.
Instance Method Summary collapse
- #begin_frame(frame, text_system:, font_size:, font_family:, scale_factor:) ⇒ Object
- #cache_size ⇒ Integer
- #cached_rows(buffer) ⇒ Array[Integer]
- #close ⇒ nil
-
#initialize ⇒ Minimap
constructor
A new instance of Minimap.
- #pending? ⇒ Boolean
- #record_search(buffer, version, ranges) ⇒ Hash[Symbol, untyped]
- #release(buffer) ⇒ nil
- #search_rows(buffer, version) ⇒ Array[Integer]
- #texture(buffer, row, width:) ⇒ Zaniah::GPU::Texture?
Constructor Details
#initialize ⇒ Minimap
Returns a new instance of Minimap.
13 14 15 16 17 |
# File 'lib/canopus/minimap.rb', line 13 def initialize @variants, @subscriptions, @search = {}, {}, {} @next_key = @frame = 0 @generated, @pending = 0, false end |
Instance Attribute Details
#generated ⇒ Integer (readonly)
Returns the value of attribute generated.
11 12 13 |
# File 'lib/canopus/minimap.rb', line 11 def generated @generated end |
Instance Method Details
#begin_frame(frame, text_system:, font_size:, font_family:, scale_factor:) ⇒ Object
19 20 21 22 23 24 25 26 27 |
# File 'lib/canopus/minimap.rb', line 19 def begin_frame(frame, text_system:, font_size:, font_family:, scale_factor:) identity = [text_system&.object_id, text_system&.respond_to?(:font) ? text_system.font.object_id : nil, font_size, font_family, scale_factor] rebuild if @identity && @identity != identity @identity, @text_system, @font_size, @scale_factor = identity, text_system, font_size, scale_factor return if @frame == frame @frame, @generated, @pending = frame, 0, false end |
#cache_size ⇒ Integer
66 |
# File 'lib/canopus/minimap.rb', line 66 def cache_size = @variants.values.sum { |variant| variant[:entries].length } |
#cached_rows(buffer) ⇒ Array[Integer]
67 |
# File 'lib/canopus/minimap.rb', line 67 def cached_rows(buffer) = @variants.values.flat_map { |variant| variant[:entries].keys.filter_map { |source, row| row if source.equal?(buffer) } }.uniq.sort |
#close ⇒ nil
91 92 93 94 95 96 97 |
# File 'lib/canopus/minimap.rb', line 91 def close @subscriptions.each_value(&:detach) @subscriptions.clear rebuild @search.clear nil end |
#pending? ⇒ Boolean
65 |
# File 'lib/canopus/minimap.rb', line 65 def pending? = @pending |
#record_search(buffer, version, ranges) ⇒ Hash[Symbol, untyped]
69 70 71 72 73 74 75 76 77 |
# File 'lib/canopus/minimap.rb', line 69 def record_search(buffer, version, ranges) attach(buffer) rows = ranges.first(10_000).filter_map do |range| buffer.rope.point_at(range.begin).row if range.is_a?(Range) && range.begin.is_a?(Integer) rescue RangeError nil end @search[buffer] = {version: version, rows: rows.sort.uniq.freeze}.freeze end |
#release(buffer) ⇒ nil
84 85 86 87 88 89 |
# File 'lib/canopus/minimap.rb', line 84 def release(buffer) @variants.each_value { |variant| remove_buffer(variant, buffer) } @subscriptions.delete(buffer)&.detach @search.delete(buffer) nil end |
#search_rows(buffer, version) ⇒ Array[Integer]
79 80 81 82 |
# File 'lib/canopus/minimap.rb', line 79 def search_rows(buffer, version) entry = @search[buffer] entry && entry[:version] == version ? entry[:rows] : [] end |
#texture(buffer, row, width:) ⇒ Zaniah::GPU::Texture?
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
# File 'lib/canopus/minimap.rb', line 29 def texture(buffer, row, width:) return unless @text_system && row.is_a?(Integer) && row.between?(0, buffer.line_count - 1) variant = variant(width) pair = [buffer, row] if (entry = variant[:entries].delete(pair)) variant[:entries][pair] = entry return variant[:cache].texture(entry[:key], outlines: []) end unless @generated < GENERATION_LIMIT @pending = true return end attach(buffer) source = line_source(buffer.rope, row) layout = @text_system.layout_line(source, size: @font_size) outlines = [] layout.glyphs.each do |glyph| break if glyph.x * 0.1 >= width begin factor = @font_size.to_f / glyph.font.units_per_em outlines << glyph.font.outline(glyph.id).transform([factor, 0, 0, -factor, glyph.x, layout.ascent]) rescue StandardError nil end end key = @next_key += 1 texture = variant[:cache].texture(key, outlines: outlines) variant[:entries][pair] = {key: key, offset: buffer.rope.line_start(row)} trim(variant) @generated += 1 texture rescue StandardError nil end |