All files / Sources/Rendering/OpenGL/RenderWindow ContextProxy.js

92% Statements 23/25
87.5% Branches 7/8
87.5% Functions 7/8
100% Lines 23/23

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66  1x     205x   205x   5787x 3969x   1818x           5589x   5589x 5589x                           205x       205x 5787x     205x 5589x   205x   242240x 242240x 242240x   158926x     242240x 242240x 11376x     230864x            
// This is used to access the underlying 3D context
export const GET_UNDERLYING_CONTEXT = '__getUnderlyingContext';
 
export function createContextProxyHandler() {
  const cache = new Map();
 
  const getParameterHandler = {
    apply(target, gl, args) {
      if (cache.has(args[0])) {
        return cache.get(args[0]);
      }
      return target.apply(gl, args);
    },
  };
 
  // only supports single-value setters
  function cachedSetterHandler(key) {
    return {
      apply(target, gl, args) {
        cache.set(key, args[0]);
        return target.apply(gl, args);
      },
    };
  }
 
  // When a property is accessed on the webgl context proxy,
  // it's accessed is intercepted. If the property name matches
  // any of the keys of `propHandlers`, then that handler is called
  // with the following arguments: (gl, prop, receiver, propValue)
  // - gl (WebGL2RenderingContext): the underlying webgl context
  // - propName (string): the property name
  // - receiver (Proxy): the webgl context proxy
  // - propValue (unknown): the value of `gl[propName]`
 
  const propHandlers = Object.create(null);
 
  // Sets getParameter(property) as a cached getter proxy.
  // propValue.bind(gl) is to avoid Illegal Invocation errors.
  propHandlers.getParameter = (gl, prop, receiver, propValue) =>
    new Proxy(propValue.bind(gl), getParameterHandler);
 
  // Sets depthMask(flag) as a cached setter proxy.
  propHandlers.depthMask = (gl, prop, receiver, propValue) =>
    new Proxy(propValue.bind(gl), cachedSetterHandler(gl.DEPTH_WRITEMASK));
 
  return {
    get(gl, prop, receiver) {
      Iif (prop === GET_UNDERLYING_CONTEXT) return () => gl;
      let value = Reflect.get(gl, prop, gl);
      if (value instanceof Function) {
        // prevents Illegal Invocation errors
        value = value.bind(gl);
      }
 
      const propHandler = propHandlers[prop];
      if (propHandler) {
        return propHandler(gl, prop, receiver, value);
      }
 
      return value;
    },
  };
}
 
export default { createContextProxyHandler };