refactor (core) reorganize method groupings in Pattern
This commit is contained in:
parent
8fea9a4beb
commit
13ec5e43e5
5 changed files with 198 additions and 201 deletions
|
@ -1,13 +1,9 @@
|
|||
import { Attributes } from '../attributes.mjs'
|
||||
import { __addNonEnumProp, __macroName } from '../utils.mjs'
|
||||
import { Part } from '../part.mjs'
|
||||
import { Stack } from '../stack.mjs'
|
||||
import { __addNonEnumProp } from '../utils.mjs'
|
||||
import { Point } from '../point.mjs'
|
||||
import { Path } from '../path.mjs'
|
||||
import { Snippet } from '../snippet.mjs'
|
||||
import { Svg } from '../svg.mjs'
|
||||
import { Store } from '../store.mjs'
|
||||
import { Hooks } from '../hooks.mjs'
|
||||
import { version } from '../../data.mjs'
|
||||
import { __loadPatternDefaults } from '../config.mjs'
|
||||
import { PatternConfig } from './pattern-config.mjs'
|
||||
|
@ -40,7 +36,6 @@ export function Pattern(designConfig = {}) {
|
|||
__addNonEnumProp(this, 'height', 0)
|
||||
__addNonEnumProp(this, 'autoLayout', { stacks: {} })
|
||||
__addNonEnumProp(this, 'is', '')
|
||||
__addNonEnumProp(this, 'hooks', new Hooks())
|
||||
__addNonEnumProp(this, 'Point', Point)
|
||||
__addNonEnumProp(this, 'Path', Path)
|
||||
__addNonEnumProp(this, 'Snippet', Snippet)
|
||||
|
@ -59,6 +54,10 @@ export function Pattern(designConfig = {}) {
|
|||
// PUBLIC METHODS //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
///////////
|
||||
// Setup //
|
||||
///////////
|
||||
|
||||
/**
|
||||
* Allows adding parts to the config at runtime
|
||||
*
|
||||
|
@ -83,6 +82,49 @@ Pattern.prototype.addPart = function (part, resolveImmediately = true) {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the initialized configuration
|
||||
*
|
||||
* @return {object} config - The initialized config
|
||||
*/
|
||||
Pattern.prototype.getConfig = function () {
|
||||
return this.__init().config
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// Plugin and Hook Handling //
|
||||
//////////////////////////////
|
||||
|
||||
/**
|
||||
* Adds a lifecycle hook method to the pattern
|
||||
*
|
||||
* @param {string} hook - Name of the lifecycle hook
|
||||
* @param {function} method - The method to run
|
||||
* @param {object} data - Any data to pass to the hook method
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.on = function (hook, method, data) {
|
||||
this.plugins.on(hook, method, data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a plugin
|
||||
*
|
||||
* @param {object} plugin - The plugin to load
|
||||
* @param {object} data - Any data to pass to the plugin
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.use = function (plugin, data) {
|
||||
this.plugins.use(plugin, data, this.settings)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
//////////////
|
||||
// Drafting //
|
||||
//////////////
|
||||
/**
|
||||
* Drafts this pattern, aka the raison d'etre of FreeSewing
|
||||
*
|
||||
|
@ -100,14 +142,9 @@ Pattern.prototype.draftPartForSet = function (partName, set) {
|
|||
return new PatternDrafter(this).draftPartForSet(partName, set)
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the initialized configuration
|
||||
*
|
||||
* @return {object} config - The initialized config
|
||||
*/
|
||||
Pattern.prototype.getConfig = function () {
|
||||
return this.__init().config
|
||||
}
|
||||
///////////////
|
||||
// Rendering //
|
||||
///////////////
|
||||
|
||||
/**
|
||||
* Renders the pattern to SVG
|
||||
|
@ -127,13 +164,26 @@ Pattern.prototype.getRenderProps = function () {
|
|||
return new PatternRenderer(this).getRenderProps()
|
||||
}
|
||||
|
||||
//////////////
|
||||
// Sampling //
|
||||
//////////////
|
||||
|
||||
/**
|
||||
* Handles pattern sampling
|
||||
*
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.sample = function () {
|
||||
return new PatternSampler(this).sample()
|
||||
this.__init()
|
||||
const sampleSetting = this.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.draft()
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -163,50 +213,13 @@ Pattern.prototype.sampleOption = function (optionName) {
|
|||
return new PatternSampler(this).sampleOption(optionName)
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a lifecycle hook method to the pattern
|
||||
*
|
||||
* @param {string} hook - Name of the lifecycle hook
|
||||
* @param {function} method - The method to run
|
||||
* @param {object} data - Any data to pass to the hook method
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.on = function (hook, method, data) {
|
||||
this.plugins.on(hook, method, data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a plugin
|
||||
*
|
||||
* @param {object} plugin - The plugin to load
|
||||
* @param {object} data - Any data to pass to the plugin
|
||||
* @return {object} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.use = function (plugin, data) {
|
||||
this.plugins.use(plugin, data, this.settings)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////
|
||||
// PRIVATE METHODS //
|
||||
//////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Creates a store for a set (of settings)
|
||||
*
|
||||
* @private
|
||||
* @return {Store} store - A new store populated with relevant data/methods
|
||||
*/
|
||||
Pattern.prototype.__createSetStore = function () {
|
||||
const store = new Store()
|
||||
store.set('data', this.store.data)
|
||||
store.extend([...this.plugins.__storeMethods])
|
||||
|
||||
return store
|
||||
}
|
||||
///////////
|
||||
// Setup //
|
||||
///////////
|
||||
|
||||
/**
|
||||
* Merges (sets of) settings with the default settings
|
||||
|
@ -237,6 +250,20 @@ Pattern.prototype.__applySettings = function (sets) {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a store for a set (of settings)
|
||||
*
|
||||
* @private
|
||||
* @return {Store} store - A new store populated with relevant data/methods
|
||||
*/
|
||||
Pattern.prototype.__createSetStore = function () {
|
||||
const store = new Store()
|
||||
store.set('data', this.store.data)
|
||||
store.extend([...this.plugins.__storeMethods])
|
||||
|
||||
return store
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the pattern coniguration and settings
|
||||
*
|
||||
|
@ -258,67 +285,32 @@ Pattern.prototype.__init = function () {
|
|||
* so we need to do the things we used to do in the contructor at a later stage.
|
||||
* This methods does that, and resolves the design config + user settings
|
||||
*/
|
||||
this.__resolveParts() // Resolves parts
|
||||
.__resolveConfig() // Gets the config from the resolver
|
||||
.__loadConfigData() // Makes config data available in store
|
||||
.__loadOptionDefaults() // Merges default options with user provided ones
|
||||
// Resolve parts
|
||||
this.designConfig.parts.forEach((p) => this.__configResolver.addPart(p))
|
||||
|
||||
this.plugins.loadConfigPlugins(this.config, this.settings) // Loads plugins
|
||||
// Print final part distances.
|
||||
this.__configResolver.logPartDistances()
|
||||
|
||||
// get the config from the resolver
|
||||
this.config = this.__configResolver.asConfig()
|
||||
|
||||
// load resolved plugins
|
||||
this.plugins.loadConfigPlugins(this.config, this.settings)
|
||||
|
||||
// Make config data available in store
|
||||
if (this.designConfig.data) this.store.set('data', this.designConfig.data)
|
||||
|
||||
// Merges default options with user provided ones
|
||||
this.__loadOptionDefaults()
|
||||
|
||||
this.store.log.info(`Pattern initialized. Draft order is: ${this.config.draftOrder.join(', ')}`)
|
||||
|
||||
this.__runHooks('postInit')
|
||||
|
||||
this.__initialized = true
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a part is hidden in the config
|
||||
*
|
||||
* @private
|
||||
* @param {string} partName - Name of the part to check
|
||||
* @return {bool} hidden - true if the part is hidden, or false if not
|
||||
*/
|
||||
Pattern.prototype.__isPartHidden = function (partName) {
|
||||
const partHidden = this.parts?.[this.activeSet]?.[partName]?.hidden || false
|
||||
if (Array.isArray(this.settings[this.activeSet || 0].only)) {
|
||||
if (this.settings[this.activeSet || 0].only.includes(partName)) return partHidden
|
||||
}
|
||||
if (this.config.partHide?.[partName]) return true
|
||||
|
||||
return partHidden
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a stack is hidden in the config
|
||||
*
|
||||
* @private
|
||||
* @param {string} stackName - Name of the stack to check
|
||||
* @return {bool} hidden - true if the part is hidden, or false if not
|
||||
*/
|
||||
Pattern.prototype.__isStackHidden = function (stackName) {
|
||||
if (!this.stacks[stackName]) return true
|
||||
const parts = this.stacks[stackName].getPartNames()
|
||||
for (const partName of parts) {
|
||||
if (!this.__isPartHidden(partName)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads data from the design config into the store
|
||||
*
|
||||
* @private
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.__loadConfigData = function () {
|
||||
if (this.designConfig.data) this.store.set('data', this.designConfig.data)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges defaults for options with user-provided options
|
||||
*
|
||||
|
@ -353,6 +345,67 @@ Pattern.prototype.__loadOptionDefaults = function () {
|
|||
return this
|
||||
}
|
||||
|
||||
///////////
|
||||
// Hooks //
|
||||
///////////
|
||||
|
||||
/**
|
||||
* Runs subscriptions to a given lifecycle hook
|
||||
*
|
||||
* @private
|
||||
* @param {string} hookName - Name of the lifecycle hook
|
||||
* @param {obhect} data - Any data to pass to the hook method
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.__runHooks = function (hookName, data = false) {
|
||||
if (data === false) data = this
|
||||
let hooks = this.plugins.hooks[hookName]
|
||||
if (hooks.length > 0) {
|
||||
this.store.log.debug(`Running \`${hookName}\` hooks`)
|
||||
for (let hook of hooks) {
|
||||
hook.method(data, hook.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////
|
||||
// Config Evaluation //
|
||||
///////////////////////
|
||||
|
||||
/**
|
||||
* Checks whether a part is hidden in the config
|
||||
*
|
||||
* @private
|
||||
* @param {string} partName - Name of the part to check
|
||||
* @return {bool} hidden - true if the part is hidden, or false if not
|
||||
*/
|
||||
Pattern.prototype.__isPartHidden = function (partName) {
|
||||
const partHidden = this.parts?.[this.activeSet]?.[partName]?.hidden || false
|
||||
if (Array.isArray(this.settings[this.activeSet || 0].only)) {
|
||||
if (this.settings[this.activeSet || 0].only.includes(partName)) return partHidden
|
||||
}
|
||||
if (this.config.partHide?.[partName]) return true
|
||||
|
||||
return partHidden
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a stack is hidden in the config
|
||||
*
|
||||
* @private
|
||||
* @param {string} stackName - Name of the stack to check
|
||||
* @return {bool} hidden - true if the part is hidden, or false if not
|
||||
*/
|
||||
Pattern.prototype.__isStackHidden = function (stackName) {
|
||||
if (!this.stacks[stackName]) return true
|
||||
const parts = this.stacks[stackName].getPartNames()
|
||||
for (const partName of parts) {
|
||||
if (!this.__isPartHidden(partName)) return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a part is needed, depending on the 'only' setting and the configured dependencies
|
||||
*
|
||||
|
@ -385,50 +438,6 @@ Pattern.prototype.__needs = function (partName, set = 0) {
|
|||
return false
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the configuration for the config resolver and sets it on the pattern
|
||||
* @private
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.__resolveConfig = function () {
|
||||
this.config = this.__configResolver.asConfig()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves parts and their dependencies
|
||||
*
|
||||
* @private
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.__resolveParts = function () {
|
||||
this.designConfig.parts.forEach((p) => this.__configResolver.addPart(p))
|
||||
|
||||
// Print final part distances.
|
||||
this.__configResolver.logPartDistances()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs subscriptions to a given lifecycle hook
|
||||
*
|
||||
* @private
|
||||
* @param {string} hookName - Name of the lifecycle hook
|
||||
* @param {obhect} data - Any data to pass to the hook method
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
Pattern.prototype.__runHooks = function (hookName, data = false) {
|
||||
if (data === false) data = this
|
||||
let hooks = this.plugins.hooks[hookName]
|
||||
if (hooks.length > 0) {
|
||||
this.store.log.debug(`Running \`${hookName}\` hooks`)
|
||||
for (let hook of hooks) {
|
||||
hook.method(data, hook.data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a part is wanted, depending on the 'only' setting and the configured dependencies
|
||||
*
|
||||
|
|
|
@ -66,7 +66,7 @@ export function PatternConfig(pattern) {
|
|||
const DISTANCE_DEBUG = false
|
||||
|
||||
////////////////////
|
||||
// PUBLIC METHODs //
|
||||
// PUBLIC METHODS //
|
||||
////////////////////
|
||||
|
||||
/**
|
||||
|
|
|
@ -121,11 +121,39 @@ PatternDrafter.prototype.__createPartForSet = function (partName, set = 0) {
|
|||
}
|
||||
}
|
||||
|
||||
PatternDrafter.prototype.__useSet = function (set = 0) {
|
||||
this.activeSet = set
|
||||
this.activeSettings = this.pattern.settings[set]
|
||||
this.activeStore = this.pattern.setStores[set]
|
||||
/**
|
||||
* Instantiates a new Part instance and populates it with the pattern context
|
||||
*
|
||||
* @private
|
||||
* @param {string} name - The name of the part
|
||||
* @param {int} set - The index of the settings set in the list of sets
|
||||
* @return {Part} part - The instantiated Part
|
||||
*/
|
||||
PatternDrafter.prototype.__createPartWithContext = function (name, set) {
|
||||
// Context object to add to Part closure
|
||||
const part = new Part()
|
||||
part.name = name
|
||||
part.set = set
|
||||
part.stack = this.pattern.config.parts[name]?.stack || name
|
||||
part.context = {
|
||||
parts: this.pattern.parts[set],
|
||||
config: this.pattern.config,
|
||||
settings: this.pattern.settings[set],
|
||||
store: this.pattern.setStores[set],
|
||||
macros: this.pattern.plugins.macros,
|
||||
}
|
||||
|
||||
if (this.pattern.settings[set]?.partClasses) {
|
||||
part.attr('class', this.pattern.settings[set].partClasses)
|
||||
}
|
||||
|
||||
for (const macro in this.pattern.plugins.macros) {
|
||||
part[__macroName(macro)] = this.pattern.plugins.macros[macro]
|
||||
}
|
||||
|
||||
return part
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an array of settings.absoluteOptions objects for sampling a list option
|
||||
*
|
||||
|
@ -193,35 +221,8 @@ PatternDrafter.prototype.__snappedPercentageOption = function (optionName, set)
|
|||
return abs
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiates a new Part instance and populates it with the pattern context
|
||||
*
|
||||
* @private
|
||||
* @param {string} name - The name of the part
|
||||
* @param {int} set - The index of the settings set in the list of sets
|
||||
* @return {Part} part - The instantiated Part
|
||||
*/
|
||||
PatternDrafter.prototype.__createPartWithContext = function (name, set) {
|
||||
// Context object to add to Part closure
|
||||
const part = new Part()
|
||||
part.name = name
|
||||
part.set = set
|
||||
part.stack = this.pattern.config.parts[name]?.stack || name
|
||||
part.context = {
|
||||
parts: this.pattern.parts[set],
|
||||
config: this.pattern.config,
|
||||
settings: this.pattern.settings[set],
|
||||
store: this.pattern.setStores[set],
|
||||
macros: this.pattern.plugins.macros,
|
||||
}
|
||||
|
||||
if (this.pattern.settings[set]?.partClasses) {
|
||||
part.attr('class', this.pattern.settings[set].partClasses)
|
||||
}
|
||||
|
||||
for (const macro in this.pattern.plugins.macros) {
|
||||
part[__macroName(macro)] = this.pattern.plugins.macros[macro]
|
||||
}
|
||||
|
||||
return part
|
||||
PatternDrafter.prototype.__useSet = function (set = 0) {
|
||||
this.activeSet = set
|
||||
this.activeSettings = this.pattern.settings[set]
|
||||
this.activeStore = this.pattern.setStores[set]
|
||||
}
|
||||
|
|
|
@ -2,19 +2,6 @@ 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
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue