Merge branch 'develop' into annotations
This commit is contained in:
commit
b33a739f54
1392 changed files with 11722 additions and 8413 deletions
|
@ -7,6 +7,7 @@ import { Point } from './point.mjs'
|
|||
import { Path } from './path.mjs'
|
||||
import { Snippet } from './snippet.mjs'
|
||||
import { Store } from './store.mjs'
|
||||
import { hidePresets } from './pattern-config.mjs'
|
||||
import {
|
||||
beamIntersectsCircle,
|
||||
beamIntersectsX,
|
||||
|
@ -47,6 +48,8 @@ export {
|
|||
Store,
|
||||
version,
|
||||
Bezier,
|
||||
//consts
|
||||
hidePresets,
|
||||
// Utils
|
||||
beamIntersectsCircle,
|
||||
beamIntersectsX,
|
||||
|
|
|
@ -135,15 +135,6 @@ Part.prototype.shorthand = function () {
|
|||
utils: utils,
|
||||
Bezier: Bezier,
|
||||
}
|
||||
// Add top-level store methods and add a part name parameter
|
||||
const partName = this.name
|
||||
for (const [key, method] of Object.entries(this.context.store)) {
|
||||
if (typeof method === 'function')
|
||||
shorthand[key] = function (...args) {
|
||||
return method(partName, ...args)
|
||||
}
|
||||
}
|
||||
|
||||
// We'll need this
|
||||
let self = this
|
||||
|
||||
|
|
|
@ -192,7 +192,8 @@ Path.prototype.clean = function () {
|
|||
|
||||
if (ops.length < this.ops.length) this.ops = ops
|
||||
|
||||
return this
|
||||
// A path with not drawing operations or only a move is not path at all
|
||||
return ops.length === 0 || (ops.length === 1 && ops[0].type === 'move') ? false : this
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1310,7 +1311,10 @@ function __pathOffset(path, distance) {
|
|||
{ x: cp2.x, y: cp2.y },
|
||||
{ x: op.to.x, y: op.to.y }
|
||||
)
|
||||
for (let bezier of b.offset(distance)) offset.push(__asPath(bezier, path.log))
|
||||
for (let bezier of b.offset(distance)) {
|
||||
const segment = __asPath(bezier, path.log)
|
||||
if (segment) offset.push(segment)
|
||||
}
|
||||
} else if (op.type === 'close') closed = true
|
||||
if (op.to) current = op.to
|
||||
if (!start) start = current
|
||||
|
|
|
@ -1,5 +1,18 @@
|
|||
import { __addNonEnumProp } from './utils.mjs'
|
||||
|
||||
export const hidePresets = {
|
||||
HIDE_ALL: {
|
||||
self: true,
|
||||
from: true,
|
||||
after: true,
|
||||
inherited: true,
|
||||
},
|
||||
HIDE_TREE: {
|
||||
from: true,
|
||||
inherited: true,
|
||||
},
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the name of the given plugin config
|
||||
*
|
||||
|
@ -46,12 +59,16 @@ export function PatternConfig(pattern) {
|
|||
__addNonEnumProp(this, '__mutated', {
|
||||
optionDistance: {},
|
||||
partDistance: {},
|
||||
hideDistance: {},
|
||||
})
|
||||
|
||||
/** @type {Object} tracking for dependency hiding */
|
||||
__addNonEnumProp(this, '__hiding', {
|
||||
all: {},
|
||||
deps: {},
|
||||
from: {},
|
||||
after: {},
|
||||
inherited: {},
|
||||
always: {},
|
||||
never: {},
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -133,14 +150,15 @@ PatternConfig.prototype.asConfig = function () {
|
|||
PatternConfig.prototype.__addPart = function (depChain) {
|
||||
// the current part is the head of the chain
|
||||
const part = depChain[0]
|
||||
// the longer the chain, the deeper the part is down it
|
||||
const distance = depChain.length
|
||||
|
||||
// only process a part that hasn't already been processed
|
||||
if (!this.parts[part.name]) this.parts[part.name] = Object.freeze(part)
|
||||
else return
|
||||
|
||||
// if it hasn't been registered with a distance, do that now
|
||||
if (typeof this.__mutated.partDistance[part.name] === 'undefined') {
|
||||
this.__mutated.partDistance[part.name] = distance
|
||||
// the longer the chain, the deeper the part is down it
|
||||
this.__mutated.partDistance[part.name] = depChain.length
|
||||
|
||||
if (DISTANCE_DEBUG)
|
||||
this.store.log.debug(
|
||||
|
@ -149,11 +167,7 @@ PatternConfig.prototype.__addPart = function (depChain) {
|
|||
}
|
||||
|
||||
// Handle various hiding possibilities
|
||||
if (part.hide || part.hideAll) this.partHide[part.name] = true
|
||||
if (part.hideDependencies) this.__hiding.deps[part.name] = true
|
||||
if (part.hideAll) {
|
||||
this.__hiding.all[part.name] = true
|
||||
}
|
||||
this.__resolvePartHiding(part)
|
||||
|
||||
// resolve its dependencies
|
||||
this.__resolvePartDependencies(depChain)
|
||||
|
@ -188,7 +202,7 @@ PatternConfig.prototype.__addPartOptions = function (part) {
|
|||
if (!part.options) return this
|
||||
|
||||
// get the part's option priority
|
||||
const partDistance = this.__mutated.partDistance?.[part.name] || 0
|
||||
const partDistance = this.__mutated.partDistance?.[part.name]
|
||||
|
||||
// loop through options
|
||||
for (const optionName in part.options) {
|
||||
|
@ -325,7 +339,60 @@ PatternConfig.prototype.__addPartPlugins = function (part) {
|
|||
|
||||
// the two types of dependencies
|
||||
const depTypes = ['from', 'after']
|
||||
// the two lists of special istructions
|
||||
const exceptionTypes = ['never', 'always']
|
||||
/**
|
||||
* Resolve the hiding configuration of this part
|
||||
* This method does not hide dependencies,
|
||||
* but it does hide or unhide parts listed in `never` and `always` in the config
|
||||
* according to this part's options priority
|
||||
* @param {Part} part the part whose config should be resolved
|
||||
* @private
|
||||
*/
|
||||
PatternConfig.prototype.__resolvePartHiding = function (part) {
|
||||
// get the config
|
||||
let hide = part.hide
|
||||
// if it's a string, get the preset by that name
|
||||
if (typeof hide === 'string') hide = hidePresets[hide]
|
||||
// no config, nothing to do
|
||||
if (!hide) return
|
||||
|
||||
// get the part's option priority
|
||||
const partDistance = this.__mutated.partDistance?.[part.name]
|
||||
// get the current distances that dictate if this part should never or always be hidden
|
||||
const neverDistance = this.__hiding.never[part.name] || Infinity
|
||||
const alwaysDistance = this.__hiding.always[part.name] || Infinity
|
||||
|
||||
// if the part is configured to hide, and it takes priority over other instructions, hide it
|
||||
if (hide.self && (neverDistance > partDistance || alwaysDistance <= neverDistance))
|
||||
this.partHide[part.name] = true
|
||||
|
||||
// for each exception list, starting with never
|
||||
exceptionTypes.forEach((e, i) => {
|
||||
// if there are instructions for this list
|
||||
if (hide[e]) {
|
||||
// each part in the list
|
||||
hide[e].forEach((p) => {
|
||||
// get the current distance of a call to never or always hide this part
|
||||
const otherDistance = this.__hiding[exceptionTypes[Math.abs(i - 1)]][p] || Infinity
|
||||
|
||||
// if a current command is less important than this one,
|
||||
if (otherDistance > partDistance) {
|
||||
const thisDistance = this.__hiding[e][p] || Infinity
|
||||
// record the new priority
|
||||
this.__hiding[e][p] = Math.min(thisDistance, partDistance)
|
||||
// hide or show the part
|
||||
this.partHide[p] = i == 1
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
// add the dependency hiding instructions if they haven't already been set
|
||||
depTypes.concat('inherited').forEach((k) => {
|
||||
if (this.__hiding[k][part.name] === undefined) this.__hiding[k][part.name] = hide[k]
|
||||
})
|
||||
}
|
||||
/**
|
||||
* Recursively register part dependencies
|
||||
* triggers {@link __addPart} on new parts found during resolution
|
||||
|
@ -364,9 +431,11 @@ PatternConfig.prototype.__resolvePartDependencies = function (depChain) {
|
|||
this.__addPart([dot, ...depChain])
|
||||
} else {
|
||||
// if it's already registered, recursion won't happen, but we still need to add its resolved dependencies to all parts in the chain
|
||||
this.resolvedDependencies[dot.name].forEach((r) => {
|
||||
depChain.forEach((c) => this.__addDependency('resolvedDependencies', c.name, r))
|
||||
})
|
||||
// this.resolvedDependencies[dot.name].forEach((r) => {
|
||||
// depChain.forEach((c) => this.__resolvePartDependencies('resolvedDependencies', c.name, r))
|
||||
// })
|
||||
this.__resolvePartDependencies([dot, ...depChain])
|
||||
// and check for stricter hiding policies
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -399,14 +468,24 @@ PatternConfig.prototype.__addDependency = function (dependencyList, partName, de
|
|||
* @private
|
||||
*/
|
||||
PatternConfig.prototype.__handlePartDependencyOfType = function (part, depName, depType) {
|
||||
switch (depType) {
|
||||
case 'from':
|
||||
this.__setFromHide(part, depName)
|
||||
this.inject[part.name] = depName
|
||||
break
|
||||
case 'after':
|
||||
this.__setAfterHide(part, depName)
|
||||
// if this dependency should be hidden based on dependency type, and doesn't already have an instruction, hide it
|
||||
if (this.__hiding[depType][part.name] === true && this.partHide[depName] === undefined) {
|
||||
this.partHide[depName] = true
|
||||
}
|
||||
|
||||
// get the part's inherited hide instructions
|
||||
const hideInherited = this.__hiding.inherited[part.name]
|
||||
// for from dependencies
|
||||
if (depType === 'from') {
|
||||
// inject the dependency into the part
|
||||
this.inject[part.name] = depName
|
||||
// hide after dependencies if inherited dependencies should hide
|
||||
this.__hiding.after[depName] = hideInherited
|
||||
}
|
||||
|
||||
// for all depependency types, from and inherited are dictated by the dependendent part's policy
|
||||
this.__hiding.from[depName] = hideInherited
|
||||
this.__hiding.inherited[depName] = hideInherited
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -455,42 +534,3 @@ PatternConfig.prototype.__resolveDraftOrder = function () {
|
|||
|
||||
return this.__draftOrder
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility of a 'from' dependency based on its config
|
||||
*
|
||||
* @private
|
||||
* @param {Part} part - The part of which this is a dependency
|
||||
* @param {string} depName - The name of the dependency
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
PatternConfig.prototype.__setFromHide = function (part, depName) {
|
||||
if (this.__hiding.deps[part.name]) {
|
||||
this.partHide[depName] = true
|
||||
this.__hiding.deps[depName] = true
|
||||
}
|
||||
if (this.__hiding.all[part.name]) {
|
||||
this.partHide[depName] = true
|
||||
this.__hiding.all[depName] = true
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets visibility of an 'after' dependency based on its config
|
||||
*
|
||||
* @private
|
||||
* @param {Part} part - The part of which this is a dependency
|
||||
* @param {string} depName - The name of the dependency
|
||||
* @param {int} set - The index of the set in the list of settings
|
||||
* @return {Pattern} this - The Pattern instance
|
||||
*/
|
||||
PatternConfig.prototype.__setAfterHide = function (part, depName) {
|
||||
if (this.__hiding.all[part.name]) {
|
||||
this.partHide[depName] = true
|
||||
this.__hiding.all[depName] = true
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
|
|
@ -160,9 +160,13 @@ Pattern.prototype.createPartForSet = function (partName, set = 0) {
|
|||
Pattern.prototype.draftPartForSet = function (partName, set) {
|
||||
if (typeof this.config.parts?.[partName]?.draft === 'function') {
|
||||
this.activePart = partName
|
||||
this.setStores[set].set('activePart', partName)
|
||||
try {
|
||||
this.__runHooks('prePartDraft')
|
||||
const result = this.config.parts[partName].draft(this.parts[set][partName].shorthand())
|
||||
if (!this.__wants(partName, set)) {
|
||||
result.hide()
|
||||
}
|
||||
this.__runHooks('postPartDraft')
|
||||
if (typeof result === 'undefined') {
|
||||
this.setStores[set].log.error(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue