lib/larynx/fields.rb in larynx-0.1.1 vs lib/larynx/fields.rb in larynx-0.1.2

- old
+ new

@@ -36,17 +36,59 @@ self.class.fields.index(field) end end + module CallbacksWithMode + + def setup(mode=:sync, &block) + block = app_scope(block) + callback = (mode == :async) ? lambda { EM.defer(block, lambda { send_next_command } ) } : block + super &callback + end + + def success(mode=:sync, &block) + block = app_scope(block) + callback = (mode == :async) ? lambda { EM.defer(block, lambda { send_next_command } ) } : block + super &callback + end + + def failure(mode=:sync, &block) + block = app_scope(block) + callback = (mode == :async) ? lambda { EM.defer(block, lambda { send_next_command } ) } : block + super &callback + end + + def validate(mode=:sync, &block) + block = app_scope(block) + if mode == :async + super &lambda { EM.defer(block, lambda {|result| evaluate_validity(result) } ) } + else + super &lambda { evaluate_validity(block.call) } + end + end + + def invalid(mode=:sync, &block) + block = app_scope(block) + if mode == :async + super &lambda { EM.defer(block, lambda {|result| invalid_input } ) } + else + super &lambda { block.call; invalid_input } + end + end + + end + class Field include Callbacks attr_reader :name define_callback :setup, :validate, :invalid, :success, :failure def initialize(name, options, &block) + class_eval { include CallbacksWithMode } + @name, @callbacks = name, {} @options = options.reverse_merge(:attempts => 3) @prompt_queue = [] instance_eval(&block) @@ -80,42 +122,50 @@ } end def execute_prompt call.execute current_prompt.command + send_next_command end def increment_attempts @attempt += 1 end - def fire_callback(callback) - if block = @callbacks[callback] - @app.instance_eval(&block) + def valid_length? + @value.size >= minimum_length + end + + def evaluate_input + if valid_length? + fire_callback(:validate) { evaluate_validity(true) } else - true + fire_callback(:invalid) { invalid_input } end end - def valid? - @value.size >= minimum_length && fire_callback(:validate) + def evaluate_validity(result) + if result + fire_callback(:success) { send_next_command } + else + fire_callback(:invalid) { invalid_input } + end end - def evaluate_input - if valid? - fire_callback(:success) + def invalid_input + if @attempt < @options[:attempts] + increment_attempts + execute_prompt else - fire_callback(:invalid) - if @attempt < @options[:attempts] - increment_attempts - execute_prompt - else - fire_callback(:failure) - end + fire_callback(:failure) { send_next_command } end end + def send_next_command + call.send_next_command if call.state == :ready + end + def set_instance_variables(input) @value = input @app.send("#{@name}=", input) end @@ -135,9 +185,23 @@ end def call @app.call end + + def app_scope(block) + lambda { @app.instance_eval(&block) } + end + + # fire callback with a default block if callback not defined + def fire_callback(callback, *args, &block) + if @callbacks && @callbacks[callback] + @callbacks[callback].call(*args) + else + yield if block_given? + end + end + end end end