dogviz 0.0.17 → 0.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/lib/dogviz/colorizer.rb +25 -0
 - data/lib/dogviz/common.rb +89 -0
 - data/lib/dogviz/container.rb +88 -0
 - data/lib/dogviz/duplicate_lookup_error.rb +7 -0
 - data/lib/dogviz/flow.rb +67 -0
 - data/lib/dogviz/flowable.rb +9 -0
 - data/lib/dogviz/graphviz_renderer.rb +60 -0
 - data/lib/dogviz/logical_container.rb +8 -0
 - data/lib/dogviz/lookup_error.rb +7 -0
 - data/lib/dogviz/missing_match_block_error.rb +7 -0
 - data/lib/dogviz/nominator.rb +18 -0
 - data/lib/dogviz/parent.rb +38 -0
 - data/lib/dogviz/process.rb +18 -0
 - data/lib/dogviz/registry.rb +39 -0
 - data/lib/dogviz/rendered_sequence.rb +13 -0
 - data/lib/dogviz/sequence_renderer.rb +47 -0
 - data/lib/dogviz/sigma_graph_hash.rb +25 -0
 - data/lib/dogviz/sigma_renderer.rb +32 -0
 - data/lib/dogviz/system.rb +95 -0
 - data/lib/dogviz/thing.rb +135 -0
 - data/lib/dogviz/version.rb +1 -1
 - data/lib/dogviz.rb +7 -687
 - data/tests/test_dogviz_sigma_rendering.rb +68 -0
 - data/todo.txt +7 -0
 - metadata +24 -2
 
    
        data/lib/dogviz.rb
    CHANGED
    
    | 
         @@ -1,689 +1,9 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
             
     | 
| 
      
 1 
     | 
    
         
            +
            require_relative 'dogviz/thing.rb'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require_relative 'dogviz/container.rb'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require_relative 'dogviz/logical_container.rb'
         
     | 
| 
       2 
4 
     | 
    
         | 
| 
       3 
     | 
    
         
            -
             
     | 
| 
       4 
     | 
    
         
            -
             
     | 
| 
       5 
     | 
    
         
            -
                def initialize(processor, description)
         
     | 
| 
       6 
     | 
    
         
            -
                  @processor = processor
         
     | 
| 
       7 
     | 
    
         
            -
                  @description = description
         
     | 
| 
       8 
     | 
    
         
            -
                end
         
     | 
| 
       9 
     | 
    
         
            -
                def name
         
     | 
| 
       10 
     | 
    
         
            -
                  @processor.name
         
     | 
| 
       11 
     | 
    
         
            -
                end
         
     | 
| 
       12 
     | 
    
         
            -
                def description
         
     | 
| 
       13 
     | 
    
         
            -
                  @description
         
     | 
| 
       14 
     | 
    
         
            -
                end
         
     | 
| 
       15 
     | 
    
         
            -
                attr_reader :processor
         
     | 
| 
       16 
     | 
    
         
            -
              end
         
     | 
| 
       17 
     | 
    
         
            -
              module Flowable
         
     | 
| 
       18 
     | 
    
         
            -
                def does(action)
         
     | 
| 
       19 
     | 
    
         
            -
                  Process.new(self, action)
         
     | 
| 
       20 
     | 
    
         
            -
                end
         
     | 
| 
       21 
     | 
    
         
            -
              end
         
     | 
| 
       22 
     | 
    
         
            -
              module Nominator
         
     | 
| 
       23 
     | 
    
         
            -
                def nominate(names_to_nominees)
         
     | 
| 
       24 
     | 
    
         
            -
                  names_to_nominees.each {|name, nominee|
         
     | 
| 
       25 
     | 
    
         
            -
                    self.class.send(:define_method, name) do
         
     | 
| 
       26 
     | 
    
         
            -
                      nominee
         
     | 
| 
       27 
     | 
    
         
            -
                    end
         
     | 
| 
       28 
     | 
    
         
            -
                  }
         
     | 
| 
       29 
     | 
    
         
            -
                end
         
     | 
| 
       30 
     | 
    
         
            -
                def nominate_from(nominee_nominator, *nominee_names)
         
     | 
| 
       31 
     | 
    
         
            -
                  nominee_names.each {|name|
         
     | 
| 
       32 
     | 
    
         
            -
                    accessor_sym = name.to_s.to_sym
         
     | 
| 
       33 
     | 
    
         
            -
                    nominate accessor_sym => nominee_nominator.send(accessor_sym)
         
     | 
| 
       34 
     | 
    
         
            -
                  }
         
     | 
| 
       35 
     | 
    
         
            -
                end
         
     | 
| 
       36 
     | 
    
         
            -
              end
         
     | 
| 
       37 
     | 
    
         
            -
              module Common
         
     | 
| 
       38 
     | 
    
         
            -
                def create_id(name, parent)
         
     | 
| 
       39 
     | 
    
         
            -
                  parts = []
         
     | 
| 
       40 
     | 
    
         
            -
                  parts << parent.id if parent.respond_to? :id
         
     | 
| 
       41 
     | 
    
         
            -
                  parts += name.split /\s/
         
     | 
| 
       42 
     | 
    
         
            -
                  parts.join '_'
         
     | 
| 
       43 
     | 
    
         
            -
                end
         
     | 
| 
       44 
     | 
    
         
            -
                def root
         
     | 
| 
       45 
     | 
    
         
            -
                  ancestors.last
         
     | 
| 
       46 
     | 
    
         
            -
                end
         
     | 
| 
       47 
     | 
    
         
            -
                def ancestors
         
     | 
| 
       48 
     | 
    
         
            -
                  ancestors = [parent]
         
     | 
| 
       49 
     | 
    
         
            -
                  loop do
         
     | 
| 
       50 
     | 
    
         
            -
                    break unless ancestors.last.respond_to?(:parent)
         
     | 
| 
       51 
     | 
    
         
            -
                    ancestors << ancestors.last.parent
         
     | 
| 
       52 
     | 
    
         
            -
                  end
         
     | 
| 
       53 
     | 
    
         
            -
                  ancestors
         
     | 
| 
       54 
     | 
    
         
            -
                end
         
     | 
| 
       55 
     | 
    
         
            -
                def info(fields)
         
     | 
| 
       56 
     | 
    
         
            -
                  @info.merge! fields
         
     | 
| 
       57 
     | 
    
         
            -
                  setup_render_attributes(label: label_with_info)
         
     | 
| 
       58 
     | 
    
         
            -
                end
         
     | 
| 
       59 
     | 
    
         
            -
                def doclink(url)
         
     | 
| 
       60 
     | 
    
         
            -
                  setup_render_attributes(URL: url)
         
     | 
| 
       61 
     | 
    
         
            -
                end
         
     | 
| 
       62 
     | 
    
         
            -
                def label_with_info
         
     | 
| 
       63 
     | 
    
         
            -
                  lines = [ name ]
         
     | 
| 
       64 
     | 
    
         
            -
                  @info.each {|k, v|
         
     | 
| 
       65 
     | 
    
         
            -
                    lines << "#{k}: #{v}"
         
     | 
| 
       66 
     | 
    
         
            -
                  }
         
     | 
| 
       67 
     | 
    
         
            -
                  lines.join "\n"
         
     | 
