Pomax / lib-font

This library adds a new Font() object to the JavaScript toolbox, similar to new Image() for images
MIT License
730 stars 72 forks source link

Adding a "cache lazy lookup results" flag #84

Open Pomax opened 4 years ago

Pomax commented 4 years ago

Updating the lazy loader to this:

function lazy(object, property, getter, cache=false) {
    if (cache) {
        // one-time getter, overwriting the property binding with
        // the actual value on first lookup.
        return Object.defineProperty(object, property, {
            get: () => {
                object[property] = getter();
                return object[property];
            },
            set: (v) => {
                delete object[property];
                object[property] = v;
            },
            configurable: true
        });
    }

    // permanent lazy loader
    let val;
    Object.defineProperty(object, property, {
        get: () => {
            if (val) return val;
            val = getter();
            return val;
        }
    });
};

means that its possible to either do pure lazy loading, always consulting the byte buffer, or one-time lazy loading, where the result gets cached to the property that was lazy loaded. Both have advantages and disadvantages, and it would be nice if there were a way to tell a font which caching policy to for which datatypes.

I'd imagine this as a dedicated cache list object that can be imported:

const cache = {};

function enableCachingFor(...classDotField) {
  classDotField.forEach(entry => {
    let [className, fieldName] = entry.split(`.`);
    if (!cache [className]) cache [className] = [];
    cache [className].push(fieldName);
  });
}

function shouldCache(classInstance, fieldName) {
  let className = classInstance.constructor.name;
  if (!cache[className]) return false;
  return cache [className].includes(fieldName};
}

export { enableCachingFor, shouldCache };

Which can then be specified in someone's code:

import { Font } from "Font.js";

const font = new Font("lol");

font.enableCachingFor(
  `NameRecord.value`,
  `VORG.vertORiginYMetrics`,
  ...
);

font.onerror = ... 
font.onload = ...
font.src = "somefontlollercakes.otf";

And that the lazy loader can consult when invoked:

import { shouldCache } from "cache-o-lator.js";

export default function lazy(object, property, getter, cache=false) {
  if (shouldCache(object, property)) {
    return Object.defineProperty(...)
  }

  // implicit else
  return Object.defineProperty(...)
}