Skip to content

Commit

Permalink
Merge pull request #57 from enbyautumn/main
Browse files Browse the repository at this point in the history
Add MEMOIZE function to automatically memoize a function
  • Loading branch information
TodePond committed Oct 6, 2022
2 parents 1095999 + 9e13724 commit db5cfef
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 69 deletions.
107 changes: 73 additions & 34 deletions build/habitat-embed.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,39 +701,6 @@ const Habitat = {}

}

//======//
// Main //
//======//
Habitat.install = (global) => {

if (Habitat.installed) return

if (!Habitat.Array.installed) Habitat.Array.install(global)
if (!Habitat.Async.installed) Habitat.Async.install(global)
if (!Habitat.Colour.installed) Habitat.Colour.install(global)
if (!Habitat.Console.installed) Habitat.Console.install(global)
if (!Habitat.Document.installed) Habitat.Document.install(global)
if (!Habitat.Event.installed) Habitat.Event.install(global)
if (!Habitat.HTML.installed) Habitat.HTML.install(global)
if (!Habitat.JS.installed) Habitat.JS.install(global)
if (!Habitat.Keyboard.installed) Habitat.Keyboard.install(global)
if (!Habitat.LinkedList.installed) Habitat.LinkedList.install(global)
if (!Habitat.Math.installed) Habitat.Math.install(global)
if (!Habitat.Mouse.installed) Habitat.Mouse.install(global)
if (!Habitat.Number.installed) Habitat.Number.install(global)
if (!Habitat.Object.installed) Habitat.Object.install(global)
if (!Habitat.Random.installed) Habitat.Random.install(global)
if (!Habitat.Stage.installed) Habitat.Stage.install(global)
if (!Habitat.String.installed) Habitat.String.install(global)
if (!Habitat.Struct.installed) Habitat.Struct.install(global)
if (!Habitat.Touches.installed) Habitat.Touches.install(global)
if (!Habitat.Tween.installed) Habitat.Tween.install(global)
if (!Habitat.Type.installed) Habitat.Type.install(global)

Habitat.installed = true

}

//======//
// Math //
//======//
Expand Down Expand Up @@ -1525,4 +1492,76 @@ Habitat.install = (global) => {

Habitat.Type = {install, Int, Positive, Negative, UInt, UpperCase, LowerCase, WhiteSpace, PureObject, Primitive}

}
}

//======//
// Main //
//======//
Habitat.install = (global) => {

if (Habitat.installed) return

if (!Habitat.Array.installed) Habitat.Array.install(global)
if (!Habitat.Async.installed) Habitat.Async.install(global)
if (!Habitat.Colour.installed) Habitat.Colour.install(global)
if (!Habitat.Console.installed) Habitat.Console.install(global)
if (!Habitat.Document.installed) Habitat.Document.install(global)
if (!Habitat.Event.installed) Habitat.Event.install(global)
if (!Habitat.HTML.installed) Habitat.HTML.install(global)
if (!Habitat.JS.installed) Habitat.JS.install(global)
if (!Habitat.Keyboard.installed) Habitat.Keyboard.install(global)
if (!Habitat.LinkedList.installed) Habitat.LinkedList.install(global)
if (!Habitat.Math.installed) Habitat.Math.install(global)
if (!Habitat.Mouse.installed) Habitat.Mouse.install(global)
if (!Habitat.Number.installed) Habitat.Number.install(global)
if (!Habitat.Object.installed) Habitat.Object.install(global)
if (!Habitat.Random.installed) Habitat.Random.install(global)
if (!Habitat.Stage.installed) Habitat.Stage.install(global)
if (!Habitat.String.installed) Habitat.String.install(global)
if (!Habitat.Struct.installed) Habitat.Struct.install(global)
if (!Habitat.Touches.installed) Habitat.Touches.install(global)
if (!Habitat.Tween.installed) Habitat.Tween.install(global)
if (!Habitat.Type.installed) Habitat.Type.install(global)
if (!Habitat.memo.installed) Habitat.memo.install(global)

Habitat.installed = true

}

