Several actions have been reworked to be non-blocking, as their
operation should still occur in the main thread, but should not block
the thread they are called from, as they are not required to continue
processing there.
End of secure access has also been made non-blocking, as it is usually
only called when an input is done accessing a given file or folder, so
it should be important to return quickly, as the input is likely about
to terminate, and other things are waiting for it to return.
Also remove a nested block call for the storage access, as it is within
an existing serializing block, so it shouldn't need to be nested.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Releasing sandbox access was incorrectly synchronizing on the object,
but still running code in the calling thread. It has been updated to
match the rest of the interface, which serializes all access through the
main thread only. This should prevent the sandbox from carrying stale
handles to already-released objects.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The code which looked up Sandbox handles for a given path had a bug
where it would re-add the handle to the in-memory cache storage even if
it already had just retrieved the current handle from the cache. I hope
this will fix the crashes which have been plaguing people adding a lot
of files to the playlist all at once from a single folder.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Synchronize with dispatches to the main thread instead of using
synchronization primitives. This prevents the main thread from
hanging another thread as a result of other threads entering the
sync block, then dispatching a callback to the main thread, which
also tries to lock on the sync block.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
All concurrency from other threads should pass through the viewContext's
performBlock or performBlockAndWait functions, and no other way. So now,
all access to Core Data is either happening on the main thread, or by
using these code blocks, all of which will wait for their access to
proceed.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This should fix up potential locking issues with maintaining a copy of
the results set while certain other background actions may happen, such
as the player updating play counts while playing.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Clean up redundant paths automatically, and on startup. Also refresh the
preferences dialog path list every time it is opened.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Added a warning dialog to notify the user of the purpose of the add
folder dialog that will pop up after it. Otherwise, they may get the
idea that the dialog is a glitch and should be cancelled.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Apparently we need this to prevent Core Data from stomping on itself
when another thread accesses it.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Only pop up the path suggester and check on local file URLs, not remote
URLs, which shouldn't be checked, since they don't require sandbox
permission grants or bookmarks.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This redesign completely changes how tags are stored in memory. Now all
arbitrary tag names are supported, where possible. Some extra work will
be needed to support arbitrary tags with TagLib, such as replacing it
with a different library.
Translation pending for a couple of strings.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The fragment remover need not detect whether the given path is a folder
or a file, as it is only removing hash marked fragments, not actually
removing the entire filename if it's only a file and not a folder like
the old versions used to. This greatly speeds up access, especially on
network shares.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Ask for permission to access the folders containing container files,
such as .CUE sheets, or .M3U or .PLS playlists.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Revert "Remove the file tree, as Sandbox does not permit"
This reverts commit 35400e1320.
This also changes how the File Tree choosing works.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Full access should be synchronized, otherwise rapid access to the same
path from different threads will cause crashes.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Include entitlement granted user folders in the permission check, so
that if the file or folder is nested under one of them, it allocates a
static permission object, rather than querying the list of configured
paths every time. This also prevents the player from popping open the
path grant / suggester dialog every time a default path is in the file
set listed, which should provide some relief to most users.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The crash was because we weren't copying the results array before
iterating over it, and the deadlock was because this was forced to go
through the main thread, rather than going through its calling thread,
which could lock up if the main thread was busy working with the Sandbox
Broker object.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
The Path Suggester will now automatically open when new files are added
to the playlist and a given path is not in the sandbox settings. It will
also pop for both the File Tree and MIDI SoundFont path configuration
settings being changed.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Synchronize storage access to main thread only, to prevent enumeration
from hitting a case of the main thread writing to the storage.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Refine the global variable usage, eliminating double underscore prefixes
and trusting that static global variables will exist in the object where
the class was created. Got rid of that nasty NSApplication extension
hack that was previously in use.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Allow opening directory URLs as-is, rather than treating them like
files. Return the full path if the caller requests opening on a
directory.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Sandbox Broker now returns a handle to the exact path object that was
retained by the caller, so it will be released correctly, regardless of
what happens to the list of bookmarked paths.
Also refined the bookmark path comparison function. For existing paths,
it will find the first match. For new paths, it will prefer the longest
path instead, to try to find the deepest matching bookmark.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
- Implemented App Sandboxing in a more friendly manner.
- All sandboxed paths will need to be set in Preferences. Set as loose
a path as you want. The shortest path will be preferred.
- Removed Last.fm client support, as it was non-functional by now,
unfortunately. Maybe something better can come in the future.
- Added support for insecure SSL to the HTTP/S reader, in case anyone
needs streams which are "protected" by self-signed or expired
certificates, without having to futz around by adding certificates to
the system settings, especially for expired certificates that can't
otherwise be dodged this way.
If you want to import your old playlists to the new version, copy the
contents of `~/Library/Application Support/Cog` to the alternate sandbox
path: `~/Library/Containers/org.cogx.cog/Data/Library/Application `...
...continued...`Support/Cog`. The preferences file will migrate to the
new version automatically.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Handle missing track items in the databse more gracefully, by deleting
the track entries before passing them on to the caller, so problems do
not occur later.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Completely rewrite the playlist storage once again, this time with a
much faster Core Data implementation. It still uses a little magic for
Album Artwork consolidation, but string consolidation doesn't seem to be
needed to reduce the disk storage size. Works much faster than my silly
implementation, too.
Old implementations are still kept for backwards compatibility with
existing playlists.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Every schema upgrade process should fall through to the next highest
version number, so they should all run, if the user has somehow upgraded
their database from such an old version.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Various warnings related to uninitialized variables, or setting values
to variables that would not be used later or would be overwritten by per
loop initializers.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
String and art adder functions now perform type checks, in case of
memory errors that somehow result in classes changing type. Which in
itself is a strange thing to happen.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Restructure the add string or art functions so they don't take a pointer
to a pointer, which may have caused issues when receiving a nil string
from the caller. Instead, take a plain pointer, and return the object,
returning the ID of the object to a pointer to an int64_t.
Also change several prototypes and functions to use _Nonnull or
_Nullable where appropriate.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This prevents crashes where inputs were not returning either properties
or metadata blocks and the file open cache was attempting to cache the
resulting nil pointer as if it were valid. Also prevent the metadata
redundant string coalescing from processing nil objects as well, in case
it's used that way somewhere else.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Add an extra condition to the visibility check, which is similar to the
previous version of this check, which now guards against the window it
is hosted in not being visible.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
For legacy systems that do not support Metal. The Metal SceneKit view
does work on even 10.13.6, if a Metal GPU is present in the system.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Promote the Plugin Controller source file to Objective-C++, and add a
simple data cache that holds on to requests for up to 5 seconds after
their last access, for preventing spammed requests from hitting files
over and over. This is apparently really relevant to the CUESheet reader
and its embedded CUESheet handling, as that tends to reread the same
file over and over as it populates the playlist with tracks. The nested
reader can also lead to repeated reading even on files without CUESheets
embedded.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Artwork deduplication should be done with hashes, not by full data
comparison. This should be a lot faster loading artwork from files now,
especially if the playlist already contains a lot of unique artwork.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This is a more correct method of identifying the supported classes to
coalesce into unique pointers through the storage array. I completely
forgot about this method, oops.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This allows for TagLib to handle artwork reading where the file built-in
readers fail, such as the FFmpeg reader, which would require parsing the
stream data for artwork packets, a really wacky convention to have.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Strings read from the database were not being stashed in the memory
store, which caused things like blank tags instead of correct metadata.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
Significantly reduce the memory footprint of adding tracks to the
playlist, by coalescing the NSString and NSData objects in the info
dictionaries as they are being loaded in the background, into a common
data set which will then be discarded when the whole job is completed.
Signed-off-by: Christopher Snowhill <kode54@gmail.com>