diff options
author | Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com> | 2015-04-20 12:29:35 +0200 |
---|---|---|
committer | Richard Moe Gustavsen <richard.gustavsen@theqtcompany.com> | 2015-05-06 19:46:39 +0000 |
commit | 1665e0d105fd97bfa2c6cd459ba20aa87d8b2a81 (patch) | |
tree | deb0018e2b4b1266fd9e606dc2ad4f47c15bbdff | |
parent | fb5530cd691699c96aa035e430459faf00dfb513 (diff) |
ios: add helper class for enumerating all available assets
Add support for enumerating all available assets on the device.
Trailing patches will use the class to fetch a list of all available
assets for directory listing, and to search for assets that cannot be
loaded by [ALAssetsLibrary assetForURL:].
Change-Id: I319721b536b14424fc8f54f683513aa7ca64e7f0
Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@theqtcompany.com>
-rw-r--r-- | src/plugins/platforms/ios/qiosfileengineassetslibrary.mm | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm index 43d40e9f56..5e73e615e2 100644 --- a/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm +++ b/src/plugins/platforms/ios/qiosfileengineassetslibrary.mm @@ -38,6 +38,122 @@ #include <QtCore/QTimer> #include <QtCore/private/qcoreapplication_p.h> +#include <QtCore/qurl.h> +#include <QtCore/qset.h> + +static const int kBufferSize = 10; +static ALAsset *kNoAsset = 0; + +class QIOSAssetEnumerator +{ +public: + QIOSAssetEnumerator(ALAssetsLibrary *assetsLibrary, ALAssetsGroupType type) + : m_semWriteAsset(dispatch_semaphore_create(kBufferSize)) + , m_semReadAsset(dispatch_semaphore_create(0)) + , m_stop(false) + , m_assetsLibrary([assetsLibrary retain]) + , m_type(type) + , m_buffer(QVector<ALAsset *>(kBufferSize)) + , m_readIndex(0) + , m_writeIndex(0) + , m_nextAssetReady(false) + { + startEnumerate(); + } + + ~QIOSAssetEnumerator() + { + m_stop = true; + + // Flush and autorelease remaining assets in the buffer + while (hasNext()) + next(); + + // Documentation states that we need to balance out calls to 'wait' + // and 'signal'. Since the enumeration function always will be one 'wait' + // ahead, we need to signal m_semProceedToNextAsset one last time. + dispatch_semaphore_signal(m_semWriteAsset); + dispatch_release(m_semReadAsset); + dispatch_release(m_semWriteAsset); + + [m_assetsLibrary autorelease]; + } + + bool hasNext() + { + if (!m_nextAssetReady) { + dispatch_semaphore_wait(m_semReadAsset, DISPATCH_TIME_FOREVER); + m_nextAssetReady = true; + } + return m_buffer[m_readIndex] != kNoAsset; + } + + ALAsset *next() + { + Q_ASSERT(m_nextAssetReady); + Q_ASSERT(m_buffer[m_readIndex]); + + ALAsset *asset = [m_buffer[m_readIndex] autorelease]; + dispatch_semaphore_signal(m_semWriteAsset); + + m_readIndex = (m_readIndex + 1) % kBufferSize; + m_nextAssetReady = false; + return asset; + } + +private: + dispatch_semaphore_t m_semWriteAsset; + dispatch_semaphore_t m_semReadAsset; + std::atomic_bool m_stop; + + ALAssetsLibrary *m_assetsLibrary; + ALAssetsGroupType m_type; + QVector<ALAsset *> m_buffer; + int m_readIndex; + int m_writeIndex; + bool m_nextAssetReady; + + void writeAsset(ALAsset *asset) + { + dispatch_semaphore_wait(m_semWriteAsset, DISPATCH_TIME_FOREVER); + m_buffer[m_writeIndex] = [asset retain]; + dispatch_semaphore_signal(m_semReadAsset); + m_writeIndex = (m_writeIndex + 1) % kBufferSize; + } + + void startEnumerate() + { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [m_assetsLibrary enumerateGroupsWithTypes:m_type usingBlock:^(ALAssetsGroup *group, BOOL *stopEnumerate) { + + if (!group) { + writeAsset(kNoAsset); + return; + } + + if (m_stop) { + *stopEnumerate = true; + return; + } + + [group enumerateAssetsUsingBlock:^(ALAsset *asset, NSUInteger index, BOOL *stopEnumerate) { + Q_UNUSED(index); + if (!asset || ![[asset valueForProperty:ALAssetPropertyType] isEqual:ALAssetTypePhoto]) + return; + + writeAsset(asset); + *stopEnumerate = m_stop; + }]; + } failureBlock:^(NSError *error) { + NSLog(@"QIOSFileEngine: %@", error); + writeAsset(kNoAsset); + }]; + }); + } + +}; + +// ------------------------------------------------------------------------- class QIOSAssetData : public QObject { |