class_docstr: Representation of global shader variable
  
  Parameters
  ----------
  name : str
      the name of the variable. This string can also contain the full
      definition of the variable, e.g. 'uniform vec2 foo'.
  value : {float, int, tuple, GLObject}
      If given, vtype and dtype are determined automatically. If a
      float/int/tuple is given, the variable is a uniform. If a gloo
      object is given that has a glsl_type property, the variable is
      an attribute and
  vtype : {'const', 'uniform', 'attribute', 'varying', 'inout'}
      The type of variable.
  dtype : str
      The data type of the variable, e.g. 'float', 'vec4', 'mat', etc.
class_docstr_tok: ["Representation","of","global","shader","variable","Parameters","--","--","--","--","--","name",":","str","the","name","of","the","variable",".","This","string","can","also","contain","the","full","definition","of","the","variable",",","e.g",".","'uniform","vec2","foo","'",".","value",":","{","float",",","int",",","tuple",",","GLObject","}","If","given",",","vtype","and","dtype","are","determined","automatically",".","If","a","float\/int\/tuple","is","given",",","the","variable","is","a","uniform",".","If","a","gloo","object","is","given","that","has","a","glsl_type","property",",","the","variable","is","an","attribute","and","vtype",":","{","'const","'",",","'uniform","'",",","'attribute","'",",","'varying","'",",","'inout","'","}","The","type","of","variable",".","dtype",":","str","The","data","type","of","the","variable",",","e.g",".","'float","'",",","'vec4","'",",","'mat","'",",","etc","."]
code: def value(self, value):
      if isinstance(value, (tuple, list)) and 1 < len(value) < 5:
          vtype = "uniform"
          dtype = "vec%d" % len(value)
      elif isinstance(value, np.ndarray):
          if value.ndim == 1 and (1 < len(value) < 5):
              vtype = "uniform"
              dtype = "vec%d" % len(value)
          elif value.ndim == 2 and value.shape in (
              (2, 2),
              (3, 3),
              (4, 4),
          ):
              vtype = "uniform"
              dtype = "mat%d" % value.shape[0]
          else:
              raise ValueError(
                  "Cannot make uniform value for %s from array "
                  "of shape %s." % (self.name, value.shape)
              )
      elif np.isscalar(value):
          vtype = "uniform"
          if isinstance(value, (float, np.floating)):
              dtype = "float"
          elif isinstance(value, (int, np.integer)):
              dtype = "int"
          else:
              raise TypeError(
                  "Unknown data type %r for variable %r"
                  % (type(value), self)
              )
      elif getattr(value, "glsl_type", None) is not None:
          # Note: hasattr() is broken by design--swallows all exceptions!
          vtype, dtype = value.glsl_type
      else:
          raise TypeError(
              "Unknown data type %r for variable %r"
              % (type(value), self)
          )
  
      self._value = value
      self._state_counter += 1
  
      if self._type_locked:
          if dtype != self._dtype or vtype != self._vtype:
              raise TypeError(
                  'Variable is type "%s"; cannot assign value '
                  "%r." % (self.dtype, value)
              )
          return
  
      # update vtype/dtype and emit changed event if necessary
      changed = False
      if self._dtype != dtype:
          self._dtype = dtype
          changed = True
      if self._vtype != vtype:
          self._vtype = vtype
          changed = True
      if changed:
          self.changed(code_changed=True, value_changed=True)
  
imports: import numpy
  from .shader_object import ShaderObject
label_desc: Use image node_id 7 for calling the Variable obj's underlying member method code with example usage: obj.value(value) without return types