Class: Glimmer::DSL::Engine

Inherits:
Object
  • Object
show all
Defined in:
lib/glimmer/dsl/engine.rb

Overview

Glimmer DSL Engine

Follows Interpreter and Chain of Responsibility Design Patterns

When DSL engine interprets an expression, it attempts to handle with ordered expression array specified via ‘.expressions=` method.

TODO support auto-loading static_expressions in the future for expressions where the keyword does not vary dynamically. These static keywords are then predefined as methods in Glimmer instead of needing method_missing

Class Method Summary collapse

Class Method Details

.add_content(parent, expression, &block) ⇒ Object

Adds content block to parent UI object

This allows evaluating parent UI object properties and children

For example, a shell widget would get properties set and children added



60
61
62
63
64
# File 'lib/glimmer/dsl/engine.rb', line 60

def add_content(parent, expression, &block)
  parent_stack.push(parent) if expression.is_a?(ParentExpression)
  expression.add_content(parent, &block) if block_given?
  parent_stack.pop if expression.is_a?(ParentExpression)
end

.current_parentObject

Current parent while evaluating Glimmer DSL (nil if just started or done evaluatiing)

Parents are maintained in a stack while evaluating Glimmer DSL to ensure properly ordered interpretation of DSL syntax



70
71
72
# File 'lib/glimmer/dsl/engine.rb', line 70

def current_parent
  parent_stack.last
end

.dynamic_expressions=(expression_names) ⇒ Object

Sets an ordered array of DSL expressions to support

Every expression has an underscored name corresponding to an upper camelcase AbstractExpression subclass name in glimmer/dsl

They are used in order following the Chain of Responsibility Design Pattern when interpretting a DSL expression

TODO rename to dynamic_expressions in the future when supporting static expressions



28
29
30
31
32
33
34
35
36
# File 'lib/glimmer/dsl/engine.rb', line 28

def dynamic_expressions=(expression_names)
  @dynamic_expression_chain_of_responsibility = expression_names.reverse.reduce(nil) do |last_expresion_handler, expression_name|
    Glimmer.logger&.debug "Loading #{expression_class_name(expression_name)}..."
    expression = expression_class(expression_name).new
    expression_handler = ExpressionHandler.new(expression)
    expression_handler.next = last_expresion_handler if last_expresion_handler
    expression_handler
  end
end

.expression_class(expression_name) ⇒ Object



38
39
40
# File 'lib/glimmer/dsl/engine.rb', line 38

def expression_class(expression_name)
  DSL.const_get(expression_class_name(expression_name).to_sym)
end

.expression_class_name(expression_name) ⇒ Object



42
43
44
# File 'lib/glimmer/dsl/engine.rb', line 42

def expression_class_name(expression_name)
  "#{expression_name}_expression".camelcase(:upper)
end

.interpret(keyword, *args, &block) ⇒ Object

Interprets Glimmer DSL keyword, args, and block (e.g. shell(:no_resize) { … })



47
48
49
50
51
52
53
# File 'lib/glimmer/dsl/engine.rb', line 47

def interpret(keyword, *args, &block)
  keyword = keyword.to_s
  expression = @dynamic_expression_chain_of_responsibility.handle(current_parent, keyword, *args, &block)
  expression.interpret(current_parent, keyword, *args, &block).tap do |ui_object|
    add_content(ui_object, expression, &block)
  end
end

.parent_stackObject



74
75
76
# File 'lib/glimmer/dsl/engine.rb', line 74

def parent_stack
  @parent_stack ||= []
end