diff --git a/lib/stateManagement/openFileTypes.dart b/lib/stateManagement/openFileTypes.dart index 7e7b8c25..e8d6bf80 100644 --- a/lib/stateManagement/openFileTypes.dart +++ b/lib/stateManagement/openFileTypes.dart @@ -546,9 +546,15 @@ class WavFileData with ChangeNotifier, HasUuid, AudioFileData { @override Future load() async { - resource = await audioResourcesManager.getAudioResource(path); + resource = await audioResourcesManager.getAudioResource(path, makeCopy: true); notifyListeners(); } + + @override + void dispose() { + resource?.dispose(); + super.dispose(); + } } class WemFileData extends OpenFileData with AudioFileData { ValueNotifier overrideData = ValueNotifier(null); @@ -616,6 +622,7 @@ class WemFileData extends OpenFileData with AudioFileData { await backupFile(path); var wav = overrideData.value!; await wavToWem(wav.path, path, basename(path).contains("BGM")); + overrideData.value!.dispose(); overrideData.value = null; // reload @@ -629,6 +636,15 @@ class WemFileData extends OpenFileData with AudioFileData { onOverrideApplied.notifyListeners(); } + Future removeOverride() async { + if (overrideData.value == null) + return; + + overrideData.value!.dispose(); + overrideData.value = null; + notifyListeners(); + } + @override Undoable takeSnapshot() { var snapshot = WemFileData( diff --git a/lib/stateManagement/otherFileTypes/audioResourceManager.dart b/lib/stateManagement/otherFileTypes/audioResourceManager.dart index 62a8ed23..79b6bc1a 100644 --- a/lib/stateManagement/otherFileTypes/audioResourceManager.dart +++ b/lib/stateManagement/otherFileTypes/audioResourceManager.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'dart:math'; import 'package:mutex/mutex.dart'; +import 'package:path/path.dart'; import 'package:tuple/tuple.dart'; import '../../fileTypeUtils/audio/riffParser.dart'; @@ -28,11 +29,12 @@ class AudioResource { class AudioResourcesManager { final Map _resources = {}; final Map _loadingMutexes = {}; + String? _tmpDir; /// Returns a reference to the audio file at the given path. /// If the file is already loaded, it will return the same reference. /// If the file is not loaded, it will load it. - Future getAudioResource(String path) async { + Future getAudioResource(String path, { bool makeCopy = false }) async { if (!_loadingMutexes.containsKey(path)) _loadingMutexes[path] = Mutex(); await _loadingMutexes[path]!.acquire(); @@ -48,6 +50,9 @@ class AudioResourcesManager { if (path.endsWith(".wem")) { wavPath = await wemToWavTmp(path); deleteOnDispose = true; + } else if (makeCopy) { + wavPath = await _copyToTmp(path); + deleteOnDispose = true; } var riff = await RiffFile.fromFile(wavPath); @@ -71,6 +76,13 @@ class AudioResourcesManager { return resource; } + Future _copyToTmp(String path) async { + _tmpDir ??= (await Directory.systemTemp.createTemp("tmpWav")).path; + var tmpPath = join(_tmpDir!, basename(path)); + await File(path).copy(tmpPath); + return tmpPath; + } + Future reloadAudioResource(AudioResource resource) async { if (resource.wemPath != null) resource.wavPath = await wemToWavTmp(resource.wemPath!); @@ -94,6 +106,9 @@ class AudioResourcesManager { if (await File(path).exists()) await File(path).delete(); })); + + if (_tmpDir != null && await Directory(_tmpDir!).exists()) + await Directory(_tmpDir!).delete(recursive: true); } /// Disposes the reference to the audio file at the given path. diff --git a/lib/widgets/propEditors/otherFileTypes/wemFileEditor.dart b/lib/widgets/propEditors/otherFileTypes/wemFileEditor.dart index 80afef46..423514c1 100644 --- a/lib/widgets/propEditors/otherFileTypes/wemFileEditor.dart +++ b/lib/widgets/propEditors/otherFileTypes/wemFileEditor.dart @@ -58,7 +58,6 @@ class _WemFileEditorState extends ChangeNotifierState { return; } var wavFile = WavFileData(file.path!); - await wavFile.load(); widget.wem.overrideData.value = wavFile; } @@ -80,7 +79,7 @@ class _WemFileEditorState extends ChangeNotifierState { const SizedBox(width: 10), if (widget.wem.overrideData.value != null) ElevatedButton( - onPressed: () => widget.wem.overrideData.value = null, + onPressed: () => widget.wem.removeOverride(), style: getTheme(context).dialogSecondaryButtonStyle, child: const Text("Remove"), ),