class_docstr: Representation of a GLSL function
  
  Objects of this class can be used for re-using and composing GLSL
  snippets. Each Function consists of a GLSL snippet in the form of
  a function. The code may have template variables that start with
  the dollar sign. These stubs can be replaced with expressions using
  the index operation. Expressions can be:
  
  * plain text that is inserted verbatim in the code
  * a Function object or a call to a funcion
  * a Variable (or Varying) object
  * float, int, tuple are automatically turned into a uniform Variable
  * a VertexBuffer is automatically turned into an attribute Variable
  
  All functions have implicit "$pre" and "$post" placeholders that may be
  used to insert code at the beginning and end of the function.
  
  Examples
  --------
  This example shows the basic usage of the Function class::
  
      vert_code_template = Function('''
          void main() {
          gl_Position = $pos;
          gl_Position.x += $xoffset;
          gl_Position.y += $yoffset;
      }''')
  
      scale_transform = Function('''
      vec4 transform_scale(vec4 pos){
          return pos * $scale;
      }''')
  
      # If you get the function from a snippet collection, always
      # create new Function objects to ensure they are 'fresh'.
      vert_code = Function(vert_code_template)
      trans1 = Function(scale_transform)
      trans2 = Function(scale_transform)  # trans2 != trans1
  
      # Three ways to assign to template variables:
      #
      # 1) Assign verbatim code
      vert_code['xoffset'] = '(3.0 / 3.1415)'
  
      # 2) Assign a value (this creates a new uniform or attribute)
      vert_code['yoffset'] = 5.0
  
      # 3) Assign a function call expression
      pos_var = Variable('attribute vec4 a_position')
      vert_code['pos'] = trans1(trans2(pos_var))
  
      # Transforms also need their variables set
      trans1['scale'] = 0.5
      trans2['scale'] = (1.0, 0.5, 1.0, 1.0)
  
      # You can actually change any code you want, but use this with care!
      vert_code.replace('gl_Position.y', 'gl_Position.z')
  
      # Finally, you can set special variables explicitly. This generates
      # a new statement at the end of the vert_code function.
      vert_code['gl_PointSize'] = '10.'
  
  
  If we use ``vert_code.compile()`` we get::
  
      attribute vec4 a_position;
      uniform float u_yoffset;
      uniform float u_scale_1;
      uniform vec4 u_scale_2;
      uniform float u_pointsize;
  
      vec4 transform_scale_1(vec4 pos){
          return pos * u_scale_1;
      }
  
      vec4 transform_scale_2(vec4 pos){
          return pos * u_scale_2;
      }
  
      void main() {
          gl_Position = transform_scale_1(transform_scale_2(a_position));
          gl_Position.x += (3.0 / 3.1415);
          gl_Position.z += u_yoffset;
  
          gl_PointSize = u_pointsize;
      }
  
  Note how the two scale function resulted in two different functions
  and two uniforms for the scale factors.
  
  Notes
  -----
  
  Function calls:
  
  As can be seen above, the arguments with which a function is to be
  called must be specified by calling the Function object. The
  arguments can be any of the expressions mentioned earlier. If the
  signature is already specified in the template code, that function
  itself must be given.
  
  ::
  
      code = Function('''
          void main() {
              vec4 position = $pos;
              gl_Position = $scale(position)
          }
      ''')
  
      # Example of a function call with all possible three expressions
      vert_code['pos'] = func1('3.0', 'uniform float u_param', func2())
  
      # For scale, the sigfnature is already specified
      code['scale'] = scale_func  # Must not specify args
  
  Data for uniform and attribute variables:
  
  To each variable a value can be associated. In fact, in most cases
  the Function class is smart enough to be able to create a Variable
  object if only the data is given.
  
  ::
  
      code['offset'] = Variable('uniform float offset')  # No data
      code['offset'] = Variable('uniform float offset', 3.0)  # With data
      code['offset'] = 3.0  # -> Uniform Variable
      position['position'] = VertexBuffer()  # -> attribute Variable
  
      # Updating variables
      code['offset'].value = 4.0
      position['position'].value.set_data(...)
