trailblazer-future 2.1.0.rc1

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.
Files changed (161) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.travis.yml +6 -0
  4. data/CHANGES.md +4 -0
  5. data/LICENSE.txt +9 -0
  6. data/README.md +48 -0
  7. data/Rakefile +10 -0
  8. data/bin/console +14 -0
  9. data/bin/setup +8 -0
  10. data/gems.rb +3 -0
  11. data/lib/trailblazer/future.rb +9 -0
  12. data/lib/trailblazer/future/version.rb +5 -0
  13. data/lib/trailblazer/v2_1/activity.rb +123 -0
  14. data/lib/trailblazer/v2_1/activity/config.rb +37 -0
  15. data/lib/trailblazer/v2_1/activity/dsl/add_task.rb +22 -0
  16. data/lib/trailblazer/v2_1/activity/dsl/helper.rb +68 -0
  17. data/lib/trailblazer/v2_1/activity/dsl/magnetic.rb +36 -0
  18. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder.rb +101 -0
  19. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/default_normalizer.rb +26 -0
  20. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/fast_track.rb +118 -0
  21. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/normalizer.rb +113 -0
  22. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/path.rb +105 -0
  23. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/railway.rb +97 -0
  24. data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/state.rb +58 -0
  25. data/lib/trailblazer/v2_1/activity/dsl/magnetic/finalizer.rb +51 -0
  26. data/lib/trailblazer/v2_1/activity/dsl/magnetic/generate.rb +62 -0
  27. data/lib/trailblazer/v2_1/activity/dsl/magnetic/merge.rb +16 -0
  28. data/lib/trailblazer/v2_1/activity/dsl/magnetic/process_options.rb +76 -0
  29. data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/alterations.rb +44 -0
  30. data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/plus_poles.rb +85 -0
  31. data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/polarization.rb +23 -0
  32. data/lib/trailblazer/v2_1/activity/dsl/record.rb +11 -0
  33. data/lib/trailblazer/v2_1/activity/dsl/schema/dependencies.rb +46 -0
  34. data/lib/trailblazer/v2_1/activity/dsl/schema/sequence.rb +46 -0
  35. data/lib/trailblazer/v2_1/activity/dsl/strategy/build_state.rb +32 -0
  36. data/lib/trailblazer/v2_1/activity/dsl/strategy/fast_track.rb +24 -0
  37. data/lib/trailblazer/v2_1/activity/dsl/strategy/path.rb +26 -0
  38. data/lib/trailblazer/v2_1/activity/dsl/strategy/plan.rb +36 -0
  39. data/lib/trailblazer/v2_1/activity/dsl/strategy/railway.rb +23 -0
  40. data/lib/trailblazer/v2_1/activity/interface.rb +16 -0
  41. data/lib/trailblazer/v2_1/activity/introspect.rb +167 -0
  42. data/lib/trailblazer/v2_1/activity/present.rb +95 -0
  43. data/lib/trailblazer/v2_1/activity/structures.rb +57 -0
  44. data/lib/trailblazer/v2_1/activity/task_builder.rb +41 -0
  45. data/lib/trailblazer/v2_1/activity/task_wrap.rb +40 -0
  46. data/lib/trailblazer/v2_1/activity/task_wrap/call_task.rb +19 -0
  47. data/lib/trailblazer/v2_1/activity/task_wrap/merge.rb +23 -0
  48. data/lib/trailblazer/v2_1/activity/task_wrap/runner.rb +62 -0
  49. data/lib/trailblazer/v2_1/activity/task_wrap/trace.rb +44 -0
  50. data/lib/trailblazer/v2_1/activity/task_wrap/variable_mapping.rb +162 -0
  51. data/lib/trailblazer/v2_1/activity/testing.rb +32 -0
  52. data/lib/trailblazer/v2_1/activity/trace.rb +97 -0
  53. data/lib/trailblazer/v2_1/circuit.rb +71 -0
  54. data/lib/trailblazer/v2_1/container_chain.rb +45 -0
  55. data/lib/trailblazer/v2_1/context.rb +79 -0
  56. data/lib/trailblazer/v2_1/deprecation/call.rb +46 -0
  57. data/lib/trailblazer/v2_1/deprecation/context.rb +43 -0
  58. data/lib/trailblazer/v2_1/dsl.rb +47 -0
  59. data/lib/trailblazer/v2_1/macro.rb +11 -0
  60. data/lib/trailblazer/v2_1/macro/contract.rb +5 -0
  61. data/lib/trailblazer/v2_1/operation.rb +91 -0
  62. data/lib/trailblazer/v2_1/operation/auto_inject.rb +47 -0
  63. data/lib/trailblazer/v2_1/operation/callable.rb +42 -0
  64. data/lib/trailblazer/v2_1/operation/class_dependencies.rb +25 -0
  65. data/lib/trailblazer/v2_1/operation/contract.rb +61 -0
  66. data/lib/trailblazer/v2_1/operation/deprecated_macro.rb +19 -0
  67. data/lib/trailblazer/v2_1/operation/deprecations.rb +21 -0
  68. data/lib/trailblazer/v2_1/operation/guard.rb +18 -0
  69. data/lib/trailblazer/v2_1/operation/heritage.rb +30 -0
  70. data/lib/trailblazer/v2_1/operation/inject.rb +36 -0
  71. data/lib/trailblazer/v2_1/operation/inspect.rb +79 -0
  72. data/lib/trailblazer/v2_1/operation/model.rb +50 -0
  73. data/lib/trailblazer/v2_1/operation/module.rb +29 -0
  74. data/lib/trailblazer/v2_1/operation/nested.rb +98 -0
  75. data/lib/trailblazer/v2_1/operation/persist.rb +14 -0
  76. data/lib/trailblazer/v2_1/operation/policy.rb +44 -0
  77. data/lib/trailblazer/v2_1/operation/public_call.rb +55 -0
  78. data/lib/trailblazer/v2_1/operation/pundit.rb +38 -0
  79. data/lib/trailblazer/v2_1/operation/railway.rb +32 -0
  80. data/lib/trailblazer/v2_1/operation/railway/fast_track.rb +13 -0
  81. data/lib/trailblazer/v2_1/operation/railway/macaroni.rb +23 -0
  82. data/lib/trailblazer/v2_1/operation/railway/normalizer.rb +58 -0
  83. data/lib/trailblazer/v2_1/operation/railway/task_builder.rb +37 -0
  84. data/lib/trailblazer/v2_1/operation/rescue.rb +42 -0
  85. data/lib/trailblazer/v2_1/operation/responder.rb +18 -0
  86. data/lib/trailblazer/v2_1/operation/result.rb +30 -0
  87. data/lib/trailblazer/v2_1/operation/test.rb +17 -0
  88. data/lib/trailblazer/v2_1/operation/trace.rb +46 -0
  89. data/lib/trailblazer/v2_1/operation/validate.rb +76 -0
  90. data/lib/trailblazer/v2_1/operation/wrap.rb +83 -0
  91. data/lib/trailblazer/v2_1/option.rb +78 -0
  92. data/lib/trailblazer/v2_1/rails.rb +12 -0
  93. data/lib/trailblazer/v2_1/rails/cell.rb +22 -0
  94. data/lib/trailblazer/v2_1/rails/controller.rb +66 -0
  95. data/lib/trailblazer/v2_1/rails/form.rb +21 -0
  96. data/lib/trailblazer/v2_1/rails/railtie.rb +31 -0
  97. data/lib/trailblazer/v2_1/rails/railtie/extend_application_controller.rb +28 -0
  98. data/lib/trailblazer/v2_1/rails/railtie/loader.rb +58 -0
  99. data/lib/trailblazer/v2_1/rails/test/integration.rb +6 -0
  100. data/lib/trailblazer/v2_1/versions.txt +7 -0
  101. data/test/rails5.0/.gitignore +17 -0
  102. data/test/rails5.0/Gemfile +21 -0
  103. data/test/rails5.0/Rakefile +3 -0
  104. data/test/rails5.0/app/concepts/artist/cell/dashboard.rb +7 -0
  105. data/test/rails5.0/app/concepts/artist/cell/show.rb +4 -0
  106. data/test/rails5.0/app/concepts/artist/view/dashboard.erb +4 -0
  107. data/test/rails5.0/app/concepts/artist/view/show.erb +1 -0
  108. data/test/rails5.0/app/concepts/params/operation/with_args.rb +5 -0
  109. data/test/rails5.0/app/concepts/song/contract/form.rb +6 -0
  110. data/test/rails5.0/app/concepts/song/operation/create.rb +15 -0
  111. data/test/rails5.0/app/concepts/song/operation/show.rb +3 -0
  112. data/test/rails5.0/app/concepts/song/operation/update.rb +15 -0
  113. data/test/rails5.0/app/controllers/application_controller.rb +46 -0
  114. data/test/rails5.0/app/controllers/args_controller.rb +5 -0
  115. data/test/rails5.0/app/controllers/artists_controller.rb +24 -0
  116. data/test/rails5.0/app/controllers/params_controller.rb +11 -0
  117. data/test/rails5.0/app/controllers/songs_controller.rb +35 -0
  118. data/test/rails5.0/app/models/artist.rb +2 -0
  119. data/test/rails5.0/app/models/song.rb +2 -0
  120. data/test/rails5.0/app/views/args/with_args.html.erb +1 -0
  121. data/test/rails5.0/app/views/layouts/application.html.erb +2 -0
  122. data/test/rails5.0/app/views/songs/edit.html.erb +4 -0
  123. data/test/rails5.0/app/views/songs/new.html.erb +5 -0
  124. data/test/rails5.0/app/views/songs/new_with_result.html.erb +3 -0
  125. data/test/rails5.0/app/views/songs/show.html.erb +3 -0
  126. data/test/rails5.0/bin/bundle +3 -0
  127. data/test/rails5.0/bin/rails +4 -0
  128. data/test/rails5.0/bin/rake +4 -0
  129. data/test/rails5.0/bin/setup +29 -0
  130. data/test/rails5.0/config.ru +4 -0
  131. data/test/rails5.0/config/application.rb +25 -0
  132. data/test/rails5.0/config/boot.rb +3 -0
  133. data/test/rails5.0/config/database.yml +21 -0
  134. data/test/rails5.0/config/environment.rb +5 -0
  135. data/test/rails5.0/config/environments/development.rb +41 -0
  136. data/test/rails5.0/config/environments/test.rb +42 -0
  137. data/test/rails5.0/config/initializers/assets.rb +11 -0
  138. data/test/rails5.0/config/initializers/backtrace_silencers.rb +7 -0
  139. data/test/rails5.0/config/initializers/cookies_serializer.rb +3 -0
  140. data/test/rails5.0/config/initializers/filter_parameter_logging.rb +4 -0
  141. data/test/rails5.0/config/initializers/inflections.rb +16 -0
  142. data/test/rails5.0/config/initializers/mime_types.rb +4 -0
  143. data/test/rails5.0/config/initializers/session_store.rb +3 -0
  144. data/test/rails5.0/config/initializers/wrap_parameters.rb +14 -0
  145. data/test/rails5.0/config/locales/en.yml +23 -0
  146. data/test/rails5.0/config/routes.rb +15 -0
  147. data/test/rails5.0/config/secrets.yml +17 -0
  148. data/test/rails5.0/db/migrate/20161122145124_create_songs.rb +8 -0
  149. data/test/rails5.0/db/schema.rb +19 -0
  150. data/test/rails5.0/log/.keep +0 -0
  151. data/test/rails5.0/test/concepts/song/operation/create_test.rb +11 -0
  152. data/test/rails5.0/test/concepts/song/operation/update_test.rb +34 -0
  153. data/test/rails5.0/test/integration/.keep +0 -0
  154. data/test/rails5.0/test/integration/args_controller_test.rb +8 -0
  155. data/test/rails5.0/test/integration/artists_controller_test.rb +28 -0
  156. data/test/rails5.0/test/integration/params_controller_test.rb +8 -0
  157. data/test/rails5.0/test/integration/songs_controller_test.rb +40 -0
  158. data/test/rails5.0/test/test_helper.rb +7 -0
  159. data/test/test_helper.rb +5 -0
  160. data/trailblazer-future.gemspec +25 -0
  161. metadata +246 -0
