From 2aa7a5ff1b1abac1fc90b7587a2699d776938f09 Mon Sep 17 00:00:00 2001 From: Matt McKegg Date: Sat, 5 Aug 2017 10:10:34 +1200 Subject: [PATCH] update cwd on rename / duplicate --- lib/file-object.js | 11 ++--- lib/observ-audio-buffer.js | 65 ++++++++++++++-------------- lib/params/sample-trimmer.js | 61 +++----------------------- lib/session-recorder.js | 3 +- lib/wave-hook.js | 5 ++- lib/widgets/orderable.js | 3 +- nodes/audio-buffer/object.js | 19 ++++---- nodes/clip/object.js | 15 +++---- nodes/external-chunk/object.js | 17 ++++---- nodes/loop-grid/grid.js | 10 ++--- nodes/project/object.js | 9 ++-- nodes/setup/object.js | 17 +++----- nodes/triggers-chunk/slot-chooser.js | 5 ++- 13 files changed, 91 insertions(+), 149 deletions(-) diff --git a/lib/file-object.js b/lib/file-object.js index ad0f35fb..eefdddc5 100644 --- a/lib/file-object.js +++ b/lib/file-object.js @@ -1,9 +1,9 @@ var resolveNode = require('lib/resolve-node') var getDirName = require('path').dirname -var resolve = require('path').resolve -var relative = require('path').relative +var Path = require('path') +var resolve = require('mutant/resolve') var Observ = require('mutant/value') var Event = require('geval') var watch = require('mutant/watch') @@ -16,6 +16,7 @@ module.exports = FileObject function FileObject (parentContext) { var context = Object.create(parentContext) + context.cwd = Observ() var obs = Observ({}) var set = obs.set @@ -115,11 +116,11 @@ function FileObject (parentContext) { obs.resolved = Observ() obs.resolvePath = function (src) { - return resolve(context.cwd, src) + return Path.resolve(resolve(context.cwd), src) } obs.relative = function (path) { - var value = relative(context.cwd, path) + var value = Path.relative(resolve(context.cwd), path) if (/^\./.exec(value)) { return value } else { @@ -141,7 +142,7 @@ function FileObject (parentContext) { loading = true obs.file = ObservFile(path) releaseRename = watch(obs.file.path, obs.path.set) - context.cwd = getDirName(path) + context.cwd.set(getDirName(path)) releaseClose = obs.file.onClose(onClose) updateFile = JsonFile(obs.file, updateNode) } diff --git a/lib/observ-audio-buffer.js b/lib/observ-audio-buffer.js index 1b69972d..75d3f579 100644 --- a/lib/observ-audio-buffer.js +++ b/lib/observ-audio-buffer.js @@ -1,6 +1,7 @@ var Observ = require('mutant/value') var watch = require('mutant/watch') -var resolve = require('path').resolve +var computed = require('mutant/computed') +var Path = require('path') var ObservFile = require('lib/observ-file') module.exports = ObservAudioBuffer @@ -11,45 +12,42 @@ function ObservAudioBuffer (context) { obs.cuePoints = Observ() var releases = [] - var lastSrc = null - obs(function (data) { - if (lastSrc !== data.src) { - lastSrc = data.src - update(data.src) - } - }) + var src = computed(obs, descriptor => descriptor.src) + var path = computed([context.cwd, src], (a, b) => a && b && Path.resolve(a, b) || null) - function update (src) { - var path = resolve(context.cwd, src) - var timePath = path + '.time' + var unwatch = watch(path, (path) => { + if (path) { + var timePath = path + '.time' - while (releases.length) { - releases.pop()() - } - - context.fs.exists(path, function (exists) { - if (exists) { - var file = ObservFile(path, 'arraybuffer') - parseAudioBuffer(file, obs.currentValue.set, context.audio) - releases.push(file.close) - } else { - obs.currentValue.set(null) + while (releases.length) { + releases.pop()() } - }) - context.fs.exists(timePath, function (exists) { - if (exists) { - var file = ObservFile(timePath, 'arraybuffer') - parseFloat32Array(file, obs.cuePoints.set) - releases.push(file.close) - } else { - obs.cuePoints.set(null) - } - }) - } + context.fs.exists(path, function (exists) { + if (exists) { + var file = ObservFile(path, 'arraybuffer') + parseAudioBuffer(file, obs.currentValue.set, context.audio) + releases.push(file.close) + } else { + obs.currentValue.set(null) + } + }) + + context.fs.exists(timePath, function (exists) { + if (exists) { + var file = ObservFile(timePath, 'arraybuffer') + parseFloat32Array(file, obs.cuePoints.set) + releases.push(file.close) + } else { + obs.cuePoints.set(null) + } + }) + } + }) obs.destroy = function () { + unwatch() while (releases.length) { releases.pop()() } @@ -74,6 +72,7 @@ function parseAudioBuffer (obs, target, audioContext) { audioContext.decodeAudioData(data, function (audioBuffer) { target(audioBuffer) }, function (err) { + if (err) throw err target(null) }) } else { diff --git a/lib/params/sample-trimmer.js b/lib/params/sample-trimmer.js index 04042f92..e6d43ea7 100644 --- a/lib/params/sample-trimmer.js +++ b/lib/params/sample-trimmer.js @@ -2,6 +2,7 @@ var h = require('lib/h') var svg = require('lib/svg') var computed = require('mutant/computed') var watch = require('mutant/watch') +var resolve = require('mutant/watch') var QueryParam = require('lib/query-param') @@ -10,7 +11,6 @@ var DomEvent = require('lib/dom-event') var read = require('lib/read') var getValue = require('lib/get-value') -var importSample = require('lib/import-sample') var cancelEvent = require('lib/cancel-event') var WaveHook = require('./wave-hook.js') @@ -102,7 +102,10 @@ function slicesSvg (slices, width, height) { return svg('line', { stroke: 'rgba(0,0,0,0.4)', 'stroke-width': '3px', - x1: x, x2: x, y1: 0, y2: height + x1: x, + x2: x, + y1: 0, + y2: height }) }) } @@ -118,62 +121,13 @@ function dragStart (ev) { var data = read(this.data) || {} if (data.buffer && data.buffer.src) { ev.dataTransfer.setData('loop-drop/sample-path', this.data.context.fileObject.resolvePath(data.buffer.src)) - ev.dataTransfer.setData('cwd', this.data.context.cwd) + ev.dataTransfer.setData('cwd', resolve(this.data.context.cwd)) ev.dataTransfer.dropEffect = 'link' } else { ev.preventDefault() } } -function dragOver (ev) { - ev.stopPropagation() - var item = ev.dataTransfer.items[0] - if (item && item.kind === 'file' && item.type.match(/^(audio|video)\//)) { - ev.currentTarget.classList.add('-dragOver') - ev.dataTransfer.dropEffect = 'copy' - ev.preventDefault() - } else if (ev.dataTransfer.types.includes('loop-drop/sample-path')) { - ev.currentTarget.classList.add('-dragOver') - ev.dataTransfer.dropEffect = 'link' - ev.preventDefault() - } -} - -function dragLeave (ev) { - ev.currentTarget.classList.remove('-dragOver') -} - -function drop (ev) { - var node = this.data - var data = read(node) - var context = this.data.context - var item = ev.dataTransfer.items[0] - - ev.preventDefault() - dragLeave(ev) - - var currentPath = data.buffer && data.buffer.src && node.context.fileObject.resolvePath(data.buffer.src) || null - - var path = item.kind === 'file' - ? ev.dataTransfer.items[0].getAsFile().path - : ev.dataTransfer.getData('loop-drop/sample-path') - - if (path && path !== currentPath) { - importSample(context, path, function (err, descriptor) { - if (err) throw err - for (var k in descriptor) { - QueryParam(node, k).set(descriptor[k]) - } - }) - } - -} - -function getGainTransform(value){ - var offsetHeight = (((currentHeightScale*height) - height) / 2) / currentHeightScale - return 'scale(' + currentWidthScale + ' ' + currentHeightScale + ') translate(0 ' + -offsetHeight + ')' -} - function handleChange (event) { this.data.set(event.currentTarget.value) } @@ -186,9 +140,6 @@ function subtract (a, b) { return a - b } - -function noop(){} - function ValueHook (obs) { return function (element) { return watch(obs, function (value) { diff --git a/lib/session-recorder.js b/lib/session-recorder.js index 9c4e8857..90fdc90f 100644 --- a/lib/session-recorder.js +++ b/lib/session-recorder.js @@ -2,6 +2,7 @@ var watch = require('mutant/watch') var computed = require('mutant/computed') var Struct = require('mutant/struct') var Value = require('mutant/value') +var resolve = require('mutant/resolve') var join = require('path').join var strftime = require('strftime') var recordToDisk = require('lib/record-to-disk') @@ -26,7 +27,7 @@ function SessionRecorder (context, active) { // constant signal to ensure file has no gaps Silence(context.audio).connect(obs.input) - var recordingsPath = join(context.cwd, '~recordings') + var recordingsPath = join(resolve(context.cwd), '~recordings') mkdirp(recordingsPath, { fs: context.fs }) var isRecording = computed([obs.recording, active], (a, b) => a || b) diff --git a/lib/wave-hook.js b/lib/wave-hook.js index 9a2a803f..78a2c2b3 100644 --- a/lib/wave-hook.js +++ b/lib/wave-hook.js @@ -1,5 +1,6 @@ var WaveSvg = require('lib/wave-svg') -var resolve = require('path').resolve +var Path = require('path') +var resolve = require('mutant/resolve') module.exports = WaveHook @@ -7,7 +8,7 @@ var cache = {} function WaveHook (context, src) { return function (element) { - var path = resolve(context.cwd, src) + var path = Path.resolve(resolve(context.cwd), src) if (!cache[path]) { cache[path] = WaveSvg(path, context) } diff --git a/lib/widgets/orderable.js b/lib/widgets/orderable.js index 105a72cf..311e3e3f 100644 --- a/lib/widgets/orderable.js +++ b/lib/widgets/orderable.js @@ -1,5 +1,6 @@ var h = require('lib/h') var MPE = require('lib/mouse-position-event') +var resolve = require('mutant/resolve') module.exports = Orderable @@ -40,7 +41,7 @@ function dragStart (ev) { ev.ordering = true ev.node = ev.data ev.dataTransfer.setData('loop-drop/' + type, JSON.stringify(data)) - ev.dataTransfer.setData('cwd', ev.data.context.cwd) + ev.dataTransfer.setData('cwd', resolve(ev.data.context.cwd)) window.currentDrag = ev } diff --git a/nodes/audio-buffer/object.js b/nodes/audio-buffer/object.js index 56177138..4e97c23e 100644 --- a/nodes/audio-buffer/object.js +++ b/nodes/audio-buffer/object.js @@ -1,7 +1,8 @@ var Observ = require('mutant/value') var watch = require('mutant/watch') var ObservAudioBuffer = require('lib/observ-audio-buffer') -var resolve = require('path').resolve +var Path = require('path') +var computed = require('mutant/computed') module.exports = ObservAudioBufferCached @@ -19,16 +20,13 @@ function ObservAudioBufferCached (context) { } var release = null - var lastSrc = null + var src = computed(obs, descriptor => descriptor.src) + var path = computed([context.cwd, src], (a, b) => a && b && Path.resolve(a, b) || null) - obs(function (data) { - if (lastSrc !== data.src) { - lastSrc = data.src - update(data.src) - } - }) + var unwatch = watch(path, update) obs.destroy = function () { + unwatch() update(null) } @@ -36,12 +34,11 @@ function ObservAudioBufferCached (context) { // scoped - function update (src) { + function update (path) { release && release() release = null - if (src) { - var path = resolve(context.cwd, src) + if (path) { var instance = cache[path] if (!instance) { diff --git a/nodes/clip/object.js b/nodes/clip/object.js index 9bfd4c71..cfeba7dd 100644 --- a/nodes/clip/object.js +++ b/nodes/clip/object.js @@ -3,7 +3,7 @@ var Struct = require('mutant/struct') var Property = require('lib/property') var watch = require('mutant/watch') var resolve = require('mutant/resolve') -var resolvePath = require('path').resolve +var Path = require('path') var computed = require('mutant/computed') var pull = require('pull-stream') var toPcm = require('lib/to-pcm') @@ -58,11 +58,11 @@ function AudioTimelineClip (context) { obs.position = Property(0) - var lastPath = null - obs.src(function (value) { - // preload - var path = resolvePath(context.cwd, value) - if (path !== lastPath) { + var path = computed([context.cwd, obs.src], (a, b) => a && b && Path.resolve(a, b) || null) + var queue = [] + + watch(path, (path) => { + if (path) { loadingMeta = true refreshLoading() @@ -99,8 +99,6 @@ function AudioTimelineClip (context) { } }) - var queue = [] - var releaseScheduler = context.scheduler(function (schedule) { for (var i = queue.length - 1; i >= 0; i--) { var item = queue[i] @@ -117,7 +115,6 @@ function AudioTimelineClip (context) { obs.start = function (at, timeOffset, duration) { var time = at - var remaining = duration var cues = getCueList(timeOffset, duration) cues.forEach(cue => { queue.push({ diff --git a/nodes/external-chunk/object.js b/nodes/external-chunk/object.js index f2abcff5..ee2dcfcb 100644 --- a/nodes/external-chunk/object.js +++ b/nodes/external-chunk/object.js @@ -2,7 +2,6 @@ var Observ = require('mutant/value') var computed = require('mutant/computed') var watch = require('mutant/watch') var resolveNode = require('lib/resolve-node') -var getDirectory = require('path').dirname var Event = require('geval') var Property = require('lib/property') var ProxyDict = require('mutant/proxy-dict') @@ -14,17 +13,18 @@ var ExternalRouter = require('lib/external-router') var BaseChunk = require('lib/base-chunk') var extendParams = require('lib/extend-params') var Param = require('lib/param') +var resolve = require('mutant/resolve') var forEach = require('mutant/for-each') var forEachPair = require('mutant/for-each-pair') -var relative = require('path').relative -var resolve = require('path').resolve +var Path = require('path') module.exports = External function External (parentContext) { var context = Object.create(parentContext) + context.cwd = Observ() var volume = Property(1) var overrideVolume = Property(1) @@ -111,11 +111,11 @@ function External (parentContext) { }) obs.resolvePath = function (src) { - return resolve(context.cwd, src) + return Path.resolve(resolve(context.cwd), src) } obs.relative = function (path) { - var value = relative(context.cwd, path) + var value = Path.relative(resolve(context.cwd), path) if (/^\./.exec(value)) { return value } else { @@ -144,6 +144,7 @@ function External (parentContext) { nodeReleases.pop()() } + unwatchPath() broadcastClose() Param.destroy(obs) } @@ -155,9 +156,9 @@ function External (parentContext) { } } - watch(obs.src, function (src) { - var path = src ? resolve(parentContext.cwd, src) : null + var path = computed([parentContext.cwd, obs.src], (a, b) => a && b && Path.resolve(a, b) || null) + var unwatchPath = watch(path, function (path) { if (obs.file && obs.file.path() !== path) { while (fileReleases.length) { fileReleases.pop()() @@ -172,6 +173,7 @@ function External (parentContext) { loading = true obs.file = ObservFile(path) updateFile = JsonFile(obs.file, updateNode) + context.cwd.set(Path.dirname(path)) fileReleases.push( watch(obs.file.path, obs.path.set) ) @@ -195,7 +197,6 @@ function External (parentContext) { } if (descriptor && ctor) { - context.cwd = getDirectory(obs.file.path()) obs.node = ctor(context) obs.node.set(descriptor) nodeReleases.push( diff --git a/nodes/loop-grid/grid.js b/nodes/loop-grid/grid.js index 11dfdf71..e4d52adc 100644 --- a/nodes/loop-grid/grid.js +++ b/nodes/loop-grid/grid.js @@ -185,7 +185,7 @@ function startDrag (ev) { coords: controller.chunkPositions.get(chunk.id()) } ev.dataTransfer.setData('loop-drop/' + type, JSON.stringify(data)) - ev.dataTransfer.setData('cwd', chunk.context.cwd) + ev.dataTransfer.setData('cwd', resolve(chunk.context.cwd)) window.currentDrag = ev } @@ -226,11 +226,11 @@ function dragOver (ev) { var currentDrag = window.currentDrag if (!currentDrag) return - var originalDirectory = currentDrag.node.context.cwd + var originalDirectory = resolve(currentDrag.node.context.cwd) - if (ev.altKey || originalDirectory !== controller.context.cwd) { + if (ev.altKey || originalDirectory !== resolve(controller.context.cwd)) { ev.dataTransfer.dropEffect = 'copy' - } else if (currentDrag && originalDirectory === controller.context.cwd) { + } else if (currentDrag && originalDirectory === resolve(controller.context.cwd)) { var chunkId = getId(currentDrag.node) if (chunkId) { var shape = controller.playback.shape() @@ -275,7 +275,7 @@ function drop (ev) { var r = Math.floor(ev.offsetY / height) var c = Math.floor(ev.offsetX / width) - if (ev.altKey || ev.shiftKey || originalDirectory !== controller.context.cwd) { + if (ev.altKey || ev.shiftKey || originalDirectory !== resolve(controller.context.cwd)) { var chunk = JSON.parse(data) setup.importChunk(chunk, originalDirectory, function (err, id) { if (err) throw err diff --git a/nodes/project/object.js b/nodes/project/object.js index dd20626f..1c11a901 100644 --- a/nodes/project/object.js +++ b/nodes/project/object.js @@ -75,9 +75,9 @@ function Project (parentContext) { obs.renaming = Observ(false) obs.duplicating = Observ(false) - obs.entries = ObservDirectory(context.cwd) + obs.entries = ObservDirectory(resolve(context.cwd)) - obs.recordingEntries = ObservDirectory(resolvePath(context.cwd, '~recordings')) + obs.recordingEntries = ObservDirectory(resolvePath(resolve(context.cwd), '~recordings')) obs.outputRms = ObservRms(masterOutput) @@ -217,7 +217,6 @@ function Project (parentContext) { if (item) { resolveAvailable(path, context.fs, function (err, newPath) { if (err) throw err - var newName = getFile(path) ncp(path, newPath, (err) => { obs.duplicating.set(false) @@ -226,7 +225,7 @@ function Project (parentContext) { obs.recordingEntries.refresh() var newSetupPath = join(newPath, 'index.json') - console.log(`Duplicated "${path}" to "${newName}"`) + console.log(`Duplicated "${path}"`) item.load(newSetupPath) obs.selected.set(resolve(item.path)) obs.renaming.set(newPath) @@ -237,7 +236,7 @@ function Project (parentContext) { }, newSetup: function () { - var path = join(context.cwd, 'New Setup') + var path = join(resolve(context.cwd), 'New Setup') resolveAvailable(path, context.fs, function (err, path) { if (err) throw err context.fs.mkdir(path, function (err) { diff --git a/nodes/setup/object.js b/nodes/setup/object.js index 360cc6cf..f5b85399 100644 --- a/nodes/setup/object.js +++ b/nodes/setup/object.js @@ -3,6 +3,7 @@ var Slots = require('lib/slots') var Observ = require('mutant/value') var watch = require('mutant/watch') var computed = require('mutant/computed') +var resolve = require('mutant/resolve') var Event = require('geval') var updateParamReferences = require('lib/update-param-references') var lookup = require('mutant/lookup') @@ -185,11 +186,11 @@ function Setup (parentContext) { if (descriptor.node === 'externalChunk') { var originalPath = join(originalDirectory, descriptor.src) - var targetPath = join(context.cwd, id + '.json') + var targetPath = join(resolve(context.cwd), id + '.json') context.fs.readFile(originalPath, 'utf8', function (err, data) { if (err) return cb && cb(err) var externalDescriptor = JSON.parse(data) - importAssociatedFiles(externalDescriptor, originalDirectory, context.cwd, function (err) { + importAssociatedFiles(externalDescriptor, originalDirectory, resolve(context.cwd), function (err) { if (err) return cb && cb(err) context.fs.writeFile(targetPath, JSON.stringify(externalDescriptor), function (err) { if (err) return cb && cb(err) @@ -201,7 +202,7 @@ function Setup (parentContext) { }) }) } else { - importAssociatedFiles(descriptor, originalDirectory, context.cwd, function (err) { + importAssociatedFiles(descriptor, originalDirectory, resolve(context.cwd), function (err) { if (err) return cb && cb(err) node.chunks.push(descriptor) cb && cb(null, id) @@ -235,7 +236,7 @@ function Setup (parentContext) { updateRouteReferences(chunk, oldId, newId) }) - if (node.selectedChunkId() === oldId){ + if (node.selectedChunkId() === oldId) { node.selectedChunkId.set(newId) } } @@ -243,14 +244,6 @@ function Setup (parentContext) { return node } -function getResolved (node) { - return node && node.resolved || node -} - -function resolveInner (node) { - return node && node.node || node -} - function updateRouteReferences (chunk, oldId, newId) { var routes = chunk.routes || (chunk.node && chunk.node.routes) if (routes) { diff --git a/nodes/triggers-chunk/slot-chooser.js b/nodes/triggers-chunk/slot-chooser.js index f6d7be61..f7d87e31 100644 --- a/nodes/triggers-chunk/slot-chooser.js +++ b/nodes/triggers-chunk/slot-chooser.js @@ -3,6 +3,7 @@ var send = require('mutant/send') var when = require('mutant/when') var computed = require('mutant/computed') var Keys = require('mutant/keys') +var resolve = require('mutant/resolve') var MPE = require('lib/mouse-position-event.js') var importSample = require('lib/import-sample') @@ -145,7 +146,7 @@ function drop (ev) { if (!target) { target = ev.data.spawnSlot({id: ev.data.id, chunk: ev.data.chunk}) } - importAssociatedFiles(descriptor, cwd, targetCollection.context.cwd, function (err) { + importAssociatedFiles(descriptor, cwd, resolve(targetCollection.context.cwd), function (err) { if (err) throw err target.sources.push(data) }) @@ -175,7 +176,7 @@ function drop (ev) { sourceCollection.remove(source) } - importAssociatedFiles(descriptor, sourceCollection.context.cwd, targetCollection.context.cwd, function (err) { + importAssociatedFiles(descriptor, resolve(sourceCollection.context.cwd), resolve(targetCollection.context.cwd), function (err) { if (err) throw err targetCollection.push(descriptor) })