From 83addc08798e9056aad46ca8d1580beabf0401e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C3=A1n=20D=C3=A9nes?= Date: Fri, 1 Jan 2021 21:46:01 +0100 Subject: [PATCH] Unit refactor done --- src/anchor.js | 6 +++--- src/cases.js | 23 +++++++++++------------ src/cli.js | 20 ++++++++++---------- src/ergogen.js | 28 ++++++++++++++-------------- src/outlines.js | 2 +- src/pcbs.js | 36 +++++++++++++++++------------------- src/prepare.js | 5 +++-- src/utils.js | 5 ++++- 8 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/anchor.js b/src/anchor.js index bc965bb..7a75a95 100644 --- a/src/anchor.js +++ b/src/anchor.js @@ -3,7 +3,7 @@ const a = require('./assert') const Point = require('./point') const anchor = module.exports = (raw, name, points={}, check_unexpected=true, default_point=new Point()) => units => { - if (a.type(raw) == 'array') { + if (a.type(raw)() == 'array') { // recursive call with incremental default_point mods, according to `affect`s let current = () => default_point.clone() for (const step of raw) { @@ -14,7 +14,7 @@ const anchor = module.exports = (raw, name, points={}, check_unexpected=true, de if (check_unexpected) a.detect_unexpected(raw, name, ['ref', 'orient', 'shift', 'rotate', 'affect']) let point = default_point.clone() if (raw.ref !== undefined) { - if (a.type(raw.ref) == 'array') { + if (a.type(raw.ref)() == 'array') { // averaging multiple anchors let x = 0, y = 0, r = 0 const len = raw.ref.length @@ -49,7 +49,7 @@ const anchor = module.exports = (raw, name, points={}, check_unexpected=true, de point = default_point.clone() const valid_affects = ['x', 'y', 'r'] let affect = raw.affect || valid_affects - if (a.type(affect) == 'string') affect = affect.split('') + if (a.type(affect)() == 'string') affect = affect.split('') affect = a.strarr(affect, `${name}.affect`) let i = 0 for (const a of affect) { diff --git a/src/cases.js b/src/cases.js index 2cec9f4..5a96157 100644 --- a/src/cases.js +++ b/src/cases.js @@ -1,10 +1,10 @@ const m = require('makerjs') -const u = require('./utils') const a = require('./assert') +const o = require('./operation') -exports.parse = (config, outlines) => { +exports.parse = (config, outlines, units) => { - const cases_config = a.sane(config, 'cases', 'object') + const cases_config = a.sane(config, 'cases', 'object')() const scripts = {} const cases = {} @@ -39,19 +39,18 @@ exports.parse = (config, outlines) => { for (let [case_name, case_config] of Object.entries(cases_config)) { // config sanitization - case_config = a.inherit('cases', case_name, cases_config) - if (a.type(case_config) == 'array') { + if (a.type(case_config)() == 'array') { case_config = {...case_config} } - const parts = a.sane(case_config, `cases.${case_name}`, 'object') + const parts = a.sane(case_config, `cases.${case_name}`, 'object')() const body = [] const case_dependencies = [] const outline_dependencies = [] let first = true for (let [part_name, part] of Object.entries(parts)) { - if (a.type(part) == 'string') { - part = a.op_str(part, { + if (a.type(part)() == 'string') { + part = o.operation(part, { outline: Object.keys(outlines), case: Object.keys(cases) }, ['case', 'outline']) @@ -60,14 +59,14 @@ exports.parse = (config, outlines) => { const part_var = `${case_name}__part_${part_name}` a.detect_unexpected(part, part_qname, ['type', 'name', 'extrude', 'shift', 'rotate', 'operation']) const type = a.in(part.type || 'outline', `${part_qname}.type`, ['outline', 'case']) - const name = a.sane(part.name, `${part_qname}.name`, 'string') - const shift = a.numarr(part.shift || [0, 0, 0], `${part_qname}.shift`, 3) - const rotate = a.numarr(part.rotate || [0, 0, 0], `${part_qname}.rotate`, 3) + const name = a.sane(part.name, `${part_qname}.name`, 'string')() + const shift = a.numarr(part.shift || [0, 0, 0], `${part_qname}.shift`, 3)(units) + const rotate = a.numarr(part.rotate || [0, 0, 0], `${part_qname}.rotate`, 3)(units) const operation = a.in(part.operation || 'add', `${part_qname}.operation`, ['add', 'subtract', 'intersect']) let base if (type == 'outline') { - const extrude = a.sane(part.extrude || 1, `${part_qname}.extrude`, 'number') + const extrude = a.sane(part.extrude || 1, `${part_qname}.extrude`, 'number')(units) const outline = outlines[name] a.assert(outline, `Field "${part_qname}.name" does not name a valid outline!`) if (!scripts[name]) { diff --git a/src/cli.js b/src/cli.js index c9b481d..3cfc6d7 100644 --- a/src/cli.js +++ b/src/cli.js @@ -78,17 +78,17 @@ for (const [name, outline] of Object.entries(results.outlines)) { io.dump_model(outline, path.join(args.o, `outlines/${name}`), args.debug) } -// for (const [name, pcb] of Object.entries(results.pcbs)) { -// const file = path.join(args.o, `pcbs/${name}.kicad_pcb`) -// fs.mkdirpSync(path.dirname(file)) -// fs.writeFileSync(file, pcb) -// } +for (const [name, _case] of Object.entries(results.cases)) { + const file = path.join(args.o, `cases/${name}.jscad`) + fs.mkdirpSync(path.dirname(file)) + fs.writeFileSync(file, _case) +} -// for (const [name, _case] of Object.entries(results.cases)) { -// const file = path.join(args.o, `cases/${name}.jscad`) -// fs.mkdirpSync(path.dirname(file)) -// fs.writeFileSync(file, _case) -// } +for (const [name, pcb] of Object.entries(results.pcbs)) { + const file = path.join(args.o, `pcbs/${name}.kicad_pcb`) + fs.mkdirpSync(path.dirname(file)) + fs.writeFileSync(file, pcb) +} if (args.debug) { fs.writeJSONSync(path.join(args.o, 'results.json'), results, {spaces: 4}) diff --git a/src/ergogen.js b/src/ergogen.js index 4c0cff5..09479a7 100644 --- a/src/ergogen.js +++ b/src/ergogen.js @@ -33,21 +33,21 @@ module.exports = { results.outlines[name] = outline } - // logger('Extruding cases...') - // const cases = cases_lib.parse(config.cases || {}, outlines, units) - // results.cases = {} - // for (const [case_name, case_text] of Object.entries(cases)) { - // if (!debug && case_name.startsWith('_')) continue - // results.cases[case_name] = case_text - // } + logger('Extruding cases...') + const cases = cases_lib.parse(config.cases || {}, outlines, units) + results.cases = {} + for (const [case_name, case_text] of Object.entries(cases)) { + if (!debug && case_name.startsWith('_')) continue + results.cases[case_name] = case_text + } - // logger('Scaffolding PCBs...') - // const pcbs = pcbs_lib.parse(config.pcbs || {}, points, outlines, units) - // results.pcbs = {} - // for (const [pcb_name, pcb_text] of Object.entries(pcbs)) { - // if (!debug && pcb_name.startsWith('_')) continue - // results.cases[pcb_name] = pcb_text - // } + logger('Scaffolding PCBs...') + const pcbs = pcbs_lib.parse(config.pcbs || {}, points, outlines, units) + results.pcbs = {} + for (const [pcb_name, pcb_text] of Object.entries(pcbs)) { + if (!debug && pcb_name.startsWith('_')) continue + results.pcbs[pcb_name] = pcb_text + } return results } diff --git a/src/outlines.js b/src/outlines.js index b09ce09..8de3920 100644 --- a/src/outlines.js +++ b/src/outlines.js @@ -244,7 +244,7 @@ exports.parse = (config = {}, points = {}, units = {}) => { sx: size[0], sy: size[1] }, units) - anchor = a.anchor(part, name, points, false)(rec_units) + anchor = make_anchor(part, name, points, false)(rec_units) const corner = a.sane(part.corner || 0, `${name}.corner`, 'number')(rec_units) const bevel = a.sane(part.bevel || 0, `${name}.bevel`, 'number')(rec_units) const rect_mirror = a.sane(part.mirror || false, `${name}.mirror`, 'boolean')() diff --git a/src/pcbs.js b/src/pcbs.js index b1506bb..15eab05 100644 --- a/src/pcbs.js +++ b/src/pcbs.js @@ -1,8 +1,6 @@ const m = require('makerjs') -const u = require('./utils') const a = require('./assert') - -const Point = require('./point') +const make_anchor = require('./anchor') const kicad_prefix = ` (kicad_pcb (version 20171130) (host pcbnew 5.1.6) @@ -145,16 +143,16 @@ const makerjs2kicad = exports._makerjs2kicad = (model, layer='Edge.Cuts') => { } const footprint_types = require('./footprints') -const footprint = exports._footprint = (config, name, points, point, net_indexer, component_indexer) => { +const footprint = exports._footprint = (config, name, points, point, net_indexer, component_indexer, units) => { if (config === false) return '' // config sanitization a.detect_unexpected(config, name, ['type', 'anchor', 'nets', 'params']) const type = a.in(config.type, `${name}.type`, Object.keys(footprint_types)) - let anchor = a.anchor(config.anchor || {}, `${name}.anchor`, points, true, point) - const nets = a.sane(config.nets || {}, `${name}.nets`, 'object') - const params = a.sane(config.params || {}, `${name}.params`, 'object') + let anchor = make_anchor(config.anchor || {}, `${name}.anchor`, points, true, point)(units) + const nets = a.sane(config.nets || {}, `${name}.nets`, 'object')() + const params = a.sane(config.params || {}, `${name}.params`, 'object')() // basic setup const fp = footprint_types[type] @@ -174,11 +172,11 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer // connecting parametric nets for (const net_ref of (fp.nets || [])) { let net = nets[net_ref] - a.sane(net, `${name}.nets.${net_ref}`, 'string') + a.sane(net, `${name}.nets.${net_ref}`, 'string')() if (net.startsWith('!') && point) { const indirect = net.substring(1) net = point.meta[indirect] - a.sane(net, `${name}.nets.${net_ref} --> ${point.meta.name}.${indirect}`, 'string') + a.sane(net, `${name}.nets.${net_ref} --> ${point.meta.name}.${indirect}`, 'string')() } const index = net_indexer(net) parsed_params.net[net_ref] = `(net ${index} "${net}")` @@ -189,7 +187,7 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer for (const param of (Object.keys(fp.params || {}))) { let value = params[param] === undefined ? fp.params[param] : params[param] if (value === undefined) throw new Error(`Field "${name}.params.${param}" is missing!`) - if (a.type(value) == 'string' && value.startsWith('!') && point) { + if (a.type(value)() == 'string' && value.startsWith('!') && point) { const indirect = value.substring(1) value = point.meta[indirect] if (value === undefined) throw new Error(`Field "${name}.params.${param} --> ${point.meta.name}.${indirect}" is missing!`) @@ -204,9 +202,9 @@ const footprint = exports._footprint = (config, name, points, point, net_indexer return fp.body(parsed_params) } -exports.parse = (config, points, outlines) => { +exports.parse = (config, points, outlines, units) => { - const pcbs = a.sane(config || {}, 'pcbs', 'object') + const pcbs = a.sane(config || {}, 'pcbs', 'object')() const results = {} for (const [pcb_name, pcb_config] of Object.entries(pcbs)) { @@ -215,14 +213,14 @@ exports.parse = (config, points, outlines) => { a.detect_unexpected(pcb_config, `pcbs.${pcb_name}`, ['outlines', 'footprints']) // outline conversion - if (a.type(pcb_config.outlines) == 'array') { + if (a.type(pcb_config.outlines)() == 'array') { pcb_config.outlines = {...pcb_config.outlines} } - const config_outlines = a.sane(pcb_config.outlines || {}, `pcbs.${pcb_name}.outlines`, 'object') + const config_outlines = a.sane(pcb_config.outlines || {}, `pcbs.${pcb_name}.outlines`, 'object')() const kicad_outlines = {} for (const [outline_name, outline] of Object.entries(config_outlines)) { const ref = a.in(outline.outline, `pcbs.${pcb_name}.outlines.${outline_name}.outline`, Object.keys(outlines)) - const layer = a.sane(outline.layer || 'Edge.Cuts', `pcbs.${pcb_name}.outlines.${outline_name}.outline`, 'string') + const layer = a.sane(outline.layer || 'Edge.Cuts', `pcbs.${pcb_name}.outlines.${outline_name}.outline`, 'string')() kicad_outlines[outline_name] = makerjs2kicad(outlines[ref], layer) } @@ -248,17 +246,17 @@ exports.parse = (config, points, outlines) => { // key-level footprints for (const [p_name, point] of Object.entries(points)) { for (const [f_name, f] of Object.entries(point.meta.footprints || {})) { - footprints.push(footprint(f, `${p_name}.footprints.${f_name}`, points, point, net_indexer, component_indexer)) + footprints.push(footprint(f, `${p_name}.footprints.${f_name}`, points, point, net_indexer, component_indexer, units)) } } // global one-off footprints - if (a.type(pcb_config.footprints) == 'array') { + if (a.type(pcb_config.footprints)() == 'array') { pcb_config.footprints = {...pcb_config.footprints} } - const global_footprints = a.sane(pcb_config.footprints || {}, `pcbs.${pcb_name}.footprints`, 'object') + const global_footprints = a.sane(pcb_config.footprints || {}, `pcbs.${pcb_name}.footprints`, 'object')() for (const [gf_name, gf] of Object.entries(global_footprints)) { - footprints.push(footprint(gf, `pcbs.${pcb_name}.footprints.${gf_name}`, points, undefined, net_indexer, component_indexer)) + footprints.push(footprint(gf, `pcbs.${pcb_name}.footprints.${gf_name}`, points, undefined, net_indexer, component_indexer, units)) } // finalizing nets diff --git a/src/prepare.js b/src/prepare.js index 365914c..3f9937f 100644 --- a/src/prepare.js +++ b/src/prepare.js @@ -48,12 +48,13 @@ const _inherit = exports._inherit = (config, root, breadcrumbs) => { breadcrumbs.push(key) let newval = _inherit(val, root, breadcrumbs) if (newval && newval.extends !== undefined) { - let candidates = [newval.extends] + let candidates = u.deepcopy(newval.extends) + if (a.type(candidates)() !== 'array') candidates = [candidates] const list = [newval] while (candidates.length) { const path = candidates.shift() const other = u.deepcopy(u.deep(root, path)) - a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.${key}.extends") does not name a valid target!`) + a.assert(other, `"${path}" (reached from "${breadcrumbs.join('.')}.extends") does not name a valid inheritance target!`) let parents = other.extends || [] if (a.type(parents)() !== 'array') parents = [parents] candidates = candidates.concat(parents) diff --git a/src/utils.js b/src/utils.js index 58fb3c5..4955cf8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -1,6 +1,9 @@ const m = require('makerjs') -exports.deepcopy = (value) => JSON.parse(JSON.stringify(value)) +exports.deepcopy = value => { + if (value === undefined) return undefined + return JSON.parse(JSON.stringify(value)) +} const deep = exports.deep = (obj, key, val) => { const levels = key.split('.')