Class: Qcmd::BaseAction

Inherits:
Object
  • Object
show all
Defined in:
lib/qcmd/actions/base_action.rb

Direct Known Subclasses

Action, CueAction

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(expression) ⇒ BaseAction

Returns a new instance of BaseAction.



23
24
25
26
27
28
29
# File 'lib/qcmd/actions/base_action.rb', line 23

def initialize(expression)
  if expression.is_a?(String)
    expression = Qcmd::Parser.parse(expression)
  end

  parse(expression)
end

Instance Attribute Details

#codeObject (readonly)

Returns the value of attribute code.



3
4
5
# File 'lib/qcmd/actions/base_action.rb', line 3

def code
  @code
end

#modificationObject

Returns the value of attribute modification.



4
5
6
# File 'lib/qcmd/actions/base_action.rb', line 4

def modification
  @modification
end

Class Method Details

.evaluate(action_input) ⇒ Object

initialize and evaluate in one shot



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/qcmd/actions/base_action.rb', line 7

def self.evaluate action_input
  is_cue_action = false

  if action_input.is_a?(String)
    is_cue_action = %w(cue cue_id).include?(action_input.split.first)
  else
    is_cue_action = ['cue', 'cue_id', :cue, :cue_id].include?(action_input.first)
  end

  if is_cue_action
    CueAction.new(action_input).evaluate
  else
    Action.new(action_input).evaluate
  end
end

Instance Method Details

#commandObject

the raw command



125
126
127
# File 'lib/qcmd/actions/base_action.rb', line 125

def command
  code[0]
end

#evaluateObject



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
# File 'lib/qcmd/actions/base_action.rb', line 31

def evaluate
  if code.size == 0
    nil
  else
    @code = code.map do |token|
      if token.is_a?(BaseAction)
        Qcmd.debug "[Action evaluate] evaluating nested action: #{ token.code.inspect }"
        token.evaluate
      else
        token
      end
    end

    Qcmd.debug "[Action evaluate] evaluating code: #{ code.inspect }"

    response = send_message
    if modification
      modification.call(response)
    else
      response
    end
  end
end

#osc_addressObject



107
108
109
110
111
112
113
114
# File 'lib/qcmd/actions/base_action.rb', line 107

def osc_address
  # prefix w/ slash if necessary
  if %r[^/] !~ code[0].to_s
    "/#{ code[0] }"
  else
    code[0]
  end
end

#osc_address=(value) ⇒ Object



116
117
118
# File 'lib/qcmd/actions/base_action.rb', line 116

def osc_address=(value)
  code[0] = value
end

#osc_argumentsObject



120
121
122
# File 'lib/qcmd/actions/base_action.rb', line 120

def osc_arguments
  stringify code[1..-1]
end

#osc_messageObject

the default command builder



103
104
105
# File 'lib/qcmd/actions/base_action.rb', line 103

def osc_message
  OSC::Message.new osc_address.to_s, *osc_arguments
end

#parse(expression) ⇒ Object

convert nested arrays into new actions



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
# File 'lib/qcmd/actions/base_action.rb', line 56

def parse(expression)
  if expression.size == 1 && expression[0].is_a?(Array)
    expression = expression[0]
  end

  @code = expression.map do |token|
    if token.is_a?(Array)
      if [:cue, :cue_id].include?(token.first)
        Qcmd.debug "nested cue action detected in #{ expression.inspect }"
        CueAction.new(token)
      else
        Action.new(token)
      end
    else
      token
    end
  end.tap {|exp|
    Qcmd.debug "[Action parse] returning: #{ exp.inspect }"
  }

  # if there's a trailing modifier command, replace it with an action that will
  # return a value that can be modified.
  if tm = trailing_modifier
    Qcmd.debug "[Action parse] found trailing modifier: #{ tm.inspect }"

    mod_type = tm[0]
    mod_value = tm[2].to_f

    # clone this action without the final arg
    new_action = self.class.new(@code[0, @code.size - 1])

    Qcmd.debug "[Action parse] creating modification proc: value.send(:#{ mod_type }, #{ mod_value })"
    new_action.modification = Proc.new {|value|
      Qcmd.debug "[Action parse] executing modification proc: #{ value }.send(:#{ mod_type }, #{ mod_value })"
      if value.respond_to?(mod_type)
        value.send mod_type, mod_value
      else
        Qcmd.log :warning, "The command `#{ new_action.code.join(' ') }` returned a value of type #{ value.class.to_s } which does not understand the #{ mod_type } modifier."
        value
      end
    }

    code[code.size - 1] = new_action
  end
end