It is beyond anything you have ever experienced or imagined
Archive for November, 2011
Function#debounce Useful JavaScript Game Extension #36
Nov 27th
I got this from Underscore.js.
###*
Calling a debounced function will postpone its execution until after
wait milliseconds have elapsed since the last time the function was
invoked. Useful for implementing behavior that should only happen after
the input has stopped arriving. For example: rendering a preview of a
Markdown comment, recalculating a layout after the window has stopped
being resized...
lazyLayout = calculateLayout.debounce(300)
$(window).resize(lazyLayout)
@name debounce
@methodOf Function#
@returns {Function} The debounced version of this function.
###
Function::debounce = (wait) ->
timeout = null
func = this
return ->
context = this
args = arguments
later = ->
timeout = null
func.apply(context, args)
clearTimeout(timeout)
timeout = setTimeout(later, wait)Already I can see an important use for it. In the code editor we copy out the buffer every keyup. This can lead to a bunch of extra work for the browser when typing. Usually it’s not a big deal because the files are generally small, but on larger files it can add up and cause some lagging. When using debounce the editor will only trigger after enough milliseconds have elapsed since the end of new keyup events. This will keep the IDE from lagging on larger files while you are typing.
Another place debounce is useful is in a game that implements a Halo style health regeneration. Every time the player takes damage a debounced startRegen function could be called. That way the regen will only start after enough time without taking damage has elapsed. In the game version it would probably be better to constrain it to ticks of the engine, or engine elapsed time for more accuracy.
I’m always a big fan of Function functions, they are a great way to reduce boilerplate and solve higher-order problems.
Array#pipeline Useful JavaScript Game Extension #35
Nov 16th
###*
Pipe the input through each function in the array in turn. For example, if you have
a list of objects you can perform a series of selection, sorting, and other
processing methods and then receive the processed list. This array must contain
functions that accept a single input and return the processed input. The output of
the first function is fed to the input of the second and so on until the final
processed output is returned.
@name pipeline
@methodOf Array#
@param {Object} input The initial input to pass to the first function in the pipeline.
@returns {Object} The result of processing the input by each function in the array.
###
Array::pipeline = (input) ->
for fn in this
input = fn(input)
return inputThe main use for this is in the PixieEngine cameras module where we need to process the camera transform with a stream of modifiers. This also allows for the game objects list to be z-sorted, filtered to a subset that passes a clip test, or any other arbitrary stream filter.
I think this is probably some sort of fundamental concept of functional programming, but I’m not sure if `pipeline` is the right name. If anyone has historic info on this please let me know.