Class: Jax::Shader

Inherits:
Sprockets::DirectiveProcessor
  • Object
show all
Defined in:
lib/jax/shader.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.default_mime_typeObject



5
6
7
# File 'lib/jax/shader.rb', line 5

def self.default_mime_type
  "application/javascript"
end

Instance Method Details

#evaluate(context, locals, &block) ⇒ Object



24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/jax/shader.rb', line 24

def evaluate(context, locals, &block)
  body = super
  body = process_exports(body)
  
  shader_name, shader_type = shader_type_and_name_for_path
  
  result = "Jax.shader_data(#{shader_name.inspect})[#{shader_type.inspect}] = #{body.inspect};\n"
  unless exports.empty?
    exports_var = "Jax.shader_data(#{shader_name.inspect})[\"exports\"]"
    exports_str   = "#{exports_var} = #{exports_var} || {};\n"
    exports.each do |name, type|
      exports_str+= "#{exports_var}[#{name.inspect}] = #{type.inspect};\n"
    end
    result.insert 0, exports_str
  end
  result
end

#exportsObject



9
10
11
# File 'lib/jax/shader.rb', line 9

def exports
  @exports ||= {}
end

#process_exports(body, rx = nil) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/jax/shader.rb', line 42

def process_exports(body, rx = nil)
  if rx
    body.scan(rx).uniq.each do |export|
      # scan gets us mostly there, but we still need the arguments.
      export =~ rx
      type  = $~[1]
      name  = $~[2]
      value = $~[3]
      exports[name] = type
      # we may use type later, when we start actively generating the export code.
      # Currently, that's done in JS.
    end
    body
  else
    process_exports_without_assignment(process_exports_with_assignment(body))
  end
end

#process_exports_with_assignment(body) ⇒ Object



64
65
66
# File 'lib/jax/shader.rb', line 64

def process_exports_with_assignment(body)
  process_exports body, /export\s*\(\s*([^\s]*),\s*([^\s]*),\s*([^\)]*)\);?/
end

#process_exports_without_assignment(body) ⇒ Object



60
61
62
# File 'lib/jax/shader.rb', line 60

def process_exports_without_assignment(body)
  process_exports body, /export\s*\(\s*([^\s]*),\s*([^\s]*)\s*\);?/
end

#process_require_directive(path) ⇒ Object



13
14
15
16
17
18
19
20
21
22
# File 'lib/jax/shader.rb', line 13

def process_require_directive(path)
  super

  # FIXME this is kind of a hacky solution to get function bodies included.
  # Should shaders be rewritten entirely, including the JS APIs?
  shader_name, shader_type = shader_type_and_name_for_path(path)
    
  str = "<%= Jax.import_shader_code(#{shader_name.inspect}, #{shader_type.inspect}) %>\n"
  body.insert 0, str unless body[str]
end

#shader_type_and_name_for_path(path = nil) ⇒ Object



68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/jax/shader.rb', line 68

def shader_type_and_name_for_path(path = nil)
  if path.nil?
    logical_path = context.logical_path
  else
    logical_path = context.environment.attributes_for(context.resolve path).logical_path
  end
  shader_name = File.basename(File.dirname(logical_path))
  shader_type = File.basename(logical_path)
  if (shader_type =~ /\.[^\.]+$/)
    shader_type = $`
  end
  
  [shader_name, shader_type]
end