UNPKG

2.31 kBJavaScriptView Raw
1// //////////////////////////////
2// ## class fuzzyFactory
3// This class acts as a factory for objects. We can search for an object with approximately
4// the desired properties (say a rectangle with width 2 and height 1)
5// The lookupOrCreate() method looks for an existing object (for example it may find an existing rectangle
6// with width 2.0001 and height 0.999. If no object is found, the user supplied callback is
7// called, which should generate a new object. The new object is inserted into the database
8// so it can be found by future lookupOrCreate() calls.
9// Constructor:
10// numdimensions: the number of parameters for each object
11// for example for a 2D rectangle this would be 2
12// tolerance: The maximum difference for each parameter allowed to be considered a match
13const FuzzyFactory = function (numdimensions, tolerance) {
14 this.lookuptable = {}
15 this.multiplier = 1.0 / tolerance
16}
17
18FuzzyFactory.prototype = {
19 // let obj = f.lookupOrCreate([el1, el2, el3], function(elements) {/* create the new object */});
20 // Performs a fuzzy lookup of the object with the specified elements.
21 // If found, returns the existing object
22 // If not found, calls the supplied callback function which should create a new object with
23 // the specified properties. This object is inserted in the lookup database.
24 lookupOrCreate: function (els, creatorCallback) {
25 let hash = ''
26 let multiplier = this.multiplier
27 els.forEach(function (el) {
28 let valueQuantized = Math.round(el * multiplier)
29 hash += valueQuantized + '/'
30 })
31 if (hash in this.lookuptable) {
32 return this.lookuptable[hash]
33 } else {
34 let object = creatorCallback(els)
35 let hashparts = els.map(function (el) {
36 let q0 = Math.floor(el * multiplier)
37 let q1 = q0 + 1
38 return ['' + q0 + '/', '' + q1 + '/']
39 })
40 let numelements = els.length
41 let numhashes = 1 << numelements
42 for (let hashmask = 0; hashmask < numhashes; ++hashmask) {
43 let hashmaskShifted = hashmask
44 hash = ''
45 hashparts.forEach(function (hashpart) {
46 hash += hashpart[hashmaskShifted & 1]
47 hashmaskShifted >>= 1
48 })
49 this.lookuptable[hash] = object
50 }
51 return object
52 }
53 }
54}
55
56module.exports = FuzzyFactory