Class: LPS

Inherits:
Object
  • Object
show all
Includes:
OptionInitializer
Defined in:
lib/lps.rb,
lib/lps/version.rb

Constant Summary collapse

VERSION =
'0.2.1'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(opts = {}) ⇒ LPS

Returns a new instance of LPS.

Parameters:

  • opts (Hash) (defaults to: {})

    Options Hash.

Options Hash (opts):

  • :freq (Numeric)

    Frequency of loop execution (loops/sec)

  • :cond (#call)

    Loop condition

Raises:

  • (ArgumentError)


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/lps.rb', line 81

def initialize opts = {}
  validate_options opts

  freq, intv, @while = opts.values_at :freq, :interval, :while
  raise ArgumentError,
    "can't have both frequency and interval" if freq && intv

  @freq =
    if freq
      freq
    elsif intv
      (intv == 0) ? nil : 1.0 / intv
    else
      nil
    end
  @interval = @freq ? 1.0 / @freq : 0
end

Instance Attribute Details

#freqNumber

Returns Loop frequency.

Returns:

  • (Number)

    Loop frequency



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
# File 'lib/lps.rb', line 8

class LPS
  include OptionInitializer
  option_initializer! :freq, :interval => Numeric, :while => :&
  option_validator :freq do |v|
    msg = 'frequency must be a positive number (or nil)'
    raise TypeError, msg unless v.is_a?(Numeric) || v.nil?
    raise ArgumentError, msg if v.is_a?(Numeric) && v <= 0
  end
  option_validator :interval do |v|
    raise ArgumentError, 'interval must be a non-negative number' if v < 0
  end

  attr_reader :freq, :interval

  # Main loop
  # @param [Proc] block Loop
  def loop &block
    ret = nil
    always = @while.nil?

    if @freq.nil?
      while always || @while.call
        ret = block.call self

        # Frequency set!
        return loop(&block) if @freq
      end
    else
      nt = Time.now
      while always || @while.call
        ret = block.call self

        # Frequency unset!
        return loop(&block) unless @freq

        nt   += @interval
        now   = Time.now
        diff  = nt - now

        if diff > 0.01
          sleep diff
        elsif diff < 0
          nt = now
        end
      end
    end
    ret
  end

  # Changes loop frequency
  # @param [Number|nil] f Loop frequency
  # @return [Number|nil]
  def freq= f
    validate_options(:freq => f)

    @freq, @interval = [f, f ? 1.0 / f : 0]
    @freq
  end

  # Changes loop interval
  # @param [Number] intv Loop interval
  # @return [Number]
  def interval= intv
    validate_options(:interval => intv)

    @freq, @interval = [(intv == 0) ? nil : 1.0 / intv, intv]
    @interval
  end

  # @param [Hash] opts Options Hash.
  # @option opts [Numeric] :freq Frequency of loop execution (loops/sec)
  # @option opts [#call] :cond Loop condition
  # @private
  def initialize opts = {}
    validate_options opts

    freq, intv, @while = opts.values_at :freq, :interval, :while
    raise ArgumentError,
      "can't have both frequency and interval" if freq && intv

    @freq =
      if freq
        freq
      elsif intv
        (intv == 0) ? nil : 1.0 / intv
      else
        nil
      end
    @interval = @freq ? 1.0 / @freq : 0
  end
end

#intervalNumber

Returns Loop interval (inverse of frequency).

Returns:

  • (Number)

    Loop interval (inverse of frequency)



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
# File 'lib/lps.rb', line 8

class LPS
  include OptionInitializer
  option_initializer! :freq, :interval => Numeric, :while => :&
  option_validator :freq do |v|
    msg = 'frequency must be a positive number (or nil)'
    raise TypeError, msg unless v.is_a?(Numeric) || v.nil?
    raise ArgumentError, msg if v.is_a?(Numeric) && v <= 0
  end
  option_validator :interval do |v|
    raise ArgumentError, 'interval must be a non-negative number' if v < 0
  end

  attr_reader :freq, :interval

  # Main loop
  # @param [Proc] block Loop
  def loop &block
    ret = nil
    always = @while.nil?

    if @freq.nil?
      while always || @while.call
        ret = block.call self

        # Frequency set!
        return loop(&block) if @freq
      end
    else
      nt = Time.now
      while always || @while.call
        ret = block.call self

        # Frequency unset!
        return loop(&block) unless @freq

        nt   += @interval
        now   = Time.now
        diff  = nt - now

        if diff > 0.01
          sleep diff
        elsif diff < 0
          nt = now
        end
      end
    end
    ret
  end

  # Changes loop frequency
  # @param [Number|nil] f Loop frequency
  # @return [Number|nil]
  def freq= f
    validate_options(:freq => f)

    @freq, @interval = [f, f ? 1.0 / f : 0]
    @freq
  end

  # Changes loop interval
  # @param [Number] intv Loop interval
  # @return [Number]
  def interval= intv
    validate_options(:interval => intv)

    @freq, @interval = [(intv == 0) ? nil : 1.0 / intv, intv]
    @interval
  end

  # @param [Hash] opts Options Hash.
  # @option opts [Numeric] :freq Frequency of loop execution (loops/sec)
  # @option opts [#call] :cond Loop condition
  # @private
  def initialize opts = {}
    validate_options opts

    freq, intv, @while = opts.values_at :freq, :interval, :while
    raise ArgumentError,
      "can't have both frequency and interval" if freq && intv

    @freq =
      if freq
        freq
      elsif intv
        (intv == 0) ? nil : 1.0 / intv
      else
        nil
      end
    @interval = @freq ? 1.0 / @freq : 0
  end
end

Instance Method Details

#loop(&block) ⇒ Object

Main loop

Parameters:

  • block (Proc)

    Loop



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
# File 'lib/lps.rb', line 24

def loop &block
  ret = nil
  always = @while.nil?

  if @freq.nil?
    while always || @while.call
      ret = block.call self

      # Frequency set!
      return loop(&block) if @freq
    end
  else
    nt = Time.now
    while always || @while.call
      ret = block.call self

      # Frequency unset!
      return loop(&block) unless @freq

      nt   += @interval
      now   = Time.now
      diff  = nt - now

      if diff > 0.01
        sleep diff
      elsif diff < 0
        nt = now
      end
    end
  end
  ret
end