| 
       68 
     | 
    
         
            -
                end
         
     | 
| 
       69 
     | 
    
         
            -
                def setup_render_attributes(attributes)
         
     | 
| 
       70 
     | 
    
         
            -
                  @attributes = {} if @attributes.nil?
         
     | 
| 
       71 
     | 
    
         
            -
                  @attributes.merge!(attributes)
         
     | 
| 
       72 
     | 
    
         
            -
                end
         
     | 
| 
       73 
     | 
    
         
            -
                def rollup?
         
     | 
| 
       74 
     | 
    
         
            -
                  @rollup
         
     | 
| 
       75 
     | 
    
         
            -
                end
         
     | 
| 
       76 
     | 
    
         
            -
                def rollup!
         
     | 
| 
       77 
     | 
    
         
            -
                  @rollup = true
         
     | 
| 
       78 
     | 
    
         
            -
                  self
         
     | 
| 
       79 
     | 
    
         
            -
                end
         
     | 
| 
       80 
     | 
    
         
            -
                def skip!
         
     | 
| 
       81 
     | 
    
         
            -
                  @skip = true
         
     | 
| 
       82 
     | 
    
         
            -
                  self
         
     | 
| 
       83 
     | 
    
         
            -
                end
         
     | 
| 
      
 5 
     | 
    
         
            +
            require_relative 'dogviz/graphviz_renderer.rb'
         
     | 
| 
      
 6 
     | 
    
         
            +
            require_relative 'dogviz/sigma_renderer.rb'
         
     | 
| 
       84 
7 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
       86 
     | 
    
         
            -
             
     | 
| 
       87 
     | 
    
         
            -
                end
         
     | 
| 
       88 
     | 
    
         
            -
             
     | 
| 
       89 
     | 
    
         
            -
                def in_skip?
         
     | 
| 
       90 
     | 
    
         
            -
                  skip? || under_skip?
         
     | 
| 
       91 
     | 
    
         
            -
                end
         
     | 
| 
       92 
     | 
    
         
            -
             
     | 
| 
       93 
     | 
    
         
            -
                def under_skip?
         
     | 
| 
       94 
     | 
    
         
            -
                  ancestors.any? &:skip?
         
     | 
| 
       95 
     | 
    
         
            -
                end
         
     | 
| 
       96 
     | 
    
         
            -
             
     | 
| 
       97 
     | 
    
         
            -
                def under_rollup?
         
     | 
| 
       98 
     | 
    
         
            -
                  ancestors.any? &:rollup?
         
     | 
| 
       99 
     | 
    
         
            -
                end
         
     | 
| 
       100 
     | 
    
         
            -
                def in_rollup?
         
     | 
| 
       101 
     | 
    
         
            -
                  rollup? || under_rollup?
         
     | 
| 
       102 
     | 
    
         
            -
                end
         
     | 
| 
       103 
     | 
    
         
            -
                def on_top_rollup?
         
     | 
| 
       104 
     | 
    
         
            -
                  rollup? && !under_rollup?
         
     | 
| 
       105 
     | 
    
         
            -
                end
         
     | 
| 
       106 
     | 
    
         
            -
                def inherited_render_options
         
     | 
| 
       107 
     | 
    
         
            -
                  inherited = {}
         
     | 
| 
       108 
     | 
    
         
            -
                  inherited[:fontname] = parent.render_options[:fontname] if parent.render_options.include?(:fontname)
         
     | 
| 
       109 
     | 
    
         
            -
                  inherited
         
     | 
| 
       110 
     | 
    
         
            -
                end
         
     | 
| 
       111 
     | 
    
         
            -
              end
         
     | 
| 
       112 
     | 
    
         
            -
              module Parent
         
     | 
| 
       113 
     | 
    
         
            -
                def find_all(&matcher)
         
     | 
| 
       114 
     | 
    
         
            -
                  raise MissingMatchBlockError.new unless block_given?
         
     | 
| 
       115 
     | 
    
         
            -
                  @by_name.find_all &matcher
         
     | 
| 
       116 
     | 
    
         
            -
                end
         
     | 
| 
       117 
     | 
    
         
            -
                def find(name=nil, &matcher)
         
     | 
| 
       118 
     | 
    
         
            -
                  if block_given?
         
     | 
| 
       119 
     | 
    
         
            -
                    @by_name.find &matcher
         
     | 
| 
       120 
     | 
    
         
            -
                  else
         
     | 
| 
       121 
     | 
    
         
            -
                    raise 'Need to provide name or block' if name.nil?
         
     | 
| 
       122 
     | 
    
         
            -
                    @by_name.lookup name
         
     | 
| 
       123 
     | 
    
         
            -
                  end
         
     | 
| 
       124 
     | 
    
         
            -
                end
         
     | 
| 
       125 
     | 
    
         
            -
                def thing(name, options={})
         
     | 
| 
       126 
     | 
    
         
            -
                  add Thing.new self, name, options
         
     | 
| 
       127 
     | 
    
         
            -
                end
         
     | 
| 
       128 
     | 
    
         
            -
                def container(name, options={})
         
     | 
| 
       129 
     | 
    
         
            -
                  add Container.new self, name, options
         
     | 
| 
       130 
     | 
    
         
            -
                end
         
     | 
| 
       131 
     | 
    
         
            -
                def logical_container(name, options={})
         
     | 
| 
       132 
     | 
    
         
            -
                  add LogicalContainer.new self, name, options
         
     | 
| 
       133 
     | 
    
         
            -
                end
         
     | 
| 
       134 
     | 
    
         
            -
                def group(name, options={})
         
     | 
| 
       135 
     | 
    
         
            -
                  logical_container name, options
         
     | 
| 
       136 
     | 
    
         
            -
                end
         
     | 
| 
       137 
     | 
    
         
            -
                def add(child)
         
     | 
| 
       138 
     | 
    
         
            -
                  @children << child
         
     | 
| 
       139 
     | 
    
         
            -
                  child
         
     | 
| 
       140 
     | 
    
         
            -
                end
         
     | 
| 
       141 
     | 
    
         
            -
              end
         
     | 
| 
       142 
     | 
    
         
            -
             
     | 
| 
       143 
     | 
    
         
            -
              class Colorizer
         
     | 
| 
       144 
     | 
    
         
            -
                def initialize
         
     | 
| 
       145 
     | 
    
         
            -
                  @i = 0
         
     | 
