Class: InputSequencer

Inherits:
Object show all
Defined in:
lib/input_sequencer.rb

Overview

InputSequencer manages the sequence of menu interactions and block executions based on user input.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(document_filename, initial_blocks = nil) ⇒ InputSequencer

Returns a new instance of InputSequencer.



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/input_sequencer.rb', line 18

def initialize(document_filename, initial_blocks = nil)
  @document_filename = document_filename
  @current_block = nil
  @block_queue = initial_blocks
  @debug = Env.env_bool('INPUT_SEQUENCER_DEBUG', default: false)
# rubocop:disable Style/RescueStandardError
rescue
  pp $!, $@
  exit 1
  # rubocop:enable Style/RescueStandardError
end

Instance Attribute Details

#block_queueObject (readonly)

self.prepend InstanceMethodWrapper # traps initialize as well



16
17
18
# File 'lib/input_sequencer.rb', line 16

def block_queue
  @block_queue
end

#current_blockObject (readonly)

self.prepend InstanceMethodWrapper # traps initialize as well



16
17
18
# File 'lib/input_sequencer.rb', line 16

def current_block
  @current_block
end

#document_filenameObject (readonly)

self.prepend InstanceMethodWrapper # traps initialize as well



16
17
18
# File 'lib/input_sequencer.rb', line 16

def document_filename
  @document_filename
end

Class Method Details

Merges the current menu state with the next, prioritizing the next state’s values.



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/input_sequencer.rb', line 31

def self.merge_link_state(current, next_state)
  MarkdownExec::LinkState.new(
    block_name: next_state.block_name,
    display_menu: next_state.display_menu.nil? ? current.display_menu : next_state.display_menu,
    document_filename: next_state.document_filename || current.document_filename,
    inherited_block_names: next_state.inherited_block_names,
    inherited_dependencies: next_state.inherited_dependencies,
    inherited_lines: next_state.inherited_lines,
    prior_block_was_link: next_state.prior_block_was_link.nil? ? current.prior_block_was_link : next_state.prior_block_was_link
  )
# rubocop:disable Style/RescueStandardError
rescue
  pp $!, $@
  exit 1
  # rubocop:enable Style/RescueStandardError
end

Generates the next menu state based on provided attributes.



50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/input_sequencer.rb', line 50

def self.next_link_state(
  block_name: nil, display_menu: nil, document_filename: nil,
  inherited_lines: nil, keep_code: false, prior_block_was_link: false
)
  MarkdownExec::LinkState.new(
    block_name: block_name,
    display_menu: display_menu,
    document_filename: document_filename,
    inherited_lines: inherited_lines,
    keep_code: keep_code,
    prior_block_was_link: prior_block_was_link
  )
end

Instance Method Details

#bq_is_empty?Boolean

Returns:

  • (Boolean)


76
77
78
# File 'lib/input_sequencer.rb', line 76

def bq_is_empty?
  !@block_queue || @block_queue.empty?
end

#run(&block) ⇒ Object

Orchestrates the flow of menu states and user interactions.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/input_sequencer.rb', line 81

def run(&block)
  now_menu = InputSequencer.next_link_state(
    display_menu: bq_is_empty?,
    document_filename: @document_filename,
    prior_block_was_link: false # true bypass_exit when last block was a link (from cli)
  )
  exit_when_bq_empty = !bq_is_empty? # true when running blocks from cli; unless "stay" is used
  loop do
    break if run_yield(:parse_document, now_menu.document_filename,
                       &block) == :break

    # self.imw_ins now_menu, 'now_menu'

    break if exit_when_bq_empty && bq_is_empty? && !now_menu.prior_block_was_link

    if now_menu.display_menu
      # !!b
      break if run_yield(:end_of_cli, &block) == :exit
      # !!b

      exit_when_bq_empty = false
      run_yield :display_menu, &block
      # !!b

      choice = run_yield :user_choice, &block
      # !!b
      break if choice == :break
      # !!b

      raise BlockMissing, 'Block not recognized.' if choice.nil?
      # Exit loop and method to terminate the app
      break if run_yield(:exit?, choice&.to_s.downcase, &block)

      next_state = run_yield :execute_block, choice, &block
      # imw_ins next_state, 'next_state'
      break if next_state == :break

      next_menu = next_state
    else
      if now_menu.block_name && !now_menu.block_name.empty?
        block_name = now_menu.block_name
      else
        # break if bq_is_empty? # Exit loop if no more blocks to process
        if bq_is_empty? # Exit loop if no more blocks to process
          # !!b
          run_yield :end_of_cli, &block
          break
        end

        block_name = @block_queue.shift
      end
      # self.imw_ins block_name, 'block_name'

      next_menu = if block_name == '.'
                    exit_when_bq_empty = false
                    InputSequencer.next_link_state(display_menu: true)
                  else
                    state = run_yield :execute_block, block_name, &block
                    break if state == :break

                    state.display_menu = bq_is_empty?
                    state
                  end
      next_menu
      # imw_ins next_menu, 'next_menu'
    end
    now_menu = InputSequencer.merge_link_state(now_menu, next_menu)
  end

  # run_yield :end_of_cli, &block

  run_yield :close_ux, &block
end

#run_yield(sym, *args, &block) ⇒ Object

Orchestrates the flow of menu states and user interactions.



65
66
67
68
69
70
71
72
73
74
# File 'lib/input_sequencer.rb', line 65

def run_yield(sym, *args, &block)
  block.call sym, *args
rescue AppInterrupt
  raise
# rubocop:disable Style/RescueStandardError
rescue
  pp $!, $@
  exit 1
  # rubocop:enable Style/RescueStandardError
end