2012-02-04 08:58:46 +00:00
|
|
|
'use strict';
|
2012-01-07 07:20:02 +00:00
|
|
|
/*@
|
|
|
|
Ox.cache <f> Memoize a function
|
|
|
|
<script>
|
2012-03-29 12:34:13 +00:00
|
|
|
Ox.test.fn = Ox.cache(function(n) { return n * Math.random(); });
|
2012-01-07 07:20:02 +00:00
|
|
|
</script>
|
2012-03-29 12:34:13 +00:00
|
|
|
> Ox.test.fn(10) == Ox.test.fn(10);
|
2012-01-07 07:20:02 +00:00
|
|
|
true
|
2012-03-29 12:34:13 +00:00
|
|
|
> Ox.test.fn(10) == Ox.test.fn.clear()(10);
|
2012-01-07 07:20:02 +00:00
|
|
|
false
|
|
|
|
@*/
|
2012-04-03 13:09:05 +00:00
|
|
|
Ox.cache = function(fn, options) {
|
|
|
|
options = Ox.extend({
|
|
|
|
async: false,
|
|
|
|
key: JSON.stringify
|
|
|
|
}, options || {})
|
2012-01-07 07:20:02 +00:00
|
|
|
var cache = {},
|
|
|
|
ret = function() {
|
2012-05-19 08:40:59 +00:00
|
|
|
var args = Ox.toArray(arguments),
|
2012-04-03 13:09:05 +00:00
|
|
|
callback,
|
|
|
|
key = options.key(args);
|
|
|
|
function callback() {
|
|
|
|
// cache all arguments passed to callback
|
2012-05-19 08:40:59 +00:00
|
|
|
cache[key] = Ox.toArray(arguments);
|
2012-04-03 13:09:05 +00:00
|
|
|
// call the original callback
|
|
|
|
Ox.last(args).apply(this, arguments);
|
|
|
|
}
|
|
|
|
if (options.async) {
|
|
|
|
if (!(key in cache)) {
|
|
|
|
// call function with patched callback
|
2012-05-24 07:45:33 +00:00
|
|
|
fn.apply(this, args.slice(0, -1).concat(callback));
|
2012-04-03 13:09:05 +00:00
|
|
|
} else {
|
|
|
|
// call callback with cached arguments
|
|
|
|
callback.apply(this, cache[key])
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!(key in cache)) {
|
|
|
|
cache[key] = fn.apply(this, args);
|
|
|
|
}
|
|
|
|
return cache[key];
|
|
|
|
}
|
2012-01-07 07:20:02 +00:00
|
|
|
};
|
|
|
|
ret.clear = function() {
|
|
|
|
if (arguments.length == 0) {
|
|
|
|
cache = {};
|
|
|
|
} else {
|
2012-05-19 08:40:59 +00:00
|
|
|
Ox.makeArray(arguments).forEach(function(key) {
|
2012-01-07 07:20:02 +00:00
|
|
|
delete cache[key];
|
|
|
|
});
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
return ret;
|
2012-02-04 08:58:46 +00:00
|
|
|
};
|
2012-04-08 12:19:53 +00:00
|
|
|
|
2012-05-24 16:20:22 +00:00
|
|
|
/*@
|
|
|
|
Ox.identity <f> Returns its first argument
|
|
|
|
This can be used as a default iterator
|
|
|
|
@*/
|
2012-05-19 08:09:48 +00:00
|
|
|
Ox.identity = function(val) {
|
|
|
|
return val;
|
|
|
|
};
|
|
|
|
|
2012-04-08 12:19:53 +00:00
|
|
|
/*@
|
2012-05-24 16:20:22 +00:00
|
|
|
Ox.noop <f> Returns undefined and calls optional callback without arguments
|
|
|
|
This can be used to combine a synchronous and an asynchronous code path.
|
2012-04-08 12:19:53 +00:00
|
|
|
@*/
|
2012-05-24 16:20:22 +00:00
|
|
|
// IE 8 doesn't like `Ox.void`
|
|
|
|
Ox.noop = function(callback) {
|
2012-04-08 12:19:53 +00:00
|
|
|
Ox.isFunction(callback) && callback();
|
|
|
|
};
|