| 
       146 
     | 
    
         
            -
                  @colors = %w(#9e0142
         
     | 
| 
       147 
     | 
    
         
            -
            #d53e4f
         
     | 
| 
       148 
     | 
    
         
            -
            #e45d33
         
     | 
| 
       149 
     | 
    
         
            -
            #ed9e61
         
     | 
| 
       150 
     | 
    
         
            -
            #762a83
         
     | 
| 
       151 
     | 
    
         
            -
            #9970ab
         
     | 
| 
       152 
     | 
    
         
            -
            #c6f578
         
     | 
| 
       153 
     | 
    
         
            -
            #abdda4
         
     | 
| 
       154 
     | 
    
         
            -
            #66c2a5
         
     | 
| 
       155 
     | 
    
         
            -
            #3288bd
         
     | 
| 
       156 
     | 
    
         
            -
            #5e4fa2)
         
     | 
| 
       157 
     | 
    
         
            -
                end
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
       159 
     | 
    
         
            -
                def next
         
     | 
| 
       160 
     | 
    
         
            -
                  color = @colors[@i]
         
     | 
| 
       161 
     | 
    
         
            -
                  @i += 1
         
     | 
| 
       162 
     | 
    
         
            -
                  @i = 0 unless @i < @colors.length
         
     | 
| 
       163 
     | 
    
         
            -
                  color
         
     | 
| 
       164 
     | 
    
         
            -
                end
         
     | 
| 
       165 
     | 
    
         
            -
              end
         
     | 
| 
       166 
     | 
    
         
            -
             
     | 
| 
       167 
     | 
    
         
            -
              class Thing
         
     | 
| 
       168 
     | 
    
         
            -
                include Common
         
     | 
| 
       169 
     | 
    
         
            -
                include Nominator
         
     | 
| 
       170 
     | 
    
         
            -
                include Flowable
         
     | 
| 
       171 
     | 
    
         
            -
                attr_reader :parent
         
     | 
| 
       172 
     | 
    
         
            -
                attr_reader :name, :id, :pointers, :edge_heads
         
     | 
| 
       173 
     | 
    
         
            -
             
     | 
| 
       174 
     | 
    
         
            -
                @@colorizer = Colorizer.new
         
     | 
| 
       175 
     | 
    
         
            -
             
     | 
| 
       176 
     | 
    
         
            -
                def initialize(parent, name, options = {})
         
     | 
| 
       177 
     | 
    
         
            -
                  @parent = parent
         
     | 
| 
       178 
     | 
    
         
            -
                  @name = name
         
     | 
| 
       179 
     | 
    
         
            -
                  @id = create_id(name, parent)
         
     | 
| 
       180 
     | 
    
         
            -
                  @pointers = []
         
     | 
| 
       181 
     | 
    
         
            -
                  @rollup = false
         
     | 
| 
       182 
     | 
    
         
            -
                  @skip = false
         
     | 
| 
       183 
     | 
    
         
            -
                  @info = {}
         
     | 
| 
       184 
     | 
    
         
            -
                  @edge_heads = []
         
     | 
| 
       185 
     | 
    
         
            -
             
     | 
| 
       186 
     | 
    
         
            -
                  rollup! if options[:rollup]
         
     | 
| 
       187 
     | 
    
         
            -
                  options.delete(:rollup)
         
     | 
| 
       188 
     | 
    
         
            -
             
     | 
| 
       189 
     | 
    
         
            -
                  @render_options = options
         
     | 
| 
       190 
     | 
    
         
            -
                  setup_render_attributes({label: name}.merge inherited_render_options)
         
     | 
| 
       191 
     | 
    
         
            -
             
     | 
| 
       192 
     | 
    
         
            -
                  parent.register name, self
         
     | 
| 
       193 
     | 
    
         
            -
                end
         
     | 
| 
       194 
     | 
    
         
            -
             
     | 
| 
       195 
     | 
    
         
            -
                def points_to_all(*others)
         
     | 
| 
       196 
     | 
    
         
            -
                  others.each {|other|
         
     | 
| 
       197 
     | 
    
         
            -
                    points_to other
         
     | 
| 
       198 
     | 
    
         
            -
                  }
         
     | 
| 
       199 
     | 
    
         
            -
                end
         
     | 
| 
       200 
     | 
    
         
            -
             
     | 
| 
       201 
     | 
    
         
            -
                def points_to(other, options = {})
         
     | 
| 
       202 
     | 
    
         
            -
                  setup_render_edge(other, options)
         
     | 
| 
       203 
     | 
    
         
            -
                  other
         
     | 
| 
       204 
     | 
    
         
            -
                end
         
     | 
| 
       205 
     | 
    
         
            -
             
     | 
| 
       206 
     | 
    
         
            -
                def render(renderer)
         
     | 
| 
       207 
     | 
    
         
            -
                  do_render_node(renderer) unless in_rollup? || in_skip?
         
     | 
| 
       208 
     | 
    
         
            -
                  end
         
     | 
| 
       209 
     | 
    
         
            -
             
     | 
| 
       210 
     | 
    
         
            -
                def render_edges(renderer)
         
     | 
| 
       211 
     | 
    
         
            -
                  pointers.each {|p|
         
     | 
| 
       212 
     | 
    
         
            -
                    render_pointer p, renderer
         
     | 
| 
       213 
     | 
    
         
            -
                  }
         
     | 
| 
       214 
     | 
    
         
            -
                end
         
     | 
| 
       215 
     | 
    
         
            -
             
     | 
| 
       216 
     | 
    
         
            -
                private
         
     | 
| 
       217 
     | 
    
         
            -
             
     | 
| 
       218 
     | 
    
         
            -
                def do_render_node(renderer)
         
     | 
| 
       219 
     | 
    
         
            -
                  render_options = @render_options
         
     | 
| 
       220 
     | 
    
         
            -
                  attributes = @attributes
         
     | 
| 
       221 
     | 
    
         
            -
                  renderer.render_node(parent, id, render_options, attributes)
         
     | 
| 
       222 
     | 
    
         
            -
                end
         
     | 
| 
       223 
     | 
    
         
            -
             
     | 
| 
       224 
     | 
    
         
            -
                def setup_render_edge(other, options)
         
     | 
| 
       225 
     | 
    
         
            -
                  pointers << {
         
     | 
| 
       226 
     | 
    
         
            -
                      other: other,
         
     | 
| 
       227 
     | 
    
         
            -
                      options: {
         
     | 
| 
       228 
     | 
    
         
            -
                          xlabel: options[:name],
         
     | 
| 
       229 
     | 
    
         
            -
                          style: options[:style]
         
     | 
| 
       230 
     | 
    
         
            -
                      }.merge(inherited_render_options)
         
     | 
| 
       231 
     | 
    
         
            -
                  }
         
     | 
| 
       232 
     | 
    
         
            -
             
     | 
| 
       233 
     | 
    
         
            -
                  if options[:colorize] || root.colorize_edges?
         
     | 
| 
       234 
     | 
    
         
            -
                    edge_color = next_colorizer_color
         
     | 
| 
       235 
     | 
    
         
            -
                    pointers.last[:options].merge!({
         
     | 
| 
       236 
     | 
    
         
            -
                      color: edge_color,
         
     | 
| 
       237 
     | 
    
         
            -
                      fontcolor: edge_color
         
     | 
| 
       238 
     | 
    
         
            -
                    })
         
     | 
| 
       239 
     | 
    
         
            -
                  end
         
     | 
| 
       240 
     | 
    
         
            -
             
     | 
| 
       241 
     | 
    
         
            -
                end
         
     | 
| 
       242 
     | 
    
         
            -
             
     | 
| 
       243 
     | 
    
         
            -
                def render_pointer(pointer, renderer)
         
     | 
| 
       244 
     | 
    
         
            -
                  other = pointer[:other]
         
     | 
| 
       245 
     | 
    
         
            -
                  while (other.in_rollup? && !other.on_top_rollup?) do
         
     | 
| 
       246 
     | 
    
         
            -
                    other = other.parent
         
     | 
| 
       247 
     | 
    
         
            -
                  end
         
     | 
| 
       248 
     | 
    
         
            -
                  return if other.under_rollup?
         
     | 
| 
       249 
     | 
    
         
            -
             
     | 
| 
       250 
     | 
    
         
            -
                  from = self
         
     | 
| 
       251 
     | 
    
         
            -
                  while (from.in_rollup? && !from.on_top_rollup?) do
         
     | 
| 
       252 
     | 
    
         
            -
                    from = from.parent
         
     | 
| 
       253 
     | 
    
         
            -
                  end
         
     | 
| 
       254 
     | 
    
         
            -
             
     | 
| 
       255 
     | 
    
         
            -
                  return if from.in_skip?
         
     | 
| 
       256 
     | 
    
         
            -
             
     | 
| 
       257 
     | 
    
         
            -
                  return if from == self && from.in_rollup?
         
     | 
| 
       258 
     | 
    
         
            -
                  return if from == other
         
     | 
| 
       259 
     | 
    
         
            -
                  return if already_added_connection?(other)
         
     | 
| 
       260 
     | 
    
         
            -
             
     | 
| 
       261 
     | 
    
         
            -
                  if other.in_skip?
         
     | 
| 
       262 
     | 
    
         
            -
                    others = resolve_skipped_others other
         
     | 
| 
       263 
     | 
    
         
            -
                  else
         
     | 
| 
       264 
     | 
    
         
            -
                    others = [other]
         
     | 
| 
       265 
     | 
    
         
            -
                  end
         
     | 
| 
       266 
     | 
    
         
            -
             
     | 
| 
       267 
     | 
    
         
            -
                  others.each do |other|
         
     | 
| 
       268 
     | 
    
         
            -
                    edge_heads << other
         
     | 
| 
       269 
     | 
    
         
            -
                    render_options = pointer[:options]
         
     | 
| 
       270 
     | 
    
         
            -
                    renderer.render_edge(from, other, render_options)
         
     | 
| 
       271 
     | 
    
         
            -
                  end
         
     | 
| 
       272 
     | 
    
         
            -
                end
         
     | 
| 
       273 
     | 
    
         
            -
             
     | 
| 
       274 
     | 
    
         
            -
                def already_added_connection?(other)
         
     | 
| 
       275 
     | 
    
         
            -
                  edge_heads.include? other
         
     | 
| 
       276 
     | 
    
         
            -
                end
         
     | 
| 
       277 
     | 
    
         
            -
             
     | 
| 
       278 
     | 
    
         
            -
                def resolve_skipped_others(skipped)
         
     | 
| 
       279 
     | 
    
         
            -
                  resolved = []
         
     | 
| 
       280 
     | 
    
         
            -
                  skipped.pointers.each {|pointer|
         
     | 
| 
       281 
     | 
    
         
            -
                    next_in_line = pointer[:other]
         
     | 
| 
       282 
     | 
    
         
            -
                    if next_in_line.in_skip?
         
     | 
| 
       283 
     | 
    
         
            -
                      resolved += resolve_skipped_others next_in_line
         
     | 
| 
       284 
     | 
    
         
            -
                    else
         
     | 
| 
       285 
     | 
    
         
            -
                      resolved << next_in_line
         
     | 
| 
       286 
     | 
    
         
            -
                    end
         
     | 
| 
       287 
     | 
    
         
            -
                  }
         
     | 
| 
       288 
     | 
    
         
            -
                  resolved
         
     | 
| 
       289 
     | 
    
         
            -
                end
         
     | 
| 
       290 
     | 
    
         
            -
             
     | 
| 
       291 
     | 
    
         
            -
                def next_colorizer_color
         
     | 
| 
       292 
     | 
    
         
            -
                  @@colorizer.next
         
     | 
| 
       293 
     | 
    
         
            -
                end
         
     | 
| 
       294 
     | 
    
         
            -
              end
         
     | 
| 
       295 
     | 
    
         
            -
             
     | 
| 
       296 
     | 
    
         
            -
              class Container
         
     | 
| 
       297 
     | 
    
         
            -
                include Common
         
     | 
| 
       298 
     | 
    
         
            -
                include Nominator
         
     | 
| 
       299 
     | 
    
         
            -
                include Parent
         
     | 
| 
       300 
     | 
    
         
            -
                attr_reader :parent
         
     | 
| 
       301 
     | 
    
         
            -
                attr_reader :name, :id, :node, :render_id, :render_type, :render_options, :children
         
     | 
| 
       302 
     | 
    
         
            -
             
     | 
| 
       303 
     | 
    
         
            -
                def initialize(parent, name, options = {})
         
     | 
| 
       304 
     | 
    
         
            -
                  @children = []
         
     | 
| 
       305 
     | 
    
         
            -
                  @by_name = Registry.new name
         
     | 
| 
       306 
     | 
    
         
            -
                  @parent = parent
         
     | 
| 
       307 
     | 
    
         
            -
                  @name = name
         
     | 
| 
       308 
     | 
    
         
            -
                  @id = create_id(name, parent)
         
     | 
| 
       309 
     | 
    
         
            -
                  @skip = false
         
     | 
| 
       310 
     | 
    
         
            -
                  @info = {}
         
     | 
| 
       311 
     | 
    
         
            -
             
     | 
| 
       312 
     | 
    
         
            -
                  init_rollup options
         
     | 
| 
       313 
     | 
    
         
            -
             
     | 
| 
       314 
     | 
    
         
            -
                  setup_render_attributes label: name
         
     | 
| 
       315 
     | 
    
         
            -
             
     | 
| 
       316 
     | 
    
         
            -
                  @render_options = options.merge inherited_render_options
         
     | 
| 
       317 
     | 
    
         
            -
             
     | 
| 
       318 
     | 
    
         
            -
                  parent.register name, self
         
     | 
| 
       319 
     | 
    
         
            -
                end
         
     | 
| 
       320 
     | 
    
         
            -
             
     | 
| 
       321 
     | 
    
         
            -
                def register(name, thing)
         
     | 
| 
       322 
     | 
    
         
            -
                  @by_name.register name, thing
         
     | 
| 
       323 
     | 
    
         
            -
                  parent.register name, thing
         
     | 
| 
       324 
     | 
    
         
            -
                end
         
     | 
| 
       325 
     | 
    
         
            -
             
     | 
| 
       326 
     | 
    
         
            -
                def render(renderer)
         
     | 
| 
       327 
     | 
    
         
            -
                  if on_top_rollup?
         
     | 
| 
       328 
     | 
    
         
            -
                    do_render_node renderer
         
     | 
| 
       329 
     | 
    
         
            -
                  elsif !under_rollup?
         
     | 
| 
       330 
     | 
    
         
            -
                    do_render_subgraph renderer
         
     | 
| 
       331 
     | 
    
         
            -
                  end
         
     | 
| 
       332 
     | 
    
         
            -
             
     | 
| 
       333 
     | 
    
         
            -
                  children.each {|c|
         
     | 
| 
       334 
     | 
    
         
            -
                    c.render renderer
         
     | 
| 
       335 
     | 
    
         
            -
                  }
         
     | 
| 
       336 
     | 
    
         
            -
                end
         
     | 
| 
       337 
     | 
    
         
            -
             
     | 
| 
       338 
     | 
    
         
            -
                def render_edges(renderer)
         
     | 
| 
       339 
     | 
    
         
            -
                  children.each {|c|
         
     | 
| 
       340 
     | 
    
         
            -
                    c.render_edges renderer
         
     | 
| 
       341 
     | 
    
         
            -
                  }
         
     | 
| 
       342 
     | 
    
         
            -
                end
         
     | 
| 
       343 
     | 
    
         
            -
             
     | 
| 
       344 
     | 
    
         
            -
                private
         
     | 
| 
       345 
     | 
    
         
            -
             
     | 
| 
       346 
     | 
    
         
            -
                def do_render_subgraph(renderer)
         
     | 
| 
       347 
     | 
    
         
            -
                  @render_type = :subgraph
         
     | 
| 
       348 
     | 
    
         
            -
                  render_id = cluster_prefix + id
         
     | 
| 
       349 
     | 
    
         
            -
                  attributes = @attributes
         
     | 
| 
       350 
     | 
    
         
            -
                  @render_id = render_id
         
     | 
| 
       351 
     | 
    
         
            -
                  @subgraph = renderer.render_subgraph(parent, render_id, render_options, attributes)
         
     | 
| 
       352 
     | 
    
         
            -
                end
         
     | 
| 
       353 
     | 
    
         
            -
             
     | 
| 
       354 
     | 
    
         
            -
                def do_render_node(renderer)
         
     | 
| 
       355 
     | 
    
         
            -
                  @render_type = :node
         
     | 
| 
       356 
     | 
    
         
            -
                  @render_id = id
         
     | 
| 
       357 
     | 
    
         
            -
                  render_id = @render_id
         
     | 
| 
       358 
     | 
    
         
            -
                  attributes = @attributes
         
     | 
| 
       359 
     | 
    
         
            -
                  renderer.render_node(parent, render_id, render_options, attributes)
         
     | 
| 
       360 
     | 
    
         
            -
                end
         
     | 
| 
       361 
     | 
    
         
            -
             
     | 
| 
       362 
     | 
    
         
            -
                def init_rollup(options)
         
     | 
| 
       363 
     | 
    
         
            -
                  @rollup = false
         
     | 
| 
       364 
     | 
    
         
            -
                  rollup! if options[:rollup]
         
     | 
| 
       365 
     | 
    
         
            -
                  options.delete(:rollup)
         
     | 
| 
       366 
     | 
    
         
            -
                end
         
     | 
| 
       367 
     | 
    
         
            -
             
     | 
| 
       368 
     | 
    
         
            -
                def cluster_prefix
         
     | 
| 
       369 
     | 
    
         
            -
                  is_cluster = true
         
     | 
| 
       370 
     | 
    
         
            -
                  if @render_options.has_key? :cluster
         
     | 
| 
       371 
     | 
    
         
            -
                    is_cluster = @render_options[:cluster]
         
     | 
| 
       372 
     | 
    
         
            -
                    @render_options.delete :cluster
         
     | 
| 
       373 
     | 
    
         
            -
                  end
         
     | 
| 
       374 
     | 
    
         
            -
                  cluster_prefix = (is_cluster ? 'cluster_' : '')
         
     | 
| 
       375 
     | 
    
         
            -
                end
         
     | 
| 
       376 
     | 
    
         
            -
             
     | 
| 
       377 
     | 
    
         
            -
              end
         
     | 
| 
       378 
     | 
    
         
            -
             
     | 
| 
       379 
     | 
    
         
            -
              class LogicalContainer < Container
         
     | 
| 
       380 
     | 
    
         
            -
                def initialize(parent, name, options)
         
     | 
| 
       381 
     | 
    
         
            -
                  super parent, name, options.merge(cluster: false)
         
     | 
| 
       382 
     | 
    
         
            -
                end
         
     | 
| 
       383 
     | 
    
         
            -
              end
         
     | 
| 
       384 
     | 
    
         
            -
             
     | 
| 
       385 
     | 
    
         
            -
              require 'date'
         
     | 
| 
       386 
     | 
    
         
            -
             
     | 
| 
       387 
     | 
    
         
            -
              class GraphvizRenderer
         
     | 
| 
       388 
     | 
    
         
            -
                attr_reader :graph
         
     | 
| 
       389 
     | 
    
         
            -
             
     | 
| 
       390 
     | 
    
         
            -
                def initialize(title, hints)
         
     | 
| 
       391 
     | 
    
         
            -
                  @graph = GraphViz.digraph(title)
         
     | 
| 
       392 
     | 
    
         
            -
                  @graph[hints]
         
     | 
| 
       393 
     | 
    
         
            -
                  @subgraphs = {}
         
     | 
| 
       394 
     | 
    
         
            -
                  @nodes = {}
         
     | 
| 
       395 
     | 
    
         
            -
                end
         
     | 
| 
       396 
     | 
    
         
            -
             
     | 
| 
       397 
     | 
    
         
            -
                def render_edge(from, other, options)
         
     | 
| 
       398 
     | 
    
         
            -
                  edge = graph.add_edges from.id, other.id
         
     | 
| 
       399 
     | 
    
         
            -
                  options.each { |key, value|
         
     | 
| 
       400 
     | 
    
         
            -
                    edge[key] = value unless value.nil?
         
     | 
| 
       401 
     | 
    
         
            -
                  }
         
     | 
| 
       402 
     | 
    
         
            -
                  edge
         
     | 
| 
       403 
     | 
    
         
            -
                end
         
     | 
| 
       404 
     | 
    
         
            -
             
     | 
| 
       405 
     | 
    
         
            -
                def render_node(parent, id, options, attributes)
         
     | 
| 
       406 
     | 
    
         
            -
                  clean_node_options options
         
     | 
| 
       407 
     | 
    
         
            -
                  default_options = {:shape => 'box', :style => ''}
         
     | 
| 
       408 
     | 
    
         
            -
                  node = parent_node(parent).add_nodes(id, default_options.merge(options))
         
     | 
| 
       409 
     | 
    
         
            -
                  apply_render_attributes node, attributes
         
     | 
| 
       410 
     | 
    
         
            -
                end
         
     | 
| 
       411 
     | 
    
         
            -
             
     | 
| 
       412 
     | 
    
         
            -
                def render_subgraph(parent, id, options, attributes)
         
     | 
| 
       413 
     | 
    
         
            -
                  subgraph = parent_node(parent).add_graph(id, options)
         
     | 
| 
       414 
     | 
    
         
            -
                  apply_render_attributes subgraph, attributes
         
     | 
| 
       415 
     | 
    
         
            -
                  @subgraphs[id] = subgraph
         
     | 
| 
       416 
     | 
    
         
            -
                  subgraph
         
     | 
| 
       417 
     | 
    
         
            -
                end
         
     | 
| 
       418 
     | 
    
         
            -
             
     | 
| 
       419 
     | 
    
         
            -
                private
         
     | 
| 
       420 
     | 
    
         
            -
             
     | 
| 
       421 
     | 
    
         
            -
                def clean_node_options(options)
         
     | 
| 
       422 
     | 
    
         
            -
                  options.delete(:rank)
         
     | 
| 
       423 
     | 
    
         
            -
                  options.delete(:cluster)
         
     | 
| 
       424 
     | 
    
         
            -
                  options
         
     | 
| 
       425 
     | 
    
         
            -
                end
         
     | 
| 
       426 
     | 
    
         
            -
             
     | 
| 
       427 
     | 
    
         
            -
                def parent_node(parent)
         
     | 
| 
       428 
     | 
    
         
            -
                  return graph unless parent.respond_to?(:render_id)
         
     | 
| 
       429 
     | 
    
         
            -
                  node = graph.search_node(parent.render_id)
         
     | 
| 
       430 
     | 
    
         
            -
                  return node unless node.nil?
         
     | 
| 
       431 
     | 
    
         
            -
                  subgraph = @subgraphs[parent.render_id]
         
     | 
| 
       432 
     | 
    
         
            -
                  raise "couldn't find node or graph: #{parent.render_id}, out of graphs: #{graph_ids}" if subgraph.nil?
         
     | 
| 
       433 
     | 
    
         
            -
                  subgraph
         
     | 
| 
       434 
     | 
    
         
            -
                end
         
     | 
| 
       435 
     | 
    
         
            -
             
     | 
| 
       436 
     | 
    
         
            -
                def apply_render_attributes(node, attributes)
         
     | 
| 
       437 
     | 
    
         
            -
                  attributes.each do |key, value|
         
     | 
| 
       438 
     | 
    
         
            -
                    node[key] = value
         
     | 
| 
       439 
     | 
    
         
            -
                  end
         
     | 
| 
       440 
     | 
    
         
            -
                end
         
     | 
| 
       441 
     | 
    
         
            -
              end
         
     | 
| 
       442 
     | 
    
         
            -
             
     | 
| 
       443 
     | 
    
         
            -
              class Flow
         
     | 
| 
       444 
     | 
    
         
            -
                def initialize(sys, name)
         
     | 
| 
       445 
     | 
    
         
            -
                  @sys = sys
         
     | 
| 
       446 
     | 
    
         
            -
                  @name = name
         
     | 
| 
       447 
     | 
    
         
            -
                  @calls = []
         
     | 
| 
       448 
     | 
    
         
            -
                end
         
     | 
| 
       449 
     | 
    
         
            -
             
     | 
| 
       450 
     | 
    
         
            -
                def make_connections
         
     | 
| 
       451 
     | 
    
         
            -
                  calls.each {|from, to, label|
         
     | 
| 
       452 
     | 
    
         
            -
                    thing_of(from).points_to thing_of(to), label: label
         
     | 
| 
       453 
     | 
    
         
            -
                  }
         
     | 
| 
       454 
     | 
    
         
            -
                end
         
     | 
| 
       455 
     | 
    
         
            -
             
     | 
| 
       456 
     | 
    
         
            -
                def flows(*steps)
         
     | 
| 
       457 
     | 
    
         
            -
                  from = nil
         
     | 
| 
       458 
     | 
    
         
            -
                  to = nil
         
     | 
| 
       459 
     | 
    
         
            -
                  label = nil
         
     | 
| 
       460 
     | 
    
         
            -
                  steps.each do |step|
         
     | 
| 
       461 
     | 
    
         
            -
                    if from.nil?
         
     | 
| 
       462 
     | 
    
         
            -
                      from = ensure_is_thing(step)
         
     | 
| 
       463 
     | 
    
         
            -
                    elsif label.nil? && step.is_a?(String)
         
     | 
| 
       464 
     | 
    
         
            -
                      label = step
         
     | 
| 
       465 
     | 
    
         
            -
                    elsif to.nil?
         
     | 
| 
       466 
     | 
    
         
            -
                      to = ensure_is_thing(step)
         
     | 
| 
       467 
     | 
    
         
            -
                    end
         
     | 
| 
       468 
     | 
    
         
            -
                    unless to.nil?
         
     | 
| 
       469 
     | 
    
         
            -
                      calls << [from, to, label]
         
     | 
| 
       470 
     | 
    
         
            -
                      from = to
         
     | 
| 
       471 
     | 
    
         
            -
                      to = label = nil
         
     | 
| 
       472 
     | 
    
         
            -
                    end
         
     | 
| 
       473 
     | 
    
         
            -
                  end
         
     | 
| 
       474 
     | 
    
         
            -
                end
         
     | 
| 
       475 
     | 
    
         
            -
             
     | 
| 
       476 
     | 
    
         
            -
                def ensure_is_thing(step)
         
     | 
| 
       477 
     | 
    
         
            -
                  raise "Expected some thing or process: '#{step}' already got: #{calls}" unless step.is_a?(Thing) || step.is_a?(Process)
         
     | 
| 
       478 
     | 
    
         
            -
                  step
         
     | 
| 
       479 
     | 
    
         
            -
                end
         
     | 
| 
       480 
     | 
    
         
            -
             
     | 
| 
       481 
     | 
    
         
            -
                def output(type_to_file)
         
     | 
| 
       482 
     | 
    
         
            -
                  type = type_to_file.keys.first
         
     | 
| 
       483 
     | 
    
         
            -
                  raise "Only support sequence, not: '#{type}'" unless type == :sequence
         
     | 
| 
       484 
     | 
    
         
            -
                  render.output(type_to_file)
         
     | 
| 
       485 
     | 
    
         
            -
                end
         
     | 
| 
       486 
     | 
    
         
            -
             
     | 
| 
       487 
     | 
    
         
            -
                def render
         
     | 
| 
       488 
     | 
    
         
            -
                  renderer = SequenceRenderer.new(@name)
         
     | 
| 
       489 
     | 
    
         
            -
                  calls.each do |from, to, label|
         
     | 
| 
       490 
     | 
    
         
            -
                    renderer.render_edge from, to, {label: label}
         
     | 
| 
       491 
     | 
    
         
            -
                  end
         
     | 
| 
       492 
     | 
    
         
            -
                  renderer.rendered
         
     | 
| 
       493 
     | 
    
         
            -
                end
         
     | 
| 
       494 
     | 
    
         
            -
             
     | 
| 
       495 
     | 
    
         
            -
                private
         
     | 
| 
       496 
     | 
    
         
            -
             
     | 
| 
       497 
     | 
    
         
            -
                attr_reader :calls, :sys
         
     | 
| 
       498 
     | 
    
         
            -
             
     | 
| 
       499 
     | 
    
         
            -
                def thing_of(it)
         
     | 
| 
       500 
     | 
    
         
            -
                  return it.processor if it.is_a?(Process)
         
     | 
| 
       501 
     | 
    
         
            -
                  it
         
     | 
| 
       502 
     | 
    
         
            -
                end
         
     | 
| 
       503 
     | 
    
         
            -
              end
         
     | 
| 
       504 
     | 
    
         
            -
             
     | 
| 
       505 
     | 
    
         
            -
             
     | 
| 
       506 
     | 
    
         
            -
              class RenderedSequence
         
     | 
| 
       507 
     | 
    
         
            -
                def initialize(lines)
         
     | 
| 
       508 
     | 
    
         
            -
                  @lines = lines
         
     | 
| 
       509 
     | 
    
         
            -
                end
         
     | 
| 
       510 
     | 
    
         
            -
                def output(type_to_file)
         
     | 
| 
       511 
     | 
    
         
            -
                  text = @lines.map(&:strip).join "\n"
         
     | 
| 
       512 
     | 
    
         
            -
                  File.write type_to_file.values.first, text
         
     | 
| 
       513 
     | 
    
         
            -
                  text
         
     | 
| 
       514 
     | 
    
         
            -
                end
         
     | 
| 
       515 
     | 
    
         
            -
              end
         
     | 
| 
       516 
     | 
    
         
            -
             
     | 
| 
       517 
     | 
    
         
            -
              class SequenceRenderer
         
     | 
| 
       518 
     | 
    
         
            -
                attr_reader :lines
         
     | 
| 
       519 
     | 
    
         
            -
                def initialize(title)
         
     | 
| 
       520 
     | 
    
         
            -
                  @lines = []
         
     | 
| 
       521 
     | 
    
         
            -
                end
         
     | 
| 
       522 
     | 
    
         
            -
             
     | 
| 
       523 
     | 
    
         
            -
                def render_edge(from, other, options)
         
     | 
| 
       524 
     | 
    
         
            -
             
     | 
| 
       525 
     | 
    
         
            -
                  detail = options[:label]
         
     | 
| 
       526 
     | 
    
         
            -
                  receiver_label = other.name
         
     | 
| 
       527 
     | 
    
         
            -
                  sender_label = from.name
         
     | 
| 
       528 
     | 
    
         
            -
                  if other.is_a?(Process)
         
     | 
| 
       529 
     | 
    
         
            -
                    detail = process_annotations(detail, sender_label, receiver_label, other.description)
         
     | 
| 
       530 
     | 
    
         
            -
                    receiver_label = process_start_label(receiver_label)
         
     | 
| 
       531 
     | 
    
         
            -
                  elsif from.is_a?(Process)
         
     | 
| 
       532 
     | 
    
         
            -
                    receiver_label = process_end_label(receiver_label)
         
     | 
| 
       533 
     | 
    
         
            -
                  end
         
     | 
| 
       534 
     | 
    
         
            -
                  lines << "#{sender_label} -> #{receiver_label}: #{detail}"
         
     | 
| 
       535 
     | 
    
         
            -
                end
         
     | 
| 
       536 
     | 
    
         
            -
             
     | 
| 
       537 
     | 
    
         
            -
                def rendered
         
     | 
| 
       538 
     | 
    
         
            -
                  RenderedSequence.new lines
         
     | 
| 
       539 
     | 
    
         
            -
                end
         
     | 
| 
       540 
     | 
    
         
            -
             
     | 
| 
       541 
     | 
    
         
            -
                private
         
     | 
| 
       542 
     | 
    
         
            -
             
     | 
| 
       543 
     | 
    
         
            -
                def process_start_label(receiver_label)
         
     | 
| 
       544 
     | 
    
         
            -
                  "+#{receiver_label}"
         
     | 
| 
       545 
     | 
    
         
            -
                end
         
     | 
| 
       546 
     | 
    
         
            -
             
     | 
| 
       547 
     | 
    
         
            -
                def process_end_label(receiver_label)
         
     | 
| 
       548 
     | 
    
         
            -
                  "-#{receiver_label}"
         
     | 
| 
       549 
     | 
    
         
            -
                end
         
     | 
| 
       550 
     | 
    
         
            -
             
     | 
| 
       551 
     | 
    
         
            -
                def process_annotations(detail, sender, receiver, process_description)
         
     | 
| 
       552 
     | 
    
         
            -
                  detail = [detail,
         
     | 
| 
       553 
     | 
    
         
            -
                            "note right of #{receiver}",
         
     | 
| 
       554 
     | 
    
         
            -
                            "  #{process_description}",
         
     | 
| 
       555 
     | 
    
         
            -
                            'end note'].join("\n")
         
     | 
| 
       556 
     | 
    
         
            -
                end
         
     | 
| 
       557 
     | 
    
         
            -
              end
         
     | 
| 
       558 
     | 
    
         
            -
             
     | 
| 
       559 
     | 
    
         
            -
              class System
         
     | 
| 
       560 
     | 
    
         
            -
                include Parent
         
     | 
| 
       561 
     | 
    
         
            -
                include Nominator
         
     | 
| 
       562 
     | 
    
         
            -
             
     | 
| 
       563 
     | 
    
         
            -
                attr_reader :render_hints, :title, :children, :graph
         
     | 
| 
       564 
     | 
    
         
            -
             
     | 
| 
       565 
     | 
    
         
            -
                alias :name :title
         
     | 
| 
       566 
     | 
    
         
            -
                alias :render_options :render_hints
         
     | 
| 
       567 
     | 
    
         
            -
             
     | 
| 
       568 
     | 
    
         
            -
                def initialize(name, hints = {splines: 'line'})
         
     | 
| 
       569 
     | 
    
         
            -
                  @children = []
         
     | 
| 
       570 
     | 
    
         
            -
                  @by_name = Registry.new name
         
     | 
| 
       571 
     | 
    
         
            -
                  @non_render_hints = remove_dogviz_hints!(hints)
         
     | 
| 
       572 
     | 
    
         
            -
                  @render_hints = hints
         
     | 
| 
       573 
     | 
    
         
            -
                  @title = create_title(name)
         
     | 
| 
       574 
     | 
    
         
            -
                  @rendered = false
         
     | 
| 
       575 
     | 
    
         
            -
                end
         
     | 
| 
       576 
     | 
    
         
            -
             
     | 
| 
       577 
     | 
    
         
            -
                def output(*args)
         
     | 
| 
       578 
     | 
    
         
            -
                  render
         
     | 
| 
       579 
     | 
    
         
            -
                  out = graph.output *args
         
     | 
| 
       580 
     | 
    
         
            -
                  puts "Created output: #{args.join ' '}" if run_from_command_line?
         
     | 
| 
       581 
     | 
    
         
            -
                  out
         
     | 
| 
       582 
     | 
    
         
            -
                end
         
     | 
| 
       583 
     | 
    
         
            -
             
     | 
| 
       584 
     | 
    
         
            -
                def flow(name)
         
     | 
| 
       585 
     | 
    
         
            -
                  Flow.new self, name
         
     | 
| 
       586 
     | 
    
         
            -
                end
         
     | 
| 
       587 
     | 
    
         
            -
             
     | 
| 
       588 
     | 
    
         
            -
                def render(type=:graphviz)
         
     | 
| 
       589 
     | 
    
         
            -
                  return @graph if @rendered
         
     | 
| 
       590 
     | 
    
         
            -
                  raise "dunno bout that '#{type}', only know :graphviz" unless type == :graphviz
         
     | 
| 
       591 
     | 
    
         
            -
             
     | 
| 
       592 
     | 
    
         
            -
                  renderer = GraphvizRenderer.new @title, render_hints
         
     | 
| 
       593 
     | 
    
         
            -
             
     | 
| 
       594 
     | 
    
         
            -
                  children.each {|c|
         
     | 
| 
       595 
     | 
    
         
            -
                    c.render renderer
         
     | 
| 
       596 
     | 
    
         
            -
                  }
         
     | 
| 
       597 
     | 
    
         
            -
                  children.each {|c|
         
     | 
| 
       598 
     | 
    
         
            -
                    c.render_edges renderer
         
     | 
| 
       599 
     | 
    
         
            -
                  }
         
     | 
| 
       600 
     | 
    
         
            -
                  @rendered = true
         
     | 
| 
       601 
     | 
    
         
            -
                  @graph = renderer.graph
         
     | 
| 
       602 
     | 
    
         
            -
                end
         
     | 
| 
       603 
     | 
    
         
            -
             
     | 
| 
       604 
     | 
    
         
            -
                def rollup?
         
     | 
| 
       605 
     | 
    
         
            -
                  false
         
     | 
| 
       606 
     | 
    
         
            -
                end
         
     | 
| 
       607 
     | 
    
         
            -
             
     | 
| 
       608 
     | 
    
         
            -
                def skip?
         
     | 
| 
       609 
     | 
    
         
            -
                  false
         
     | 
| 
       610 
     | 
    
         
            -
                end
         
     | 
| 
       611 
     | 
    
         
            -
             
     | 
| 
       612 
     | 
    
         
            -
                def register(name, thing)
         
     | 
| 
       613 
     | 
    
         
            -
                  @by_name.register name, thing
         
     | 
| 
       614 
     | 
    
         
            -
                end
         
     | 
| 
       615 
     | 
    
         
            -
             
     | 
| 
       616 
     | 
    
         
            -
                def colorize_edges?
         
     | 
| 
       617 
     | 
    
         
            -
                  @non_render_hints[:colorize_edges]
         
     | 
| 
       618 
     | 
    
         
            -
                end
         
     | 
| 
       619 
     | 
    
         
            -
             
     | 
| 
       620 
     | 
    
         
            -
                private
         
     | 
| 
       621 
     | 
    
         
            -
             
     | 
| 
       622 
     | 
    
         
            -
                def remove_dogviz_hints!(hints)
         
     | 
| 
       623 
     | 
    
         
            -
                  dogviz_only_hints = {}
         
     | 
| 
       624 
     | 
    
         
            -
                  %i(colorize_edges).each {|k|
         
     | 
| 
       625 
     | 
    
         
            -
                    dogviz_only_hints[k] = hints.delete k
         
     | 
| 
       626 
     | 
    
         
            -
                  }
         
     | 
| 
       627 
     | 
    
         
            -
                  dogviz_only_hints
         
     | 
| 
       628 
     | 
    
         
            -
                end
         
     | 
| 
       629 
     | 
    
         
            -
             
     | 
| 
       630 
     | 
    
         
            -
                def create_title(name)
         
     | 
| 
       631 
     | 
    
         
            -
                  now = DateTime.now
         
     | 
| 
       632 
     | 
    
         
            -
                  "#{now.strftime '%H:%M'} #{name} #{now.strftime '%F'}"
         
     | 
| 
       633 
     | 
    
         
            -
                end
         
     | 
| 
       634 
     | 
    
         
            -
             
     | 
| 
       635 
     | 
    
         
            -
                def run_from_command_line?
         
     | 
| 
       636 
     | 
    
         
            -
                  $stdout.isatty
         
     | 
| 
       637 
     | 
    
         
            -
                end
         
     | 
| 
       638 
     | 
    
         
            -
              end
         
     | 
| 
       639 
     | 
    
         
            -
             
     | 
| 
       640 
     | 
    
         
            -
              class LookupError < StandardError
         
     | 
| 
       641 
     | 
    
         
            -
                def initialize(context, message)
         
     | 
| 
       642 
     | 
    
         
            -
                  super "(in context '#{context}') #{message}"
         
     | 
| 
       643 
     | 
    
         
            -
                end
         
     | 
| 
       644 
     | 
    
         
            -
              end
         
     | 
| 
       645 
     | 
    
         
            -
              class MissingMatchBlockError < LookupError
         
     | 
| 
       646 
     | 
    
         
            -
                def initialize(context)
         
     | 
| 
       647 
     | 
    
         
            -
                  super context, 'need to provide match block'
         
     | 
| 
       648 
     | 
    
         
            -
                end
         
     | 
| 
       649 
     | 
    
         
            -
              end
         
     | 
| 
       650 
     | 
    
         
            -
              class DuplicateLookupError < LookupError
         
     | 
| 
       651 
     | 
    
         
            -
                def initialize(context, name)
         
     | 
| 
       652 
     | 
    
         
            -
                  super context, "More than one object registered of name '#{name}' - you'll need to search in a narrower context"
         
     | 
| 
       653 
     | 
    
         
            -
                end
         
     | 
| 
       654 
     | 
    
         
            -
              end
         
     | 
| 
       655 
     | 
    
         
            -
              class Registry
         
     | 
| 
       656 
     | 
    
         
            -
                def initialize(context)
         
     | 
| 
       657 
     | 
    
         
            -
                  @context = context
         
     | 
| 
       658 
     | 
    
         
            -
                  @by_name = {}
         
     | 
| 
       659 
     | 
    
         
            -
                  @all = []
         
     | 
| 
       660 
     | 
    
         
            -
                end
         
     | 
| 
       661 
     | 
    
         
            -
             
     | 
| 
       662 
     | 
    
         
            -
                def register(name, thing)
         
     | 
| 
       663 
     | 
    
         
            -
                  @all << thing
         
     | 
| 
       664 
     | 
    
         
            -
                  if @by_name.has_key?(name)
         
     | 
| 
       665 
     | 
    
         
            -
                    @by_name[name] = DuplicateLookupError.new @context, name
         
     | 
| 
       666 
     | 
    
         
            -
                  else
         
     | 
| 
       667 
     | 
    
         
            -
                    @by_name[name] = thing
         
     | 
| 
       668 
     | 
    
         
            -
                  end
         
     | 
| 
       669 
     | 
    
         
            -
                end
         
     | 
| 
       670 
     | 
    
         
            -
             
     | 
| 
       671 
     | 
    
         
            -
                def find(&matcher)
         
     | 
| 
       672 
     | 
    
         
            -
                  raise LookupError.new(@context, "need to provide match block") unless block_given?
         
     | 
| 
       673 
     | 
    
         
            -
                  @all.find &matcher
         
     | 
| 
       674 
     | 
    
         
            -
                end
         
     | 
| 
       675 
     | 
    
         
            -
             
     | 
| 
       676 
     | 
    
         
            -
                def find_all(&matcher)
         
     | 
| 
       677 
     | 
    
         
            -
                  raise MissingMatchBlockError.new(@context) unless block_given?
         
     | 
| 
       678 
     | 
    
         
            -
                  @all.select &matcher
         
     | 
| 
       679 
     | 
    
         
            -
                end
         
     | 
| 
       680 
     | 
    
         
            -
             
     | 
| 
       681 
     | 
    
         
            -
                def lookup(name)
         
     | 
| 
       682 
     | 
    
         
            -
                  found = @by_name[name]
         
     | 
| 
       683 
     | 
    
         
            -
                  raise LookupError.new(@context, "could not find '#{name}'") if found.nil?
         
     | 
| 
       684 
     | 
    
         
            -
                  raise found if found.is_a?(Exception)
         
     | 
| 
       685 
     | 
    
         
            -
                  found
         
     | 
| 
       686 
     | 
    
         
            -
                end
         
     | 
| 
       687 
     | 
    
         
            -
              end
         
     | 
| 
       688 
     | 
    
         
            -
             
     | 
| 
       689 
     | 
    
         
            -
            end
         
     | 
| 
      
 8 
     | 
    
         
            +
            require_relative 'dogviz/flow.rb'
         
     | 
| 
      
 9 
     | 
    
         
            +
            require_relative 'dogviz/system.rb'
         
     |