Class: Canopus::Decoration::Registry
- Inherits:
-
Object
- Object
- Canopus::Decoration::Registry
- Defined in:
- lib/canopus/decoration.rb,
sig/decoration.rbs
Constant Summary collapse
- CACHE_LIMIT =
256
Instance Attribute Summary collapse
-
#version ⇒ Integer
readonly
Returns the value of attribute version.
Instance Method Summary collapse
-
#initialize ⇒ Registry
constructor
A new instance of Registry.
- #invalidate(source, buffer: nil, rows: nil) ⇒ nil
- #items_for(buffer, row_range, context: nil) ⇒ Array[Item]
- #register(source) {|arg0, arg1, arg2| ... } ⇒ Symbol
- #unregister(source) ⇒ Proc?
Constructor Details
#initialize ⇒ Registry
Returns a new instance of Registry.
13 14 15 16 |
# File 'lib/canopus/decoration.rb', line 13 def initialize @suppliers, @generations, @cache = {}, Hash.new(0), {} @lock, @version = Mutex.new, 0 end |
Instance Attribute Details
#version ⇒ Integer (readonly)
Returns the value of attribute version.
11 12 13 |
# File 'lib/canopus/decoration.rb', line 11 def version @version end |
Instance Method Details
#invalidate(source, buffer: nil, rows: nil) ⇒ nil
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'lib/canopus/decoration.rb', line 71 def invalidate(source, buffer: nil, rows: nil) source = normalize_source(source) row_bounds = normalize_rows(rows) if rows @lock.synchronize do @version += 1 @generations[source] += 1 if buffer || row_bounds @cache.delete_if do |key, _| same_source = key[0] == source same_buffer = !buffer || key[1] == buffer.object_id overlaps = !row_bounds || (key[3] < row_bounds[1] && row_bounds[0] < key[4]) same_source && same_buffer && overlaps end else @cache.delete_if { |key, _| key[0] == source } end end nil end |
#items_for(buffer, row_range, context: nil) ⇒ Array[Item]
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 64 65 66 67 68 69 |
# File 'lib/canopus/decoration.rb', line 38 def items_for(buffer, row_range, context: nil) first, last = normalize_rows(row_range) state = [buffer.respond_to?(:version) ? buffer.version : nil, context&.object_id, context&.respond_to?(:selections) ? context.selections : buffer.respond_to?(:selections) ? buffer.selections : nil, context&.respond_to?(:tab_size) ? context.tab_size : nil, context&.respond_to?(:language_document) ? context.language_document.object_id : nil] suppliers = @lock.synchronize do @suppliers.map { |source, supplier| [source, supplier, @generations[source]] } end items = suppliers.flat_map do |source, supplier, generation| key = [source, buffer.object_id, state, first, last] cached = @lock.synchronize { @cache[key] } next cached if cached supplied = if supplier.arity == 2 supplier.call(buffer, first...last) else supplier.call(buffer, first...last, context) end raise TypeError, "decoration supplier must return an array" unless supplied.is_a?(Array) supplied = supplied.map { |item| normalize_item(item, source) }.freeze @lock.synchronize do if @suppliers[source].equal?(supplier) && @generations[source] == generation @cache.shift while @cache.length >= CACHE_LIMIT @cache[key] = supplied end end supplied end items.each_with_index.sort_by { |item, index| [item.priority, index] }.map!(&:first).freeze end |
#register(source) {|arg0, arg1, arg2| ... } ⇒ Symbol
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/canopus/decoration.rb', line 18 def register(source, &supplier) raise ArgumentError, "decoration supplier required" unless supplier source = normalize_source(source) @lock.synchronize do @suppliers[source] = supplier invalidate_locked(source) end source end |
#unregister(source) ⇒ Proc?
29 30 31 32 33 34 35 36 |
# File 'lib/canopus/decoration.rb', line 29 def unregister(source) source = normalize_source(source) @lock.synchronize do supplier = @suppliers.delete(source) invalidate_locked(source) if supplier supplier end end |