@@ -0,0 +1,23 @@
1
+ module Trailblazer::V2_1
2
+ module Activity::Magnetic
3
+ module DSL
4
+ # Every DSL method creates a set of polarizations that are evaluated and decide about a task's
5
+ # incoming and outgoing connections.
6
+ #
7
+ # @note The API of Polarization might be simplified soon.
8
+ # @api private
9
+ class Polarization
10
+ def initialize( output:raise, color:raise )
11
+ @output, @color = output, color
12
+ end
13
+
14
+ def call(magnetic_to, plus_poles, options)
15
+ [
16
+ magnetic_to,
17
+ plus_poles.merge( @output => @color ) # this usually adds a new Output to the task.
18
+ ]
19
+ end
20
+ end # Polarization
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,11 @@
1
+ module Trailblazer::V2_1
2
+ class Activity < Module
3
+ module DSL
4
+ # {:extension API}
5
+ # Record each DSL call (like #step) on the activity.
6
+ def self.record(activity, *args, original_dsl_args:)
7
+ activity[:record, original_dsl_args[1]] = original_dsl_args
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,46 @@
1
+ module Trailblazer::V2_1
2
+ module Activity::Schema
3
+ # Helps organizing the structure of the circuit and allows to define steps that
4
+ # might be inserted in a completely different order, but it's experimental.
5
+ #
6
+ # Translates linear DSL calls that might refer to the same task several times into a linear "drawing instruction"
7
+ # that can be consumed by Schema.bla.
8
+ #
9
+ # This class is experimental.
10
+ class Dependencies
11
+ def initialize
12
+ @groups = {
13
+ start: Sequence.new,
14
+ main: Sequence.new, # normal steps
15
+ end: Sequence.new, # ends
16
+ unresolved: Sequence.new, # div
17
+ }
18
+
19
+ @order = [ :start, :main, :end, :unresolved ]
20
+ end
21
+
22
+ def add(id, seq_options, group: :main, **sequence_options)
23
+ group = @groups[group] or raise "unknown group #{group}, implement me"
24
+
25
+ group.add(id, seq_options, **sequence_options) # handles
26
+ end
27
+
28
+ def to_a
29
+ @order.collect{ |name| @groups[name].to_a }.flatten(1)
30
+ end
31
+
32
+ # @api private
33
+ def find(id)
34
+ @groups.find do |name, group|
35
+ index = group.send( :find_index, id )
36
+ return group, index if index
37
+ end
38
+ end
39
+
40
+ # @api private
41
+ def self.sequence_keywords
42
+ [ :group, :before, :after, :replace, :delete ]
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ module Trailblazer::V2_1
2
+ module Activity::Schema
3
+ # the list of what tasks to add to the graph, for the "drawer"
4
+ # produces immutable list of: (node, magnetic_to (incoming colors), outgoing colors)
5
+ # via #to_a
6
+
7
+ #mutable, for DSL
8
+ #
9
+ # @api private
10
+ class Sequence < ::Array
11
+ Element = Struct.new(:id, :configuration)
12
+
13
+ # Insert the task into {Sequence} array by respecting options such as `:before`.
14
+ # This mutates the object per design.
15
+ #
16
+ # @param wiring [ [:success, :special_1], A, [ Output, Output ] ]
17
+ def add(id, wiring, before:nil, after:nil, replace:nil, delete:nil)
18
+ element = Element.new(id, wiring).freeze
19
+
20
+ return insert(find_index!(before), element) if before
21
+ return insert(find_index!(after)+1, element) if after
22
+ return self[find_index!(replace)] = element if replace
23
+ return delete_at(find_index!(delete)) if delete
24
+
25
+ self << element
26
+ end
27
+
28
+ def to_a
29
+ collect { |element| element.configuration }
30
+ end
31
+
32
+ private
33
+
34
+ def find_index(id)
35
+ element = find { |el| el.id == id }
36
+ index(element)
37
+ end
38
+
39
+ def find_index!(id)
40
+ find_index(id) or raise IndexError.new(id)
41
+ end
42
+
43
+ class IndexError < IndexError; end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,32 @@
1
+ class Trailblazer::V2_1::Activity < Module
2
+ module BuildState
3
+ # Compute all objects that need to be passed into the new Activity module.
4
+ # 1. Build the normalizer (unless passed with :normalizer)
5
+ # 2. Build the builder (in State)
6
+ # 3. Let State compute all state variables (that implies recompiling the Process)
7
+ #
8
+ # @return [Builder, Adds, Process, Outputs, remaining options]
9
+ # @api private
10
+ def self.build_state_for(default_options, options)
11
+ options = default_options.merge(options) # TODO: use Variables::Merge() here.
12
+ normalizer, options = build_normalizer(options)
13
+ builder, adds, circuit, outputs, options = build_state(normalizer, options)
14
+ end
15
+
16
+ # Builds the normalizer (to process options in DSL calls) unless {:normalizer} is already set.
17
+ #
18
+ # @api private
19
+ def self.build_normalizer(normalizer_class:, normalizer: false, **options)
20
+ normalizer, options = normalizer_class.build( options ) unless normalizer
21
+
22
+ return normalizer, options
23
+ end
24
+
25
+ # @api private
26
+ def self.build_state(normalizer, builder_class:, builder_options: {}, **options)
27
+ builder, adds, circuit, outputs = Magnetic::Builder::State.build(builder_class, normalizer, options.merge(builder_options))
28
+
29
+ return builder, adds, circuit, outputs, options
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,24 @@
1
+ class Trailblazer::V2_1::Activity < Module
2
+ def self.FastTrack(options={})
3
+ FastTrack.new(FastTrack, options)
4
+ end
5
+
6
+ # Implementation module that can be passed to `Activity[]`.
7
+ class FastTrack < Trailblazer::V2_1::Activity
8
+ def self.config
9
+ Railway.config.merge(
10
+ builder_class: Magnetic::Builder::FastTrack,
11
+ extend: [
12
+ DSL.def_dsl(:step, Magnetic::Builder::FastTrack, :StepPolarizations),
13
+ DSL.def_dsl(:fail, Magnetic::Builder::FastTrack, :FailPolarizations),
14
+ DSL.def_dsl(:pass, Magnetic::Builder::FastTrack, :PassPolarizations),
15
+ DSL.def_dsl(:_end, Magnetic::Builder::Path, :EndEventPolarizations), # TODO: TEST ME
16
+ ],
17
+ )
18
+ end
19
+
20
+ # Signals
21
+ FailFast = Class.new(Signal)
22
+ PassFast = Class.new(Signal)
23
+ end
24
+ end
@@ -0,0 +1,26 @@
1
+ module Trailblazer::V2_1
2
+ class Activity < Module
3
+ def self.Path(options={})
4
+ Activity::Path.new(Path, options)
5
+ end
6
+
7
+ # Implementation module that can be passed to `Activity[]`.
8
+ class Path < Activity
9
+ # Default variables, called in {Activity::initialize}.
10
+ def self.config
11
+ {
12
+ builder_class: Magnetic::Builder::Path, # we use the Activity-based Normalizer
13
+ normalizer_class: Magnetic::Normalizer,
14
+ default_outputs: Magnetic::Builder::Path.default_outputs, # binary outputs
15
+
16
+ extend: [
17
+ # DSL.def_dsl(:task, Magnetic::Builder::Path, :PassPolarizations),
18
+ DSL.def_dsl(:_end, Magnetic::Builder::Path, :EndEventPolarizations),
19
+ DSL.def_dsl(:task, Magnetic::Builder::Railway, :PassPolarizations),
20
+ ],
21
+ }
22
+ end
23
+ end # Path
24
+ end
25
+ end
26
+
@@ -0,0 +1,36 @@
1
+ module Trailblazer::V2_1
2
+ class Activity::Path < Activity
3
+ def self.Plan()
4
+ Plan
5
+ end
6
+
7
+ module Plan
8
+ def self.extended(extended)
9
+ extended.singleton_class.send :attr_accessor, :record
10
+ extended.record = []
11
+ extended.extend(Methods)
12
+ end
13
+
14
+ module Methods
15
+ def task(*args, &block)
16
+ record << [:task, args, block]
17
+ end
18
+ end
19
+
20
+ def self.merge!(activity, plan)
21
+ plan.record.each { |(dsl_method, args, block)| activity.send(dsl_method, *args, &block) }
22
+ activity
23
+ end
24
+
25
+ # Creates a copy of the {activity} module and merges the {Plan} into it.
26
+ #
27
+ # @params activity [Activity] The activity to extend
28
+ # @params plan [Plan] The plan providing additional steps
29
+ # @return [Activity] A new, merged activity
30
+ def self.merge(activity, plan)
31
+ merge!(activity.clone, plan)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,23 @@
1
+ module Trailblazer::V2_1
2
+ # Implementation module that can be passed to `Activity[]`.
3
+ class Activity < Module
4
+ def self.Railway(options={})
5
+ Railway.new(Railway, options)
6
+ end
7
+
8
+ class Railway < Activity
9
+ def self.config
10
+ Path.config.merge(
11
+ builder_class: Magnetic::Builder::Railway,
12
+ default_outputs: Magnetic::Builder::Path.default_outputs,
13
+ extend: [
14
+ DSL.def_dsl(:step, Magnetic::Builder::Railway, :StepPolarizations),
15
+ DSL.def_dsl(:fail, Magnetic::Builder::Railway, :FailPolarizations),
16
+ DSL.def_dsl(:pass, Magnetic::Builder::Railway, :PassPolarizations),
17
+ DSL.def_dsl(:_end, Magnetic::Builder::Path, :EndEventPolarizations), # TODO: TEST ME
18
+ ],
19
+ )
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,16 @@
1
+ class Trailblazer::V2_1::Activity < Module
2
+ module Interface
3
+ # @return [Process, Hash, Adds] Adds is private and should not be used in your application as it might get removed.
4
+ def to_h # TODO: test me
5
+ @state.to_h
6
+ end
7
+
8
+ def debug # TODO: TEST ME
9
+ to_h[:debug]
10
+ end
11
+
12
+ def outputs
13
+ to_h[:outputs]
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,167 @@
1
+ module Trailblazer::V2_1
2
+ class Activity < Module
3
+ # Compile-time.
4
+ # Introspection is not used at run-time except for rendering diagrams, tracing, and the like.
5
+ module Introspect
6
+ def self.Graph(*args)
7
+ Graph.new(*args)
8
+ end
9
+
10
+ # @private This API is still under construction.
11
+ class Graph
12
+ def initialize(activity)
13
+ @activity = activity
14
+ @circuit = activity.to_h[:circuit]
15
+ @adds = activity.to_h[:adds].compact # FIXME: why are there nils in Adds?
16
+ end
17
+
18
+ def find(id=nil, &block)
19
+ return find_by_id(id) unless block_given?
20
+ find_with_block(&block)
21
+ end
22
+
23
+ private
24
+
25
+ def find_by_id(id)
26
+ (_, (id, triplett)) = @adds.find { |(op, (_id, triplett))| _id == id }
27
+
28
+ Node(triplett[1], id, triplett[0])
29
+ end
30
+
31
+ def find_with_block(&block)
32
+ adds = @adds.find { |(op, (id, triplett))| yield( Node(triplett[1], id, triplett[0]) ) }
33
+ return nil unless adds
34
+
35
+ (op, (id, triplett)) = adds
36
+
37
+ Node(triplett[1], id, triplett[0])
38
+ end
39
+
40
+ def Node(*args)
41
+ Node.new(*args).freeze
42
+ end
43
+
44
+ Node = Struct.new(:task, :id, :magnetic_to)
45
+ end
46
+
47
+
48
+ # FIXME: remove this
49
+ # @private This will be removed shortly.
50
+ def self.collect(activity, options={}, &block)
51
+ circuit = activity.to_h[:circuit]
52
+ circuit_hash = circuit.to_h[:map]
53
+
54
+ locals = circuit_hash.collect do |task, connections|
55
+ [
56
+ yield(task, connections),
57
+ *options[:recursive] && task.is_a?(Activity::Interface) ? collect(task, options, &block) : []
58
+ ]
59
+ end.flatten(1)
60
+ end
61
+
62
+
63
+ def self.inspect_task_builder(task)
64
+ proc = task.instance_variable_get(:@user_proc)
65
+ match = proc.inspect.match(/(\w+)>$/)
66
+
67
+ %{#<TaskBuilder{.#{match[1]}}>}
68
+ end
69
+
70
+ # FIXME: clean up that shit below.
71
+
72
+ # render
73
+ def self.Cct(circuit, **options)
74
+ circuit_hash( circuit.to_h[:map], **options )
75
+ end
76
+
77
+ def self.circuit_hash(circuit_hash, show_ids:false, **options)
78
+ content =
79
+ circuit_hash.collect do |task, connections|
80
+ conns = connections.collect do |signal, target|
81
+ " {#{signal}} => #{inspect_with_matcher(target, **options)}"
82
+ end
83
+
84
+ [ inspect_with_matcher(task, **options), conns.join("\n") ]
85
+ end
86
+
87
+ content = content.join("\n")
88
+
89
+ return "\n#{content}" if show_ids
90
+ return "\n#{content}".gsub(/0x\w+/, "0x").gsub(/0.\d+/, "0.")
91
+ end
92
+
93
+ def self.Ends(activity)
94
+ end_events = activity.to_h[:end_events]
95
+ ends = end_events.collect { |evt| inspect_end(evt) }.join(",")
96
+ "[#{ends}]".gsub(/\d\d+/, "")
97
+ end
98
+
99
+
100
+ def self.Outputs(outputs)
101
+ outputs.collect { |semantic, output| "#{semantic}=> (#{output.signal}, #{output.semantic})" }.
102
+ join("\n").gsub(/0x\w+/, "").gsub(/\d\d+/, "")
103
+ end
104
+
105
+ # If Ruby had pattern matching, this function wasn't necessary.
106
+ def self.inspect_with_matcher(task, inspect_task: method(:inspect_task), inspect_end: method(:inspect_end))
107
+ return inspect_task.(task) unless task.kind_of?(Trailblazer::V2_1::Activity::End)
108
+ inspect_end.(task)
109
+ end
110
+
111
+ def self.inspect_task(task)
112
+ task.inspect
113
+ end
114
+
115
+ def self.inspect_end(task)
116
+ class_name = strip(task.class)
117
+ options = task.to_h
118
+
119
+ "#<#{class_name}/#{options[:semantic].inspect}>"
120
+ end
121
+
122
+ def self.strip(string)
123
+ string.to_s.sub("Trailblazer::V2_1::Activity::", "")
124
+ end
125
+ end #Introspect
126
+ end
127
+
128
+ module Activity::Magnetic
129
+ module Introspect
130
+ def self.seq(activity)
131
+ adds = activity.instance_variable_get(:@adds)
132
+ tripletts = Builder::Finalizer.adds_to_tripletts(adds)
133
+
134
+ Seq(tripletts)
135
+ end
136
+
137
+ def self.cct(builder)
138
+ adds = builder.instance_variable_get(:@adds)
139
+ circuit, _ = Builder::Finalizer.(adds)
140
+
141
+ Cct(circuit)
142
+ end
143
+
144
+ private
145
+
146
+ def self.Seq(sequence)
147
+ content =
148
+ sequence.collect do |(magnetic_to, task, plus_poles)|
149
+ pluses = plus_poles.collect { |plus_pole| PlusPole(plus_pole) }
150
+
151
+ %{#{magnetic_to.inspect} ==> #{Activity::Introspect.inspect_with_matcher(task)}
152
+ #{pluses.empty? ? " []" : pluses.join("\n")}}
153
+ end.join("\n")
154
+
155
+ "\n#{content}\n".gsub(/\d\d+/, "").gsub(/0x\w+/, "0x")
156
+ end
157
+
158
+ def self.PlusPole(plus_pole)
159
+ signal = plus_pole.signal.to_s.sub("Trailblazer::V2_1::Activity::", "")
160
+ semantic = plus_pole.send(:output).semantic
161
+ " (#{semantic})/#{signal} ==> #{plus_pole.color.inspect}"
162
+ end
163
+
164
+
165
+ end
166
+ end
167
+ end