Class: Vizcore::DSL::SceneBuilder

Inherits:
Object
  • Object
show all
Defined in:
lib/vizcore/dsl/scene_builder.rb

Overview

Collects layer definitions inside a single scene block.

Instance Method Summary collapse

Constructor Details

#initialize(name:, styles: {}, themes: {}, mapping_presets: {}, layers: [], strict: false) ⇒ SceneBuilder

Returns a new instance of SceneBuilder.

Parameters:

  • name (Symbol, String)

    scene identifier

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

    reusable layer parameter styles

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

    reusable scene-wide layer parameter themes

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

    reusable mapping presets

  • layers (Array<Hash>) (defaults to: [])

    initial layer definitions

  • strict (Boolean) (defaults to: false)

    true when unknown layer params should fail



18
19
20
21
22
23
24
25
26
27
# File 'lib/vizcore/dsl/scene_builder.rb', line 18

def initialize(name:, styles: {}, themes: {}, mapping_presets: {}, layers: [], strict: false)
  @name = name.to_sym
  @styles = styles
  @themes = themes
  @mapping_presets = mapping_presets
  @strict = !!strict
  @theme_name = nil
  @theme_params = {}
  @layers = layers.map { |layer| deep_dup(layer) }
end

Instance Method Details

#evaluate { ... } ⇒ Vizcore::DSL::SceneBuilder

Evaluate a scene block.

Yields:

  • Layer definitions

Returns:



33
34
35
36
# File 'lib/vizcore/dsl/scene_builder.rb', line 33

def evaluate(&block)
  instance_eval(&block) if block
  self
end

#group(name) { ... } ⇒ void

This method returns an undefined value.

Define a related group of layers with shared params.

Parameters:

  • name (Symbol, String)

    group identifier

Yields:

  • Layer group definition block



119
120
121
122
123
# File 'lib/vizcore/dsl/scene_builder.rb', line 119

def group(name, &block)
  builder = LayerGroupBuilder.new(name: name, styles: @styles, mapping_presets: @mapping_presets, defaults: @theme_params, strict: @strict)
  builder.evaluate(&block)
  @layers.concat(builder.to_a)
end

#layer(name) { ... } ⇒ void

This method returns an undefined value.

Define one layer in this scene.

Parameters:

  • name (Symbol, String)

    layer identifier

Yields:

  • Layer definition block



43
44
45
46
47
# File 'lib/vizcore/dsl/scene_builder.rb', line 43

def layer(name, &block)
  builder = LayerBuilder.new(name: name, styles: @styles, mapping_presets: @mapping_presets, defaults: @theme_params, strict: @strict)
  builder.evaluate(&block)
  @layers << builder.to_h
end

#override_layer(name, **params) { ... } ⇒ Hash

Override params on an existing layer without changing its type/shader.

Parameters:

  • name (Symbol, String)
  • params (Hash)

Yields:

  • optional style-like param block

Returns:

  • (Hash)

    updated layer definition

Raises:

  • (ArgumentError)


100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/vizcore/dsl/scene_builder.rb', line 100

def override_layer(name, **params, &block)
  index = layer_index!(name)
  overrides = params.each_with_object({}) { |(key, value), output| output[key.to_sym] = value }
  if block
    block_overrides = StyleBuilder.new(name: name, kind: "override_layer").evaluate(&block).to_h[:params]
    overrides.merge!(block_overrides)
  end
  raise ArgumentError, "override_layer #{name} requires at least one parameter" if overrides.empty?

  layer = deep_dup(@layers[index])
  layer[:params] = Hash(layer[:params] || {}).merge(overrides)
  @layers[index] = layer
end

#remove_layer(name) ⇒ Hash

Remove an inherited or previously declared layer by name.

Parameters:

  • name (Symbol, String)

Returns:

  • (Hash)

    removed layer definition



71
72
73
74
# File 'lib/vizcore/dsl/scene_builder.rb', line 71

def remove_layer(name)
  index = layer_index!(name)
  @layers.delete_at(index)
end

#replace_layer(name) { ... } ⇒ Hash

Replace an inherited or previously declared layer while preserving order.

Parameters:

  • name (Symbol, String)

Yields:

  • Layer definition block

Returns:

  • (Hash)

    replacement layer definition



81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/vizcore/dsl/scene_builder.rb', line 81

def replace_layer(name, &block)
  index = layer_index!(name)
  builder = LayerBuilder.new(
    name: name,
    styles: @styles,
    mapping_presets: @mapping_presets,
    defaults: @theme_params,
    strict: @strict
  )
  builder.evaluate(&block)
  @layers[index] = builder.to_h
end

#scene_defaults(**params) { ... } ⇒ Hash

Set defaults applied to every layer in this scene.

Parameters:

  • params (Hash)

    layer params

Yields:

  • optional defaults block using style-like setters

Returns:

  • (Hash)

Raises:

  • (ArgumentError)


54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/vizcore/dsl/scene_builder.rb', line 54

def scene_defaults(**params, &block)
  defaults = params.each_with_object({}) { |(key, value), output| output[key.to_sym] = value }
  if block
    block_defaults = StyleBuilder.new(name: :scene_defaults, kind: "scene_defaults").evaluate(&block).to_h[:params]
    defaults.merge!(block_defaults)
  end
  raise ArgumentError, "scene_defaults requires at least one parameter" if defaults.empty?

  @theme_params = deep_dup(@theme_params).merge(defaults)
  @layers = @layers.map { |layer| apply_theme_defaults(layer, defaults) }
  deep_dup(@theme_params)
end

#to_hHash

Returns serialized scene payload.

Returns:

  • (Hash)

    serialized scene payload



140
141
142
143
144
145
146
147
# File 'lib/vizcore/dsl/scene_builder.rb', line 140

def to_h
  scene = {
    name: @name,
    layers: @layers.map { |layer| deep_dup(layer) }
  }
  scene[:theme] = @theme_name if @theme_name
  scene
end

#use_theme(name) ⇒ Hash

Apply a named theme as default params for all layers in this scene.

Parameters:

  • name (Symbol, String)

    theme identifier

Returns:

  • (Hash)

    applied theme params

Raises:

  • (ArgumentError)

    when the theme is unknown



130
131
132
133
134
135
136
137
# File 'lib/vizcore/dsl/scene_builder.rb', line 130

def use_theme(name)
  theme_name = name.to_sym
  theme_params = @themes.fetch(theme_name) { raise ArgumentError, "unknown theme: #{theme_name}" }
  @theme_name = theme_name
  @theme_params = deep_dup(theme_params)
  @layers = @layers.map { |layer| apply_theme_defaults(layer, @theme_params) }
  deep_dup(@theme_params)
end