//=========//
// Memoize //
//=========//
{
// Memoize the function - Modified from https://tjinlag.medium.com/memoize-javascript-function-638f3b7c80e9
// keymaker is optional and allows you to specifiy a method for generating the key for the cache
// It should be used if the default method is not suitable for the use case
// The memo function returns a new function that will now be memoized, meaning it caches results
Habitat.memo = (fn, keyMaker) => {
// Make a Map (similar to an object but with faster lookup) to store the results of the function
const cache = new Map()

return (...args) => {
// Make a key that will be used to look up the results of the function
// This keyMaker is not very efficent, but should work for more use cases
// A better keyMaker would be one that is specific to the use case, such as (a) => args[0]
const key = keyMaker ? keyMaker.apply(this, args) : args.map(JSON.stringify).join('')

// If the key is in the cache, return the value
if (cache.has(key)) {
return cache.get(key)
}

// If the key is not in the cache, run the function and store the result in the cache
const result = fn.apply(this, args)
cache.set(key, result)

return result
}
}

Habitat.memo.install = (global) => {
global.memo = Habitat.memo
Habitat.memo.installed = true
}

}
106 changes: 73 additions & 33 deletions build/habitat-import.js
Original file line number Diff line number Diff line change
Expand Up @@ -701,39 +701,6 @@ const Habitat = {}

}

//======//
// Main //
//======//
Habitat.install = (global) => {

if (Habitat.installed) return

if (!Habitat.Array.installed) Habitat.Array.install(global)
if (!Habitat.Async.installed) Habitat.Async.install(global)
if (!Habitat.Colour.installed) Habitat.Colour.install(global)
if (!Habitat.Console.installed) Habitat.Console.install(global)
if (!Habitat.Document.installed) Habitat.Document.install(global)
if (!Habitat.Event.installed) Habitat.Event.install(global)
if (!Habitat.HTML.installed) Habitat.HTML.install(global)
if (!Habitat.JS.installed) Habitat.JS.install(global)
if (!Habitat.Keyboard.installed) Habitat.Keyboard.install(global)
if (!Habitat.LinkedList.installed) Habitat.LinkedList.install(global)
if (!Habitat.Math.installed) Habitat.Math.install(global)
if (!Habitat.Mouse.installed) Habitat.Mouse.install(global)
if (!Habitat.Number.installed) Habitat.Number.install(global)
if (!Habitat.Object.installed) Habitat.Object.install(global)
if (!Habitat.Random.installed) Habitat.Random.install(global)
if (!Habitat.Stage.installed) Habitat.Stage.install(global)
if (!Habitat.String.installed) Habitat.String.install(global)
if (!Habitat.Struct.installed) Habitat.Struct.install(global)
if (!Habitat.Touches.installed) Habitat.Touches.install(global)
if (!Habitat.Tween.installed) Habitat.Tween.install(global)
if (!Habitat.Type.installed) Habitat.Type.install(global)

Habitat.installed = true

}

//======//
// Math //
//======//
Expand Down Expand Up @@ -1527,6 +1494,79 @@ Habitat.install = (global) => {

}

//======//
// Main //
//======//
Habitat.install = (global) => {

if (Habitat.installed) return

if (!Habitat.Array.installed) Habitat.Array.install(global)
if (!Habitat.Async.installed) Habitat.Async.install(global)
if (!Habitat.Colour.installed) Habitat.Colour.install(global)
if (!Habitat.Console.installed) Habitat.Console.install(global)
if (!Habitat.Document.installed) Habitat.Document.install(global)
if (!Habitat.Event.installed) Habitat.Event.install(global)
if (!Habitat.HTML.installed) Habitat.HTML.install(global)
if (!Habitat.JS.installed) Habitat.JS.install(global)
if (!Habitat.Keyboard.installed) Habitat.Keyboard.install(global)
if (!Habitat.LinkedList.installed) Habitat.LinkedList.install(global)
if (!Habitat.Math.installed) Habitat.Math.install(global)
if (!Habitat.Mouse.installed) Habitat.Mouse.install(global)
if (!Habitat.Number.installed) Habitat.Number.install(global)
if (!Habitat.Object.installed) Habitat.Object.install(global)
if (!Habitat.Random.installed) Habitat.Random.install(global)
if (!Habitat.Stage.installed) Habitat.Stage.install(global)
if (!Habitat.String.installed) Habitat.String.install(global)
if (!Habitat.Struct.installed) Habitat.Struct.install(global)
if (!Habitat.Touches.installed) Habitat.Touches.install(global)
if (!Habitat.Tween.installed) Habitat.Tween.install(global)
if (!Habitat.Type.installed) Habitat.Type.install(global)
if (!Habitat.memo.installed) Habitat.memo.install(global)

Habitat.installed = true

}