class_docstr_tok: ["Representation","of","a","GLSL","function","Objects","of","this","class","can","be","used","for","re-using","and","composing","GLSL","snippets",".","Each","Function","consists","of","a","GLSL","snippet","in","the","form","of","a","function",".","The","code","may","have","template","variables","that","start","with","the","dollar","sign",".","These","stubs","can","be","replaced","with","expressions","using","the","index","operation",".","Expressions","can","be",":","*","plain","text","that","is","inserted","verbatim","in","the","code","*","a","Function","object","or","a","call","to","a","funcion","*","a","Variable","(","or","Varying",")","object","*","float",",","int",",","tuple","are","automatically","turned","into","a","uniform","Variable","*","a","VertexBuffer","is","automatically","turned","into","an","attribute","Variable","All","functions","have","implicit","``","$","pre","''","and","``","$","post","''","placeholders","that","may","be","used","to","insert","code","at","the","beginning","and","end","of","the","function",".","Examples","--","--","--","--","This","example","shows","the","basic","usage","of","the","Function","class",":",":","vert_code_template","=","Function","(","``","'","void","main","(",")","{","gl_Position","=","$","pos",";","gl_Position.x","+=","$","xoffset",";","gl_Position.y","+=","$","yoffset",";","}","''","'",")","scale_transform","=","Function","(","``","'","vec4","transform_scale","(","vec4","pos",")","{","return","pos","*","$","scale",";","}","''","'",")","#","If","you","get","the","function","from","a","snippet","collection",",","always","#","create","new","Function","objects","to","ensure","they","are","'fresh","'",".","vert_code","=","Function","(","vert_code_template",")","trans1","=","Function","(","scale_transform",")","trans2","=","Function","(","scale_transform",")","#","trans2","!","=","trans1","#","Three","ways","to","assign","to","template","variables",":","#","#","1",")","Assign","verbatim","code","vert_code","[","'xoffset","'","]","=","'","(","3.0","\/","3.1415",")","'","#","2",")","Assign","a","value","(","this","creates","a","new","uniform","or","attribute",")","vert_code","[","'yoffset","'","]","=","5.0","#","3",")","Assign","a","function","call","expression","pos_var","=","Variable","(","'attribute","vec4","a_position","'",")","vert_code","[","'pos","'","]","=","trans1","(","trans2","(","pos_var",")",")","#","Transforms","also","need","their","variables","set","trans1","[","'scale","'","]","=","0.5","trans2","[","'scale","'","]","=","(","1.0",",","0.5",",","1.0",",","1.0",")","#","You","can","actually","change","any","code","you","want",",","but","use","this","with","care","!","vert_code.replace","(","'gl_Position.y","'",",","'gl_Position.z","'",")","#","Finally",",","you","can","set","special","variables","explicitly",".","This","generates","#","a","new","statement","at","the","end","of","the","vert_code","function",".","vert_code","[","'gl_PointSize","'","]","=","'10",".","'","If","we","use","``","vert_code.compile","(",")","``","we","get",":",":","attribute","vec4","a_position",";","uniform","float","u_yoffset",";","uniform","float","u_scale_1",";","uniform","vec4","u_scale_2",";","uniform","float","u_pointsize",";","vec4","transform_scale_1","(","vec4","pos",")","{","return","pos","*","u_scale_1",";","}","vec4","transform_scale_2","(","vec4","pos",")","{","return","pos","*","u_scale_2",";","}","void","main","(",")","{","gl_Position","=","transform_scale_1","(","transform_scale_2","(","a_position",")",")",";","gl_Position.x","+=","(","3.0","\/","3.1415",")",";","gl_Position.z","+=","u_yoffset",";","gl_PointSize","=","u_pointsize",";","}","Note","how","the","two","scale","function","resulted","in","two","different","functions","and","two","uniforms","for","the","scale","factors",".","Notes","--","--","-","Function","calls",":","As","can","be","seen","above",",","the","arguments","with","which","a","function","is","to","be","called","must","be","specified","by","calling","the","Function","object",".","The","arguments","can","be","any","of","the","expressions","mentioned","earlier",".","If","the","signature","is","already","specified","in","the","template","code",",","that","function","itself","must","be","given",".",":",":","code","=","Function","(","``","'","void","main","(",")","{","vec4","position","=","$","pos",";","gl_Position","=","$","scale","(","position",")","}","``","'",")","#","Example","of","a","function","call","with","all","possible","three","expressions","vert_code","[","'pos","'","]","=","func1","(","'","3.0","'",",","'uniform","float","u_param","'",",","func2","(",")",")","#","For","scale",",","the","sigfnature","is","already","specified","code","[","'scale","'","]","=","scale_func","#","Must","not","specify","args","Data","for","uniform","and","attribute","variables",":","To","each","variable","a","value","can","be","associated",".","In","fact",",","in","most","cases","the","Function","class","is","smart","enough","to","be","able","to","create","a","Variable","object","if","only","the","data","is","given",".",":",":","code","[","'offset","'","]","=","Variable","(","'uniform","float","offset","'",")","#","No","data","code","[","'offset","'","]","=","Variable","(","'uniform","float","offset","'",",","3.0",")","#","With","data","code","[","'offset","'","]","=","3.0","#","-",">","Uniform","Variable","position","[","'position","'","]","=","VertexBuffer","(",")","#","-",">","attribute","Variable","#","Updating","variables","code","[","'offset","'","]",".value","=","4.0","position","[","'position","'","]",".value.set_data","(","...",")"]
docstr: Find all template variables in self._code, excluding the function name.
docstr_tok: ["Find","all","template","variables","in","self._code",",","excluding","the","function","name","."]
code: def _parse_template_vars(self):
      """Find all template variables in self._code, excluding the function name."""
      template_vars = set()
      for var in parsing.find_template_variables(self._code):
          var = var.lstrip("$")
          if var == self.name:
              continue
          if var in ("pre", "post"):
              raise ValueError(
                  "GLSL uses reserved template variable $%s" % var
              )
          template_vars.add(var)
      return template_vars
  
imports: from collections import OrderedDict
  import logging
  import re
  import numpy
  from ...util.eq import eq
  from ...util import logger
  from .None import parsing
  from .shader_object import ShaderObject
  from .variable import Variable, Varying
  from .expression import TextExpression, FunctionCall
label_desc: Use image node_id 15 for calling the Function obj's underlying member method code with example usage: obj._parse_template_vars() and returns: template_vars