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.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.travis.yml +6 -0
- data/CHANGES.md +4 -0
- data/LICENSE.txt +9 -0
- data/README.md +48 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/gems.rb +3 -0
- data/lib/trailblazer/future.rb +9 -0
- data/lib/trailblazer/future/version.rb +5 -0
- data/lib/trailblazer/v2_1/activity.rb +123 -0
- data/lib/trailblazer/v2_1/activity/config.rb +37 -0
- data/lib/trailblazer/v2_1/activity/dsl/add_task.rb +22 -0
- data/lib/trailblazer/v2_1/activity/dsl/helper.rb +68 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic.rb +36 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder.rb +101 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/default_normalizer.rb +26 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/fast_track.rb +118 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/normalizer.rb +113 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/path.rb +105 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/railway.rb +97 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/builder/state.rb +58 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/finalizer.rb +51 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/generate.rb +62 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/merge.rb +16 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/process_options.rb +76 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/alterations.rb +44 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/plus_poles.rb +85 -0
- data/lib/trailblazer/v2_1/activity/dsl/magnetic/structure/polarization.rb +23 -0
- data/lib/trailblazer/v2_1/activity/dsl/record.rb +11 -0
- data/lib/trailblazer/v2_1/activity/dsl/schema/dependencies.rb +46 -0
- data/lib/trailblazer/v2_1/activity/dsl/schema/sequence.rb +46 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/build_state.rb +32 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/fast_track.rb +24 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/path.rb +26 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/plan.rb +36 -0
- data/lib/trailblazer/v2_1/activity/dsl/strategy/railway.rb +23 -0
- data/lib/trailblazer/v2_1/activity/interface.rb +16 -0
- data/lib/trailblazer/v2_1/activity/introspect.rb +167 -0
- data/lib/trailblazer/v2_1/activity/present.rb +95 -0
- data/lib/trailblazer/v2_1/activity/structures.rb +57 -0
- data/lib/trailblazer/v2_1/activity/task_builder.rb +41 -0
- data/lib/trailblazer/v2_1/activity/task_wrap.rb +40 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/call_task.rb +19 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/merge.rb +23 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/runner.rb +62 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/trace.rb +44 -0
- data/lib/trailblazer/v2_1/activity/task_wrap/variable_mapping.rb +162 -0
- data/lib/trailblazer/v2_1/activity/testing.rb +32 -0
- data/lib/trailblazer/v2_1/activity/trace.rb +97 -0
- data/lib/trailblazer/v2_1/circuit.rb +71 -0
- data/lib/trailblazer/v2_1/container_chain.rb +45 -0
- data/lib/trailblazer/v2_1/context.rb +79 -0
- data/lib/trailblazer/v2_1/deprecation/call.rb +46 -0
- data/lib/trailblazer/v2_1/deprecation/context.rb +43 -0
- data/lib/trailblazer/v2_1/dsl.rb +47 -0
- data/lib/trailblazer/v2_1/macro.rb +11 -0
- data/lib/trailblazer/v2_1/macro/contract.rb +5 -0
- data/lib/trailblazer/v2_1/operation.rb +91 -0
- data/lib/trailblazer/v2_1/operation/auto_inject.rb +47 -0
- data/lib/trailblazer/v2_1/operation/callable.rb +42 -0
- data/lib/trailblazer/v2_1/operation/class_dependencies.rb +25 -0
- data/lib/trailblazer/v2_1/operation/contract.rb +61 -0
- data/lib/trailblazer/v2_1/operation/deprecated_macro.rb +19 -0
- data/lib/trailblazer/v2_1/operation/deprecations.rb +21 -0
- data/lib/trailblazer/v2_1/operation/guard.rb +18 -0
- data/lib/trailblazer/v2_1/operation/heritage.rb +30 -0
- data/lib/trailblazer/v2_1/operation/inject.rb +36 -0
- data/lib/trailblazer/v2_1/operation/inspect.rb +79 -0
- data/lib/trailblazer/v2_1/operation/model.rb +50 -0
- data/lib/trailblazer/v2_1/operation/module.rb +29 -0
- data/lib/trailblazer/v2_1/operation/nested.rb +98 -0
- data/lib/trailblazer/v2_1/operation/persist.rb +14 -0
- data/lib/trailblazer/v2_1/operation/policy.rb +44 -0
- data/lib/trailblazer/v2_1/operation/public_call.rb +55 -0
- data/lib/trailblazer/v2_1/operation/pundit.rb +38 -0
- data/lib/trailblazer/v2_1/operation/railway.rb +32 -0
- data/lib/trailblazer/v2_1/operation/railway/fast_track.rb +13 -0
- data/lib/trailblazer/v2_1/operation/railway/macaroni.rb +23 -0
- data/lib/trailblazer/v2_1/operation/railway/normalizer.rb +58 -0
- data/lib/trailblazer/v2_1/operation/railway/task_builder.rb +37 -0
- data/lib/trailblazer/v2_1/operation/rescue.rb +42 -0
- data/lib/trailblazer/v2_1/operation/responder.rb +18 -0
- data/lib/trailblazer/v2_1/operation/result.rb +30 -0
- data/lib/trailblazer/v2_1/operation/test.rb +17 -0
- data/lib/trailblazer/v2_1/operation/trace.rb +46 -0
- data/lib/trailblazer/v2_1/operation/validate.rb +76 -0
- data/lib/trailblazer/v2_1/operation/wrap.rb +83 -0
- data/lib/trailblazer/v2_1/option.rb +78 -0
- data/lib/trailblazer/v2_1/rails.rb +12 -0
- data/lib/trailblazer/v2_1/rails/cell.rb +22 -0
- data/lib/trailblazer/v2_1/rails/controller.rb +66 -0
- data/lib/trailblazer/v2_1/rails/form.rb +21 -0
- data/lib/trailblazer/v2_1/rails/railtie.rb +31 -0
- data/lib/trailblazer/v2_1/rails/railtie/extend_application_controller.rb +28 -0
- data/lib/trailblazer/v2_1/rails/railtie/loader.rb +58 -0
- data/lib/trailblazer/v2_1/rails/test/integration.rb +6 -0
- data/lib/trailblazer/v2_1/versions.txt +7 -0
- data/test/rails5.0/.gitignore +17 -0
- data/test/rails5.0/Gemfile +21 -0
- data/test/rails5.0/Rakefile +3 -0
- data/test/rails5.0/app/concepts/artist/cell/dashboard.rb +7 -0
- data/test/rails5.0/app/concepts/artist/cell/show.rb +4 -0
- data/test/rails5.0/app/concepts/artist/view/dashboard.erb +4 -0
- data/test/rails5.0/app/concepts/artist/view/show.erb +1 -0
- data/test/rails5.0/app/concepts/params/operation/with_args.rb +5 -0
- data/test/rails5.0/app/concepts/song/contract/form.rb +6 -0
- data/test/rails5.0/app/concepts/song/operation/create.rb +15 -0
- data/test/rails5.0/app/concepts/song/operation/show.rb +3 -0
- data/test/rails5.0/app/concepts/song/operation/update.rb +15 -0
- data/test/rails5.0/app/controllers/application_controller.rb +46 -0
- data/test/rails5.0/app/controllers/args_controller.rb +5 -0
- data/test/rails5.0/app/controllers/artists_controller.rb +24 -0
- data/test/rails5.0/app/controllers/params_controller.rb +11 -0
- data/test/rails5.0/app/controllers/songs_controller.rb +35 -0
- data/test/rails5.0/app/models/artist.rb +2 -0
- data/test/rails5.0/app/models/song.rb +2 -0
- data/test/rails5.0/app/views/args/with_args.html.erb +1 -0
- data/test/rails5.0/app/views/layouts/application.html.erb +2 -0
- data/test/rails5.0/app/views/songs/edit.html.erb +4 -0
- data/test/rails5.0/app/views/songs/new.html.erb +5 -0
- data/test/rails5.0/app/views/songs/new_with_result.html.erb +3 -0
- data/test/rails5.0/app/views/songs/show.html.erb +3 -0
- data/test/rails5.0/bin/bundle +3 -0
- data/test/rails5.0/bin/rails +4 -0
- data/test/rails5.0/bin/rake +4 -0
- data/test/rails5.0/bin/setup +29 -0
- data/test/rails5.0/config.ru +4 -0
- data/test/rails5.0/config/application.rb +25 -0
- data/test/rails5.0/config/boot.rb +3 -0
- data/test/rails5.0/config/database.yml +21 -0
- data/test/rails5.0/config/environment.rb +5 -0
- data/test/rails5.0/config/environments/development.rb +41 -0
- data/test/rails5.0/config/environments/test.rb +42 -0
- data/test/rails5.0/config/initializers/assets.rb +11 -0
- data/test/rails5.0/config/initializers/backtrace_silencers.rb +7 -0
- data/test/rails5.0/config/initializers/cookies_serializer.rb +3 -0
- data/test/rails5.0/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/rails5.0/config/initializers/inflections.rb +16 -0
- data/test/rails5.0/config/initializers/mime_types.rb +4 -0
- data/test/rails5.0/config/initializers/session_store.rb +3 -0
- data/test/rails5.0/config/initializers/wrap_parameters.rb +14 -0
- data/test/rails5.0/config/locales/en.yml +23 -0
- data/test/rails5.0/config/routes.rb +15 -0
- data/test/rails5.0/config/secrets.yml +17 -0
- data/test/rails5.0/db/migrate/20161122145124_create_songs.rb +8 -0
- data/test/rails5.0/db/schema.rb +19 -0
- data/test/rails5.0/log/.keep +0 -0
- data/test/rails5.0/test/concepts/song/operation/create_test.rb +11 -0
- data/test/rails5.0/test/concepts/song/operation/update_test.rb +34 -0
- data/test/rails5.0/test/integration/.keep +0 -0
- data/test/rails5.0/test/integration/args_controller_test.rb +8 -0
- data/test/rails5.0/test/integration/artists_controller_test.rb +28 -0
- data/test/rails5.0/test/integration/params_controller_test.rb +8 -0
- data/test/rails5.0/test/integration/songs_controller_test.rb +40 -0
- data/test/rails5.0/test/test_helper.rb +7 -0
- data/test/test_helper.rb +5 -0
- data/trailblazer-future.gemspec +25 -0
- metadata +246 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
class Builder
|
|
4
|
+
class Railway < Builder
|
|
5
|
+
def self.for(normalizer, builder_options={}) # Build the Builder.
|
|
6
|
+
Activity::Magnetic::Builder(
|
|
7
|
+
Railway,
|
|
8
|
+
normalizer,
|
|
9
|
+
{ track_color: :success, end_semantic: :success, failure_color: :failure }.merge( builder_options )
|
|
10
|
+
)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Adds the End.failure end to the Path sequence.
|
|
14
|
+
# @return [Adds] list of Adds instances that can be chained or added to an existing sequence.
|
|
15
|
+
def self.InitialAdds(failure_color:raise, failure_end: Activity.End(failure_color), **builder_options)
|
|
16
|
+
path_adds = Path.InitialAdds(**builder_options)
|
|
17
|
+
|
|
18
|
+
end_adds = adds(
|
|
19
|
+
failure_end,
|
|
20
|
+
|
|
21
|
+
Path::EndEventPolarizations(builder_options),
|
|
22
|
+
|
|
23
|
+
{},
|
|
24
|
+
{ group: :end },
|
|
25
|
+
|
|
26
|
+
magnetic_to: [failure_color],
|
|
27
|
+
id: "End.#{failure_color}",
|
|
28
|
+
plus_poles: {},
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
path_adds + end_adds
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# ONLY JOB: magnetic_to and Outputs ("Polarization") via PlusPoles.merge
|
|
35
|
+
def self.StepPolarizations(**options)
|
|
36
|
+
[
|
|
37
|
+
*Path.TaskPolarizations(options),
|
|
38
|
+
StepPolarization.new(options)
|
|
39
|
+
]
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def self.PassPolarizations(options)
|
|
43
|
+
[
|
|
44
|
+
Railway::PassPolarization.new( options )
|
|
45
|
+
]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def self.FailPolarizations(options)
|
|
49
|
+
[
|
|
50
|
+
Railway::FailPolarization.new( options )
|
|
51
|
+
]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
class StepPolarization
|
|
55
|
+
def initialize(track_color: :success, failure_color: :failure, **o)
|
|
56
|
+
@track_color, @failure_color = track_color, failure_color
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# Returns the polarization for a DSL call. Takes care of user options such as :magnetic_to.
|
|
60
|
+
def call(magnetic_to, plus_poles, options)
|
|
61
|
+
[
|
|
62
|
+
magnetic_to || default_magnetic_to,
|
|
63
|
+
plus_poles_for(plus_poles, options),
|
|
64
|
+
]
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private
|
|
68
|
+
|
|
69
|
+
def plus_poles_for(plus_poles, options)
|
|
70
|
+
plus_poles.reconnect( :failure => @failure_color )
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def default_magnetic_to
|
|
74
|
+
[@track_color]
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
class PassPolarization < StepPolarization
|
|
79
|
+
def plus_poles_for(plus_poles, options)
|
|
80
|
+
plus_poles.reconnect( :failure => @track_color, :success => @track_color )
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
class FailPolarization < StepPolarization
|
|
85
|
+
def default_magnetic_to
|
|
86
|
+
[@failure_color]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def plus_poles_for(plus_poles, options)
|
|
90
|
+
plus_poles.reconnect( :failure => @failure_color, :success => @failure_color )
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
end # Railway
|
|
95
|
+
end # Builder
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
class Activity::Magnetic::Builder
|
|
3
|
+
# Maintain Builder instance plus Adds/Process/Outputs as immutable objects.
|
|
4
|
+
module State
|
|
5
|
+
def self.build(builder_class, normalizer, builder_options)
|
|
6
|
+
builder, adds = builder_class.for(normalizer, builder_options) # e.g. Path.for(...) which creates a Builder::Path instance.
|
|
7
|
+
|
|
8
|
+
recompile(builder.freeze, adds.freeze)
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def self.add(builder, adds, strategy, polarizer, *args, &block)
|
|
12
|
+
new_adds, *returned_options = builder.insert(strategy, polarizer, *args, &block) # TODO: move that out of here.
|
|
13
|
+
|
|
14
|
+
adds = adds + new_adds
|
|
15
|
+
|
|
16
|
+
recompile(builder, adds.freeze, returned_options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
# @return {builder, Adds, Process, outputs}, returned_options
|
|
22
|
+
def self.recompile(builder, adds, *args)
|
|
23
|
+
circuit, outputs = recompile_circuit(adds)
|
|
24
|
+
|
|
25
|
+
return builder, adds, circuit.freeze, outputs.freeze, *args
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def self.recompile_circuit(adds)
|
|
29
|
+
circuit, outputs = Recompile.( adds )
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
module Recompile
|
|
33
|
+
# Recompile the circuit and outputs from the {ADDS} instance that collects circuit tasks and connections.
|
|
34
|
+
#
|
|
35
|
+
# @return [Process, Hash] The {Process} instance and its outputs hash.
|
|
36
|
+
def self.call(adds)
|
|
37
|
+
circuit, end_events = Finalizer.(adds)
|
|
38
|
+
outputs = recompile_outputs(end_events)
|
|
39
|
+
|
|
40
|
+
return circuit, outputs
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
private
|
|
44
|
+
|
|
45
|
+
def self.recompile_outputs(end_events)
|
|
46
|
+
ary = end_events.collect do |evt|
|
|
47
|
+
[
|
|
48
|
+
semantic = evt.to_h[:semantic],
|
|
49
|
+
Activity::Output(evt, semantic)
|
|
50
|
+
]
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
::Hash[ ary ]
|
|
54
|
+
end
|
|
55
|
+
end # Recompile
|
|
56
|
+
end # State
|
|
57
|
+
end
|
|
58
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
class Builder
|
|
4
|
+
module Finalizer
|
|
5
|
+
|
|
6
|
+
def self.call(adds)
|
|
7
|
+
tripletts = adds_to_tripletts(adds)
|
|
8
|
+
|
|
9
|
+
circuit_hash = tripletts_to_circuit_hash( tripletts )
|
|
10
|
+
|
|
11
|
+
circuit_hash_to_process( circuit_hash )
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.adds_to_tripletts(adds)
|
|
15
|
+
alterations = adds_to_alterations(adds)
|
|
16
|
+
|
|
17
|
+
alterations.to_a
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.adds_to_alterations(adds)
|
|
21
|
+
alterations = DSL::Alterations.new
|
|
22
|
+
|
|
23
|
+
adds = adds.compact # TODO: test me explicitly, and where does this come from anyway?
|
|
24
|
+
|
|
25
|
+
adds.each { |method, cfg| alterations.send( method, *cfg ) }
|
|
26
|
+
|
|
27
|
+
alterations
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.tripletts_to_circuit_hash(tripletts)
|
|
31
|
+
Activity::Magnetic::Generate.( tripletts )
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.circuit_hash_to_process(circuit_hash)
|
|
35
|
+
end_events = end_events_for(circuit_hash)
|
|
36
|
+
|
|
37
|
+
return Circuit.new(circuit_hash, end_events, start_task: circuit_hash.keys.first), end_events
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Find all end events that don't have outgoing connections.
|
|
41
|
+
def self.end_events_for(circuit_hash)
|
|
42
|
+
ary = circuit_hash.collect do |task, connections|
|
|
43
|
+
task.kind_of?(Activity::End) && connections.empty? ? task : nil
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
ary.compact
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
# Transforms an array of {Triplett}s into a circuit hash.
|
|
4
|
+
module Generate
|
|
5
|
+
Line = Struct.new(:source, :output)
|
|
6
|
+
MinusPole = Struct.new(:color)
|
|
7
|
+
|
|
8
|
+
class OpenLines
|
|
9
|
+
def initialize
|
|
10
|
+
@arr = []
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def pop(signal, &block)
|
|
14
|
+
lines = @arr.find_all { |line| line.output.color == signal }
|
|
15
|
+
@arr -= lines
|
|
16
|
+
|
|
17
|
+
lines.each(&block)
|
|
18
|
+
lines.any?
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def <<((node, output))
|
|
22
|
+
@arr << Line.new(node, output)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.call(tasks)
|
|
27
|
+
open_plus_poles = OpenLines.new
|
|
28
|
+
open_minus_poles = OpenLines.new
|
|
29
|
+
circuit_hash = {}
|
|
30
|
+
|
|
31
|
+
tasks.each do |(magnetic_to, node, outputs)|
|
|
32
|
+
circuit_hash[ node ] ||= {} # DISCUSS: or needed?
|
|
33
|
+
|
|
34
|
+
magnetic_to.each do |edge_color| # minus poles
|
|
35
|
+
open_plus_poles.pop(edge_color) do |line|
|
|
36
|
+
connect( circuit_hash, line.source, line.output.signal, node )
|
|
37
|
+
end and next
|
|
38
|
+
|
|
39
|
+
# only run when there were no open_minus_poles
|
|
40
|
+
open_minus_poles << [node, MinusPole.new(edge_color)] # open inputs on a node, waiting to be connected.
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
outputs.each do |output|
|
|
44
|
+
open_minus_poles.pop(output.color) do |line|
|
|
45
|
+
connect( circuit_hash, node, output.signal, line.source )
|
|
46
|
+
end and next
|
|
47
|
+
|
|
48
|
+
# only run when there were no open_plus_poles
|
|
49
|
+
open_plus_poles << [node, output]
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
circuit_hash
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# plus minus
|
|
57
|
+
def self.connect(circuit_hash, source, signal, target)
|
|
58
|
+
circuit_hash[ source ][ signal ] = target
|
|
59
|
+
end
|
|
60
|
+
end # Magnetic
|
|
61
|
+
end
|
|
62
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
class Trailblazer::V2_1::Activity < Module
|
|
2
|
+
module Magnetic
|
|
3
|
+
module Merge
|
|
4
|
+
def merge!(merged)
|
|
5
|
+
merged[:record].each do |key, args|
|
|
6
|
+
dsl_method, *args = args
|
|
7
|
+
|
|
8
|
+
return send( dsl_method, args[0], args[1], &args[2] ) if args[2]
|
|
9
|
+
send( dsl_method, args[0], args[1] )
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
self
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
module DSL
|
|
4
|
+
# This module only processes additional "wiring" options from the DSL calls
|
|
5
|
+
# Output(:success) => End("my.new")
|
|
6
|
+
#
|
|
7
|
+
# Returns PlusPoles and additional sequence alterations.
|
|
8
|
+
module ProcessOptions
|
|
9
|
+
module_function
|
|
10
|
+
|
|
11
|
+
# Output => target (End/"id"/:color)
|
|
12
|
+
# @return [PlusPole]
|
|
13
|
+
# @return additional alterations
|
|
14
|
+
#
|
|
15
|
+
# options:
|
|
16
|
+
# { DSL::Output[::Semantic] => target }
|
|
17
|
+
#
|
|
18
|
+
def call(id, options, plus_poles, &block)
|
|
19
|
+
polarization, adds =
|
|
20
|
+
options.
|
|
21
|
+
collect { |key, task|
|
|
22
|
+
# this method call is the only thing that really matters here. # TODO: make this transformation a bit more obvious.
|
|
23
|
+
process_tuple(id, key, task, plus_poles, &block)
|
|
24
|
+
}.
|
|
25
|
+
inject([[],[]]) { |memo, (polarization, adds)| memo[0]<<polarization; memo[1]<<adds; memo }
|
|
26
|
+
|
|
27
|
+
return polarization, adds.flatten(1)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def process_tuple(id, output, task, plus_poles, &block)
|
|
31
|
+
output = output_for(output, plus_poles) if output.kind_of?(Activity::DSL::OutputSemantic)
|
|
32
|
+
|
|
33
|
+
if task.kind_of?(Activity::End)
|
|
34
|
+
# raise %{An end event with semantic `#{task.to_h[:semantic]}` has already been added. Please use an ID reference: `=> "End.#{task.to_h[:semantic]}"`} if
|
|
35
|
+
new_edge = "#{id}-#{output.signal}"
|
|
36
|
+
|
|
37
|
+
[
|
|
38
|
+
Polarization.new( output: output, color: new_edge ),
|
|
39
|
+
[ [:add, [task.to_h[:semantic], [ [new_edge], task, [] ], group: :end]] ]
|
|
40
|
+
]
|
|
41
|
+
# procs come from DSL calls such as `Path() do ... end`.
|
|
42
|
+
elsif task.is_a?(Proc)
|
|
43
|
+
start_color, activity = task.(block)
|
|
44
|
+
|
|
45
|
+
adds = activity.to_h[:adds]
|
|
46
|
+
|
|
47
|
+
[
|
|
48
|
+
Polarization.new( output: output, color: start_color ),
|
|
49
|
+
# TODO: this is a pseudo-"merge" and should be public API at some point.
|
|
50
|
+
# TODO: we also need to merge all the other states such as debug.
|
|
51
|
+
adds[1..-1] # drop start
|
|
52
|
+
]
|
|
53
|
+
elsif task.is_a?(Activity::DSL::Track) # An additional plus polarization. Example: Output => :success
|
|
54
|
+
[
|
|
55
|
+
Polarization.new( output: output, color: task.color )
|
|
56
|
+
]
|
|
57
|
+
else # ID: existing step
|
|
58
|
+
new_edge = "#{id}-#{output.signal}-#{task}" # edge from <id> to <target>
|
|
59
|
+
|
|
60
|
+
[
|
|
61
|
+
Polarization.new( output: output, color: new_edge ),
|
|
62
|
+
[[ :magnetic_to, [ task, [new_edge] ] ]], # mark target (`task`) as magnetic to the new edge.
|
|
63
|
+
]
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param semantic DSL::Output::Semantic
|
|
68
|
+
def output_for(semantic, plus_poles)
|
|
69
|
+
# DISCUSS: review PlusPoles#[]
|
|
70
|
+
output, _ = plus_poles.instance_variable_get(:@plus_poles)[semantic.value]
|
|
71
|
+
output or raise("Couldn't find existing output for `#{semantic.value.inspect}`.")
|
|
72
|
+
end
|
|
73
|
+
end # OptionsProcessing
|
|
74
|
+
end # DSL
|
|
75
|
+
end
|
|
76
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
module DSL
|
|
4
|
+
# works on a generic Dependencies structure that has no knowledge of magnetism.
|
|
5
|
+
class Alterations
|
|
6
|
+
def initialize
|
|
7
|
+
@groups = Activity::Schema::Dependencies.new
|
|
8
|
+
@future_magnetic_to = {} # DISCUSS: future - should it be here?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def add(id, options, **sequence_options)
|
|
12
|
+
@groups.add(id, options, **sequence_options)
|
|
13
|
+
|
|
14
|
+
# DISCUSS: future - should it be here?
|
|
15
|
+
if magnetic_to = @future_magnetic_to.delete(id)
|
|
16
|
+
magnetic_to( id, magnetic_to )
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# make `id` magnetic_to
|
|
23
|
+
def magnetic_to(id, magnetic_to)
|
|
24
|
+
group, index = @groups.find(id) # this can be a future task!
|
|
25
|
+
|
|
26
|
+
unless group # DISCUSS: future - should it be here?
|
|
27
|
+
@future_magnetic_to[id] = magnetic_to
|
|
28
|
+
return
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
arr = group[index].configuration.dup
|
|
32
|
+
|
|
33
|
+
arr[0] = arr[0] + magnetic_to
|
|
34
|
+
group.add(id, arr, replace: id)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Returns array of tripletts.
|
|
38
|
+
def to_a
|
|
39
|
+
@groups.to_a
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end # DSL
|
|
43
|
+
end
|
|
44
|
+
end
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
module Trailblazer::V2_1
|
|
2
|
+
module Activity::Magnetic
|
|
3
|
+
# A plus pole is associating an Output{:signal, :semantic} to a magnetic :color.
|
|
4
|
+
#
|
|
5
|
+
# When it comes to connecting tasks to each other, PlusPoles is the most important object
|
|
6
|
+
# here. When a task is added via the DSL, a PlusPoles is set up, and the DSL adds polarizations
|
|
7
|
+
# from the implementation and from the options (e.g. `Outputs(..) => ..`).
|
|
8
|
+
#
|
|
9
|
+
# These are then finalized and return the effective plus poles
|
|
10
|
+
|
|
11
|
+
# Polarization is one or multiple calls to PlusPoles
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
# Output(:signal, :semantic) => :color
|
|
18
|
+
# add / merge
|
|
19
|
+
# change existing, => color
|
|
20
|
+
#
|
|
21
|
+
#
|
|
22
|
+
# Produces [ PlusPole, PlusPole, ] via `to_a`.
|
|
23
|
+
#
|
|
24
|
+
# @privat
|
|
25
|
+
# @note This is private until we know what we want.
|
|
26
|
+
class PlusPoles
|
|
27
|
+
def initialize(plus_poles={})
|
|
28
|
+
@plus_poles = plus_poles.freeze
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# merge( Activity::Magnetic.Output(Right, :success) => :success
|
|
32
|
+
def merge(output_to_color)
|
|
33
|
+
overrides = ::Hash[ output_to_color.collect { |output, color| [ output.semantic, [output, color] ] } ]
|
|
34
|
+
PlusPoles.new(@plus_poles.merge(overrides))
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def reverse_merge(output_to_color)
|
|
38
|
+
existing_colors = @plus_poles.values.collect { |pole_cfg| pole_cfg.last }
|
|
39
|
+
|
|
40
|
+
# filter all outputs with a color that already exists.
|
|
41
|
+
overrides = output_to_color.find_all { |output, color| !existing_colors.include?(color) }
|
|
42
|
+
merge(overrides)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def reconnect(semantic_to_color)
|
|
46
|
+
ary = semantic_to_color.collect do |semantic, color|
|
|
47
|
+
existing_output, _ = @plus_poles[semantic]
|
|
48
|
+
|
|
49
|
+
next unless existing_output
|
|
50
|
+
|
|
51
|
+
[ Activity.Output(existing_output.signal, existing_output.semantic), color ]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
merge( ::Hash[ary.compact] )
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Compile one {PlusPoles} instance from all a sequence of {Polarization}s.
|
|
58
|
+
# This is usually called once per `step` DSL call.
|
|
59
|
+
#
|
|
60
|
+
# @api private
|
|
61
|
+
def self.apply_polarizations(polarizations, magnetic_to, plus_poles, options)
|
|
62
|
+
magnetic_to, plus_poles = polarizations.inject([magnetic_to, plus_poles]) do |args, pol|
|
|
63
|
+
magnetic_to, plus_poles = pol.(*args, options)
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
return magnetic_to, plus_poles.to_a
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# The DSL is a series of transformations that yield in tasks with several PlusPole instances each.
|
|
70
|
+
#
|
|
71
|
+
# @api private
|
|
72
|
+
def to_a
|
|
73
|
+
@plus_poles.values.collect { |output, color| PlusPole.new(output, color) }
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# FIXME: should this be a hash or whatever?
|
|
77
|
+
#
|
|
78
|
+
# @return Hash All {Output}s mapped to their (guessed) semantic: `{ Output(Right, :success) => :success }`
|
|
79
|
+
def self.initial(outputs)
|
|
80
|
+
new.merge(Hash[ outputs.collect { |semantic, output| [output, semantic] } ])
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|