//=========//
// Memoize //
//=========//
{
// Memoize the function - Modified from https://tjinlag.medium.com/memoize-javascript-function-638f3b7c80e9
// keymaker is optional and allows you to specifiy a method for generating the key for the cache
// It should be used if the default method is not suitable for the use case
// The memo function returns a new function that will now be memoized, meaning it caches results
Habitat.memo = (fn, keyMaker) => {
// Make a Map (similar to an object but with faster lookup) to store the results of the function
const cache = new Map()

return (...args) => {
// Make a key that will be used to look up the results of the function
// This keyMaker is not very efficent, but should work for more use cases
// A better keyMaker would be one that is specific to the use case, such as (a) => args[0]
const key = keyMaker ? keyMaker.apply(this, args) : args.map(JSON.stringify).join('')

// If the key is in the cache, return the value
if (cache.has(key)) {
return cache.get(key)
}

// If the key is not in the cache, run the function and store the result in the cache
const result = fn.apply(this, args)
cache.set(key, result)

return result
}
}

Habitat.memo.install = (global) => {
global.memo = Habitat.memo
Habitat.memo.installed = true
}

}


export {Habitat}
export default Habitat
export const {install} = Habitat
Expand Down
3 changes: 2 additions & 1 deletion examples/example-embed-multiple.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
<script src="../source/javascript.js"></script>
<script src="../source/keyboard.js"></script>
<script src="../source/linkedList.js"></script>
<script src="../source/main.js"></script>
<script src="../source/math.js"></script>
<script src="../source/mouse.js"></script>
<script src="../source/number.js"></script>
Expand All @@ -23,6 +22,8 @@
<script src="../source/touch.js"></script>
<script src="../source/tween.js"></script>
<script src="../source/type.js"></script>
<script src="../source/main.js"></script>
<script src="../source/memoize.js"></script>
<script>

Habitat.install(window)
Expand Down
1 change: 1 addition & 0 deletions source/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ Habitat.install = (global) => {
if (!Habitat.Touches.installed) Habitat.Touches.install(global)
if (!Habitat.Tween.installed) Habitat.Tween.install(global)
if (!Habitat.Type.installed) Habitat.Type.install(global)
if (!Habitat.memo.installed) Habitat.memo.install(global)

Habitat.installed = true

Expand Down
37 changes: 37 additions & 0 deletions source/memoize.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//=========//
// Memoize //
//=========//
{
// Memoize the function - Modified from https://tjinlag.medium.com/memoize-javascript-function-638f3b7c80e9
// keymaker is optional and allows you to specifiy a method for generating the key for the cache
// It should be used if the default method is not suitable for the use case
// The memo function returns a new function that will now be memoized, meaning it caches results
Habitat.memo = (fn, keyMaker) => {
// Make a Map (similar to an object but with faster lookup) to store the results of the function
const cache = new Map()

return (...args) => {
// Make a key that will be used to look up the results of the function
// This keyMaker is not very efficent, but should work for more use cases
// A better keyMaker would be one that is specific to the use case, such as (a) => args[0]
const key = keyMaker ? keyMaker.apply(this, args) : args.map(JSON.stringify).join('')

// If the key is in the cache, return the value
if (cache.has(key)) {
return cache.get(key)
}

// If the key is not in the cache, run the function and store the result in the cache
const result = fn.apply(this, args)
cache.set(key, result)

return result
}
}

Habitat.memo.install = (global) => {
global.memo = Habitat.memo
Habitat.memo.installed = true
}

}
3 changes: 2 additions & 1 deletion tinker/tinker.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<script src="../source/javascript.js"></script>
<script src="../source/keyboard.js"></script>
<script src="../source/linkedList.js"></script>
<script src="../source/main.js"></script>
<script src="../source/math.js"></script>
<script src="../source/mouse.js"></script>
<script src="../source/number.js"></script>
Expand All @@ -24,4 +23,6 @@
<script src="../source/touch.js"></script>
<script src="../source/tween.js"></script>
<script src="../source/type.js"></script>
<script src="../source/main.js"></script>
<script src="../source/memoize.js"></script>
<body><script src="tinker.js"></script></body>

0 comments on commit db5cfef

Please sign in to comment.