Module: Contrek::Concurrent::Partitionable

Included in:
Polyline
Defined in:
lib/contrek/finder/concurrent/partitionable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#partsObject (readonly)

Returns the value of attribute parts.



4
5
6
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 4

def parts
  @parts
end

Instance Method Details

#add_part(new_part) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 11

def add_part(new_part)
  last = @parts.last
  @parts << new_part
  last.next = last.circular_next = new_part if last
  new_part.circular_next = @parts.first
  new_part.prev = last
end

#find_first_part_by_position(position) ⇒ Object



19
20
21
22
23
24
25
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 19

def find_first_part_by_position(position)
  @parts.find do |part|
    part.is?(Part::SEAM) &&
      part.passes == 0 &&
      position.end_point.queues.include?(part)
  end
end

#initialize(*args, **kwargs, &block) ⇒ Object



6
7
8
9
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 6

def initialize(*args, **kwargs, &block)
  super
  @parts = []
end

#inspect_partsObject



27
28
29
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 27

def inspect_parts
  [" "] + ["#{self.class} parts=#{@parts.size}"] + @parts.map { |p| p.inspect } + [" "]
end

#partition!Object



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
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 31

def partition!
  current_part = nil
  @parts = []

  @raw.each_with_index do |position, n|
    if @tile.tg_border?(position)
      if current_part.nil?
        current_part = Part.new(Part::SEAM, self)
      elsif !current_part.is?(Part::SEAM)
        add_part(current_part)
        current_part = Part.new(Part::SEAM, self)
      end
    elsif current_part.nil?
      current_part = Part.new(Part::EXCLUSIVE, self)
    elsif !current_part.is?(Part::EXCLUSIVE)
      add_part(current_part)
      current_part = Part.new(Part::EXCLUSIVE, self)
    end
    if n > 0 && @raw[n - 1] == position
      current_part.inverts = true
    end
    current_part.add_position(position, n)
  end
  add_part(current_part)

  trasmute_parts!
end

#sew!(intersection, other) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/contrek/finder/concurrent/partitionable.rb', line 59

def sew!(intersection, other)
  matching_part_indexes = []
  parts.each_with_index do |part, index|
    next if part.trasmuted
    matching_part_indexes << index if part.intersection_with_array?(intersection)
  end
  other_matching_part_indexes = []
  other.parts.each_with_index do |part, index|
    next if part.trasmuted
    other_matching_part_indexes << index if part.intersection_with_array?(intersection)
  end
  # other_matching_part_indexes and matching_part_indexes always contain at least one element
  before_parts = other.parts[other_matching_part_indexes.last + 1..]
  after_parts = other_matching_part_indexes.first.zero? ? [] : other.parts[0..other_matching_part_indexes.first - 1]
  part_start = parts[matching_part_indexes.first]
  part_end = parts[matching_part_indexes.last]

  # They are inverted since they traverse in opposite directions
  sequence = Sequence.new
  sequence.add part_start.head
  before_parts.each { |part| sequence.append(part) }
  after_parts.each { |part| sequence.append(part) }
  sequence.add part_end.tail if part_end.tail # nil when part_start == part_end

  part_start.replace!(sequence)
  part_start.type = Part::EXCLUSIVE
  part_end.reset! if part_start != part_end

  left = []
  (matching_part_indexes.first + 1).upto(matching_part_indexes.last - 1) do |n|
    left << parts[n].to_a if matching_part_indexes.index(n).nil?
  end
  (matching_part_indexes.last - 1).downto(matching_part_indexes.first + 1) do |n|
    delete_part = parts[n]
    delete_part.prev.next = delete_part.next if delete_part.prev
    delete_part.next.prev = delete_part.prev if delete_part.next
    parts.delete_at(n)
  end
  right = []
  (other_matching_part_indexes.first + 1).upto(other_matching_part_indexes.last - 1) do |n|
    right << other.parts[n].to_a if other_matching_part_indexes.index(n).nil?
  end
  [left, right]
end