From d5680ebf8a01b1b906edb78c2c6bfd0e477fd557 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Thu, 18 Jun 2015 13:33:54 +0200 Subject: [PATCH] Add memoize functionality --- rpg-docs/lib/memoize/memoize.js | 45 +++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 rpg-docs/lib/memoize/memoize.js diff --git a/rpg-docs/lib/memoize/memoize.js b/rpg-docs/lib/memoize/memoize.js new file mode 100644 index 00000000..6d510374 --- /dev/null +++ b/rpg-docs/lib/memoize/memoize.js @@ -0,0 +1,45 @@ +Tracker.memoize = function(func, hasher){ + var memoize = function(key) { + var cache = memoize.cache; + var address = "" + (hasher ? hasher.apply(this, arguments) : key); + if (!_.has(cache, address)) { + cache[address] = new CacheObject(func, address, arguments, cache, this); + } + return cache[address].get(); + }; + memoize.cache = {}; + return memoize; +}; + +function CacheObject(func, address, args, cache, context){ + var self = this; + self.currentValue = null; + self.dep = new Tracker.Dependency(); + + //spawn a new autorun that keeps the value up-to-date + Tracker.nonreactive(function() { + Tracker.autorun(function(computation) { + //if this isn't the first run and nobody is listening, + //delete itself from cache and stop the computation + if (!computation.firstRun && !self.dep.hasDependents()){ + computation.stop(); + delete cache[address]; + console.log("Nothing depends on '" + address + "', deleting"); + } + //call the expensive function + var newValue = func.apply(context, args); + //if the value changed, store the new value + if (self.currentValue !== newValue){ + self.currentValue = newValue; + //tell the dependents that we've changed + self.dep.changed(); + } + }); + }); +} + +CacheObject.prototype.get = function() { + //if there is an active computation, track dependents + if (Tracker.active) this.dep.depend(); + return this.currentValue; +};