1
0
Fork 0

Merge branch 'develop' into annotations

This commit is contained in:
joostdecock 2023-04-15 15:47:00 +02:00
commit b33a739f54
1392 changed files with 11722 additions and 8413 deletions

View file

@ -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,

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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(