refactor (core) separate sampling into its own handler
This commit is contained in:
parent
3c54e94c43
commit
e59341effa
3 changed files with 231 additions and 194 deletions
|
@ -13,6 +13,7 @@ import { version } from '../../data.mjs'
|
|||
import { __loadPatternDefaults } from '../config.mjs'
|
||||
import { PatternConfig, getPluginName } from './pattern-config.mjs'
|
||||
import { PatternDraftQueue } from './pattern-draft-queue.mjs'
|
||||
import { PatternSampler } from './pattern-sampler.mjs'
|
||||
import cloneDeep from 'lodash.clonedeep'
|
||||
|
||||
//////////////////////////////////////////////
|
||||
|
@ -254,14 +255,7 @@ Pattern.prototype.getRenderProps = function () {
|
|||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.sample = function () {
|
||||
this.__init()
|
||||
if (this.settings[0].sample.type === 'option') {
|
||||
return this.sampleOption(this.settings[0].sample.option)
|
||||
} else if (this.settings[0].sample.type === 'measurement') {
|
||||
return this.sampleMeasurement(this.settings[0].sample.measurement)
|
||||
} else if (this.settings[0].sample.type === 'models') {
|
||||
return this.sampleModels(this.settings[0].sample.models, this.settings[0].sample.focus || false)
|
||||
}
|
||||
return new PatternSampler(this).sample()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -270,13 +264,7 @@ Pattern.prototype.sample = function () {
|
|||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.sampleMeasurement = function (measurementName) {
|
||||
this.store.log.debug(`Sampling measurement \`${measurementName}\``)
|
||||
this.__runHooks('preSample')
|
||||
this.__applySettings(this.__measurementSets(measurementName))
|
||||
this.__init()
|
||||
this.__runHooks('postSample')
|
||||
|
||||
return this.draft()
|
||||
return new PatternSampler(this).sampleMeasurement(measurementName)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,13 +273,7 @@ Pattern.prototype.sampleMeasurement = function (measurementName) {
|
|||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.sampleModels = function (models, focus = false) {
|
||||
this.store.log.debug(`Sampling models \`${Object.keys(models).join(', ')}\``)
|
||||
this.__runHooks('preSample')
|
||||
this.__applySettings(this.__modelSets(models, focus))
|
||||
this.__init()
|
||||
this.__runHooks('postSample')
|
||||
|
||||
return this.draft()
|
||||
return new PatternSampler(this).sampleModels(models, focus)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -300,13 +282,7 @@ Pattern.prototype.sampleModels = function (models, focus = false) {
|
|||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.sampleOption = function (optionName) {
|
||||
this.store.log.debug(`Sampling option \`${optionName}\``)
|
||||
this.__runHooks('preSample')
|
||||
this.__applySettings(this.__optionSets(optionName))
|
||||
this.__init()
|
||||
this.__runHooks('postSample')
|
||||
|
||||
return this.draft()
|
||||
return new PatternSampler(this).sampleOption(optionName)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -527,36 +503,6 @@ Pattern.prototype.__isStackHidden = function (stackName) {
|
|||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings.options objects for sampling a list or boolean option
|
||||
*
|
||||
* @private
|
||||
* @param {string} optionName - Name of the option to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
Pattern.prototype.__listBoolOptionSets = function (optionName) {
|
||||
let option = this.config.options[optionName]
|
||||
const base = this.__setBase()
|
||||
const sets = []
|
||||
let run = 1
|
||||
if (typeof option.bool !== 'undefined') option = { list: [false, true] }
|
||||
for (const choice of option.list) {
|
||||
const settings = {
|
||||
...base,
|
||||
options: {
|
||||
...base.options,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.options[optionName] = choice
|
||||
sets.push(settings)
|
||||
run++
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings.absoluteOptions objects for sampling a list option
|
||||
*
|
||||
|
@ -729,75 +675,6 @@ Pattern.prototype.__macro = function (key, method) {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling a measurement
|
||||
*
|
||||
* @private
|
||||
* @param {string} measurementName - The name of the measurement to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
Pattern.prototype.__measurementSets = function (measurementName) {
|
||||
let val = this.settings[0].measurements[measurementName]
|
||||
if (val === undefined)
|
||||
this.store.log.error(
|
||||
`Cannot sample measurement \`${measurementName}\` because it's \`undefined\``
|
||||
)
|
||||
let step = val / 50
|
||||
val = val * 0.9
|
||||
const sets = []
|
||||
const base = this.__setBase()
|
||||
for (let run = 1; run < 11; run++) {
|
||||
const settings = {
|
||||
...base,
|
||||
measurements: {
|
||||
...base.measurements,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.measurements[measurementName] = val
|
||||
sets.push(settings)
|
||||
val += step
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling a list of models
|
||||
*
|
||||
* @private
|
||||
* @param {object} models - The models to sample
|
||||
* @param {string} focus - The ID of the model that should be highlighted
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
Pattern.prototype.__modelSets = function (models, focus = false) {
|
||||
const sets = []
|
||||
const base = this.__setBase()
|
||||
let run = 1
|
||||
// If there's a focus, do it first so it's at the bottom of the SVG
|
||||
if (focus) {
|
||||
sets.push({
|
||||
...base,
|
||||
measurements: models[focus],
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run} sample-focus`,
|
||||
})
|
||||
run++
|
||||
delete models[focus]
|
||||
}
|
||||
for (const measurements of Object.values(models)) {
|
||||
sets.push({
|
||||
...base,
|
||||
measurements,
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
})
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a part is needed, depending on the 'only' setting and the configured dependencies
|
||||
*
|
||||
|
@ -830,58 +707,6 @@ Pattern.prototype.__needs = function (partName, set = 0) {
|
|||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling an option
|
||||
*
|
||||
* @private
|
||||
* @param {string} optionName - The name of the option to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
Pattern.prototype.__optionSets = function (optionName) {
|
||||
const sets = []
|
||||
if (!(optionName in this.config.options)) return sets
|
||||
let option = this.config.options[optionName]
|
||||
if (typeof option.list === 'object' || typeof option.bool !== 'undefined')
|
||||
return this.__listBoolOptionSets(optionName)
|
||||
let factor = 1
|
||||
let step, val
|
||||
let numberRuns = 10
|
||||
let stepFactor = numberRuns - 1
|
||||
if (typeof option.min === 'undefined' || typeof option.max === 'undefined') {
|
||||
const min = option * 0.9
|
||||
const max = option * 1.1
|
||||
option = { min, max }
|
||||
}
|
||||
if (typeof option.pct !== 'undefined') factor = 100
|
||||
val = option.min / factor
|
||||
if (typeof option.count !== 'undefined' || typeof option.mm !== 'undefined') {
|
||||
const numberOfCounts = option.max - option.min + 1
|
||||
if (numberOfCounts < 10) {
|
||||
numberRuns = numberOfCounts
|
||||
stepFactor = Math.max(numberRuns - 1, 1)
|
||||
}
|
||||
}
|
||||
step = (option.max / factor - val) / stepFactor
|
||||
const base = this.__setBase()
|
||||
for (let run = 1; run <= numberRuns; run++) {
|
||||
const settings = {
|
||||
...base,
|
||||
options: {
|
||||
...base.options,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.options[optionName] = val
|
||||
sets.push(settings)
|
||||
val += step
|
||||
if (typeof option.count !== 'undefined' || typeof option.mm !== 'undefined')
|
||||
val = Math.round(val)
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Packs stacks in a 2D space and sets pattern size
|
||||
*
|
||||
|
@ -999,20 +824,6 @@ Pattern.prototype.__runHooks = function (hookName, data = false) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base/defaults to generate a set of settings
|
||||
*
|
||||
* @private
|
||||
* @return {object} settings - The settings object
|
||||
*/
|
||||
Pattern.prototype.__setBase = function () {
|
||||
return {
|
||||
...this.settings[0],
|
||||
measurements: { ...(this.settings[0].measurements || {}) },
|
||||
options: { ...(this.settings[0].options || {}) },
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the absolute value of a snapped percentage option
|
||||
*
|
||||
|
|
0
packages/core/src/pattern/pattern-draft-handler.mjs
Normal file
0
packages/core/src/pattern/pattern-draft-handler.mjs
Normal file
226
packages/core/src/pattern/pattern-sampler.mjs
Normal file
226
packages/core/src/pattern/pattern-sampler.mjs
Normal file
|
@ -0,0 +1,226 @@
|
|||
export function PatternSampler(pattern) {
|
||||
this.pattern = pattern
|
||||
}
|
||||
|
||||
PatternSampler.prototype.sample = function () {
|
||||
this.pattern.__init()
|
||||
const sampleSetting = this.pattern.settings[0].sample
|
||||
if (sampleSetting.type === 'option') {
|
||||
return this.sampleOption(sampleSetting.option)
|
||||
} else if (sampleSetting.type === 'measurement') {
|
||||
return this.sampleMeasurement(sampleSetting.measurement)
|
||||
} else if (sampleSetting.type === 'models') {
|
||||
return this.sampleModels(sampleSetting.models, sampleSetting.focus || false)
|
||||
}
|
||||
return this.pattern
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles measurement sampling
|
||||
*
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
PatternSampler.prototype.sampleMeasurement = function (measurementName) {
|
||||
this.pattern.store.log.debug(`Sampling measurement \`${measurementName}\``)
|
||||
this.pattern.__runHooks('preSample')
|
||||
this.pattern.__applySettings(this.__measurementSets(measurementName))
|
||||
this.pattern.__init()
|
||||
this.pattern.__runHooks('postSample')
|
||||
|
||||
return this.pattern.draft()
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles models sampling
|
||||
*
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
PatternSampler.prototype.sampleModels = function (models, focus = false) {
|
||||
this.pattern.store.log.debug(`Sampling models \`${Object.keys(models).join(', ')}\``)
|
||||
this.pattern.__runHooks('preSample')
|
||||
this.pattern.__applySettings(this.__modelSets(models, focus))
|
||||
this.pattern.__init()
|
||||
this.pattern.__runHooks('postSample')
|
||||
|
||||
return this.pattern.draft()
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles option sampling
|
||||
*
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
PatternSampler.prototype.sampleOption = function (optionName) {
|
||||
this.pattern.store.log.debug(`Sampling option \`${optionName}\``)
|
||||
this.pattern.__runHooks('preSample')
|
||||
this.pattern.__applySettings(this.__optionSets(optionName))
|
||||
this.pattern.__init()
|
||||
this.pattern.__runHooks('postSample')
|
||||
|
||||
return this.pattern.draft()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the base/defaults to generate a set of settings
|
||||
*
|
||||
* @private
|
||||
* @return {object} settings - The settings object
|
||||
*/
|
||||
PatternSampler.prototype.__setBase = function () {
|
||||
return {
|
||||
measurements: {},
|
||||
options: {},
|
||||
...this.pattern.settings[0],
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings.options objects for sampling a list or boolean option
|
||||
*
|
||||
* @private
|
||||
* @param {string} optionName - Name of the option to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
PatternSampler.prototype.__listBoolOptionSets = function (optionName) {
|
||||
let option = this.pattern.config.options[optionName]
|
||||
const base = this.__setBase()
|
||||
const sets = []
|
||||
let run = 1
|
||||
if (typeof option.bool !== 'undefined') option = { list: [false, true] }
|
||||
for (const choice of option.list) {
|
||||
const settings = {
|
||||
...base,
|
||||
options: {
|
||||
...base.options,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.options[optionName] = choice
|
||||
sets.push(settings)
|
||||
run++
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling a measurement
|
||||
*
|
||||
* @private
|
||||
* @param {string} measurementName - The name of the measurement to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
PatternSampler.prototype.__measurementSets = function (measurementName) {
|
||||
let val = this.pattern.settings[0].measurements[measurementName]
|
||||
if (val === undefined)
|
||||
this.pattern.store.log.error(
|
||||
`Cannot sample measurement \`${measurementName}\` because it's \`undefined\``
|
||||
)
|
||||
let step = val / 50
|
||||
val = val * 0.9
|
||||
const sets = []
|
||||
const base = this.__setBase()
|
||||
for (let run = 1; run < 11; run++) {
|
||||
const settings = {
|
||||
...base,
|
||||
measurements: {
|
||||
...base.measurements,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.measurements[measurementName] = val
|
||||
sets.push(settings)
|
||||
val += step
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling a list of models
|
||||
*
|
||||
* @private
|
||||
* @param {object} models - The models to sample
|
||||
* @param {string} focus - The ID of the model that should be highlighted
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
PatternSampler.prototype.__modelSets = function (models, focus = false) {
|
||||
const sets = []
|
||||
const base = this.__setBase()
|
||||
let run = 1
|
||||
// If there's a focus, do it first so it's at the bottom of the SVG
|
||||
if (focus) {
|
||||
sets.push({
|
||||
...base,
|
||||
measurements: models[focus],
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run} sample-focus`,
|
||||
})
|
||||
run++
|
||||
delete models[focus]
|
||||
}
|
||||
for (const measurements of Object.values(models)) {
|
||||
sets.push({
|
||||
...base,
|
||||
measurements,
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
})
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings objects for sampling an option
|
||||
*
|
||||
* @private
|
||||
* @param {string} optionName - The name of the option to sample
|
||||
* @return {Array} sets - The list of settings objects
|
||||
*/
|
||||
PatternSampler.prototype.__optionSets = function (optionName) {
|
||||
const sets = []
|
||||
if (!(optionName in this.pattern.config.options)) return sets
|
||||
let option = this.pattern.config.options[optionName]
|
||||
if (typeof option.list === 'object' || typeof option.bool !== 'undefined')
|
||||
return this.__listBoolOptionSets(optionName)
|
||||
let factor = 1
|
||||
let step, val
|
||||
let numberRuns = 10
|
||||
let stepFactor = numberRuns - 1
|
||||
if (typeof option.min === 'undefined' || typeof option.max === 'undefined') {
|
||||
const min = option * 0.9
|
||||
const max = option * 1.1
|
||||
option = { min, max }
|
||||
}
|
||||
if (typeof option.pct !== 'undefined') factor = 100
|
||||
val = option.min / factor
|
||||
if (typeof option.count !== 'undefined' || typeof option.mm !== 'undefined') {
|
||||
const numberOfCounts = option.max - option.min + 1
|
||||
if (numberOfCounts < 10) {
|
||||
numberRuns = numberOfCounts
|
||||
stepFactor = Math.max(numberRuns - 1, 1)
|
||||
}
|
||||
}
|
||||
step = (option.max / factor - val) / stepFactor
|
||||
const base = this.__setBase()
|
||||
for (let run = 1; run <= numberRuns; run++) {
|
||||
const settings = {
|
||||
...base,
|
||||
options: {
|
||||
...base.options,
|
||||
},
|
||||
idPrefix: `sample-${run}`,
|
||||
partClasses: `sample-${run}`,
|
||||
}
|
||||
settings.options[optionName] = val
|
||||
sets.push(settings)
|
||||
val += step
|
||||
if (typeof option.count !== 'undefined' || typeof option.mm !== 'undefined')
|
||||
val = Math.round(val)
|
||||
}
|
||||
|
||||
return sets
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue