diff --git a/source/Ox/js/Core.js b/source/Ox/js/Core.js index d18b1366..0dc98bdd 100644 --- a/source/Ox/js/Core.js +++ b/source/Ox/js/Core.js @@ -230,20 +230,20 @@ Ox.loop For-loop, functional-style break statement. Unlike a for loop, Ox.loop doesn't leak its counter variable to the outer scope, but returns it. - (stop, callback) -> Next value - equivalent to for (var i = 0; i < stop; i++) - (start, stop, callback) -> Next value - equivalent to for (var i = start; i < stop; i++) or, - if start is larger than stop, - for (var i = start; i > stop; i--) - (start, stop, step, callback) -> Next value - equivalent to for (var i = start; i < stop; i += step) or, - if step is negative, - for (var i = start; i > stop; i += step) + (stop, fn) -> Next value + equivalent to for (var i = 0; i < stop; i++) { fn(i); } + (start, stop, fn) -> Next value + equivalent to for (var i = start; i < stop; i++) { fn(i); } + or, if start is larger than stop, + for (var i = start; i > stop; i--) { fn(i); } + (start, stop, step, fn) -> Next value + equivalent to for (var i = start; i < stop; i += step) { fn(i); + } or, if step is negative, for (var i = start; + i > stop; i += step) { fn(i); } start Start value stop Stop value (exclusive) step Step value - callback Iterator function + fn Iterator function i Counter value > Ox.loop(10, function(i) { return i != 4; }) 4 @@ -255,16 +255,57 @@ Ox.loop = function() { start = len > 2 ? arguments[0] : 0, stop = arguments[len > 2 ? 1 : 0], step = len == 4 ? arguments[2] : (start <= stop ? 1 : -1), - callback = arguments[len - 1], + fn = arguments[len - 1], i; for (i = start; step > 0 ? i < stop : i > stop; i += step) { - if (callback(i) === false) { + if (fn(i) === false) { break; } } return i; }; +Ox._loop = function() { + var type = Ox.toArray(arguments).map(function(arg) { + return Ox.typeOf(arg); + }), + fnIndex = type.indexOf('function'), + callbackIndex = type.lastIndexOf('function'), + nIndex = callbackIndex - 1, + hasStart = type[1] == 'number', + hasStep = hasStart && type[2] == 'number', + hasCallback = fnIndex != callbackIndex, + hasN = hasCallback && type[nIndex] == 'number', + start = hasStart ? arguments[0] : 0, + stop = arguments[hasStart ? 1 : 0], + step = hasStep ? arguments[2] : (start <= stop ? 1 : -1), + fn = arguments[fnIndex], + n = hasN ? arguments[nIndex] / step : 1, + callback = hasCallback ? arguments[callbackIndex] : null; + function loop(start_, stop_, callback_) { + var i, isFalse; + for (i = start_; step > 0 ? i < stop_ : i > stop_; i += step) { + if (isFalse = fn(i) === false) { + break; + } + } + callback_ && callback_(i, !isFalse); + return i; + } + function next(start_) { + setTimeout(function() { + loop(start_, Math.min(start_ + n, stop), function(i, ret) { + (ret && i < stop ? next : callback)(i); + }); + }); + } + if (hasCallback) { + next(start); + } else { + return loop(start, stop); + } +}; + /*@ Ox.print Prints its arguments to the console (arg, ...) -> String