Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: dfb518c46f
Fetching contributors…

Cannot retrieve contributors at this time

file 109 lines (92 sloc) 2.295 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 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
include 'ruby-plc/sequences/step_listeners'
include 'ruby-plc/timedomain/wait_step'
include 'ruby-plc/timedomain/timer'
include 'ruby-plc/timedomain/sequencer'

mmodule RubyPlc
  module Sequences
    class Sequence
      include StepListeners

      attr_reader :name

      def initialize(name = nil, options = {})
        init_step_listeners
        @name = name
        @steps = []
        @current_step_index = nil # index of current step
        @options = options
        yield self if block_given?
        if @options[:auto_start]
          Sequencer::at_once { start }
        end
        if @options[:cyclic]
          on_exit do
            Sequencer::at_once { start }
          end
        end

      end

      def step(s)
        if s.respond_to? :to_step
          add_step s.to_step
        else
          add_step s
        end
        s
      end

      def wait(time)
        step WaitStep.new time
      end

      def circular(delay = 100)
        Timer t = Timer.new delay
        on_exit do
          t.start
          t.at_end do
            start
          end
        end
      end


      def finished?
        current_step
      end

      def active?
        not finished
      end
      
      def start
        if not current_step || @steps.any?
          notify_enter
          @current_step_index = 0
        end
      end

      def current_step
        @current_step_index && @steps[@current_step_index]
      end

      def reset(mode = :all)
        @steps.each {|s| s.reset(mode) } if mode == :all
        @steps[0..@current_step_index].each {|s| s.reset(mode) } if (mode == :used && @current_step_index)
        @current_step_index = nil
        notify_reset
      end

      private

      def add_step(s)
        if @options[:reverse]
          @steps.unshift s
        else
          @steps << s
        end

        step.on_exit do
          Sequencer::at_once do
            current_step_finished
          end
        end
      end

      def current_step_finished
        if @current_step_index
          @current_step_index += 1
          if @current_step_index >= @steps.size
            @current_step_index = nil
            notify_exit
          end
          current_step.start if current_step
        end
      end
    end
  end
end
Something went wrong with that request. Please try again.