class_docstr: Shader program using Function instances as basis for its shaders.
  
  Automatically rebuilds program when functions have changed and uploads
  program variables.
class_docstr_tok: ["Shader","program","using","Function","instances","as","basis","for","its","shaders",".","Automatically","rebuilds","program","when","functions","have","changed","and","uploads","program","variables","."]
docstr: Reset shader source if necesssary.
docstr_tok: ["Reset","shader","source","if","necesssary","."]
code: def build_if_needed(self):
      """Reset shader source if necesssary."""
      if self._need_build:
          self._build()
  
          # after recompile, we need to upload all variables again
          # (some variables may have changed name)
          self._variable_cache.clear()
  
          # Collect a list of all settable variables
          settable_vars = "attribute", "uniform", "in"
          deps = [
              d
              for d in self.vert.dependencies()
              if (isinstance(d, Variable) and d.vtype in settable_vars)
          ]
          deps += [
              d
              for d in self.frag.dependencies()
              if (isinstance(d, Variable) and d.vtype == "uniform")
          ]
          if self.geom is not None:
              deps += [
                  d
                  for d in self.geom.dependencies()
                  if (isinstance(d, Variable) and d.vtype == "uniform")
              ]
          self._variables = deps
  
          self._need_build = False
  
imports: from __future__ import division
  import logging
  from weakref import WeakKeyDictionary
  from ...gloo import Program
  from ...gloo.preprocessor import preprocess
  from ...util import logger
  from ...util.event import EventEmitter
  from .function import MainFunction
  from .variable import Variable
  from .compiler import Compiler
label_desc: Use image node_id 10 for calling the ModularProgram obj's underlying member method code with example usage: obj.build_if_needed() without return types