Core: Adding to library is now recursive
Vicki Pfau vi@endrift.com
Tue, 05 Jan 2021 00:23:52 -0800
5 files changed,
50 insertions(+),
38 deletions(-)
M
CHANGES
→
CHANGES
@@ -94,6 +94,7 @@ - Core: Add savedataUpdated callback
- Core: Add shutdown callback - Core: Rework thread state synchronization - Core: Improve support for ROM patch cheats, supporting disabling overlapping patches + - Core: Adding to library is now recursive - GB: Allow pausing event loop while CPU is blocked - GB: Add support for sleep and shutdown callbacks - GB: Redo double speed emulation (closes mgba.io/i/1515)
M
include/mgba/core/library.h
→
include/mgba/core/library.h
@@ -35,7 +35,7 @@ void mLibraryDestroy(struct mLibrary*);
struct VDir; struct VFile; -void mLibraryLoadDirectory(struct mLibrary* library, const char* base); +void mLibraryLoadDirectory(struct mLibrary* library, const char* base, bool recursive); void mLibraryClear(struct mLibrary* library); size_t mLibraryCount(struct mLibrary* library, const struct mLibraryEntry* constraints);
M
src/core/library.c
→
src/core/library.c
@@ -42,7 +42,7 @@ "CASE WHEN :useRoot THEN roots.path = :root ELSE 1 END"
static void _mLibraryDeleteEntry(struct mLibrary* library, struct mLibraryEntry* entry); static void _mLibraryInsertEntry(struct mLibrary* library, struct mLibraryEntry* entry); -static void _mLibraryAddEntry(struct mLibrary* library, const char* filename, const char* base, struct VFile* vf); +static bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const char* base, struct VFile* vf); static void _bindConstraints(sqlite3_stmt* statement, const struct mLibraryEntry* constraints) { if (!constraints) {@@ -212,7 +212,7 @@ sqlite3_close(library->db);
free(library); } -void mLibraryLoadDirectory(struct mLibrary* library, const char* base) { +void mLibraryLoadDirectory(struct mLibrary* library, const char* base, bool recursive) { struct VDir* dir = VDirOpenArchive(base); if (!dir) { dir = VDirOpen(base);@@ -248,44 +248,55 @@
dir->rewind(dir); struct VDirEntry* dirent = dir->listNext(dir); while (dirent) { - struct VFile* vf = dir->openFile(dir, dirent->name(dirent), O_RDONLY); - if (!vf) { - dirent = dir->listNext(dir); - continue; + const char* name = dirent->name(dirent); + struct VFile* vf = dir->openFile(dir, name, O_RDONLY); + bool wasAdded = false; + + if (vf) { + wasAdded = _mLibraryAddEntry(library, name, base, vf); } - _mLibraryAddEntry(library, dirent->name(dirent), base, vf); + if (!wasAdded && name[0] != '.') { + char newBase[PATH_MAX]; + snprintf(newBase, sizeof(newBase), "%s" PATH_SEP "%s", base, name); + + if (recursive) { + mLibraryLoadDirectory(library, newBase, recursive); + } else if (dirent->type(dirent) == VFS_FILE) { + mLibraryLoadDirectory(library, newBase, true); // This will add as an archive + } + } dirent = dir->listNext(dir); } dir->close(dir); sqlite3_exec(library->db, "COMMIT;", NULL, NULL, NULL); } -void _mLibraryAddEntry(struct mLibrary* library, const char* filename, const char* base, struct VFile* vf) { - struct mCore* core; +bool _mLibraryAddEntry(struct mLibrary* library, const char* filename, const char* base, struct VFile* vf) { if (!vf) { - return; + return false; } - core = mCoreFindVF(vf); - if (core) { - struct mLibraryEntry entry; - memset(&entry, 0, sizeof(entry)); - core->init(core); - core->loadROM(core, vf); - - core->getGameTitle(core, entry.internalTitle); - core->getGameCode(core, entry.internalCode); - core->checksum(core, &entry.crc32, mCHECKSUM_CRC32); - entry.platform = core->platform(core); - entry.title = NULL; - entry.base = base; - entry.filename = filename; - entry.filesize = vf->size(vf); - _mLibraryInsertEntry(library, &entry); - // Note: this destroys the VFile - core->deinit(core); - } else { + struct mCore* core = mCoreFindVF(vf); + if (!core) { vf->close(vf); + return false; } + struct mLibraryEntry entry; + memset(&entry, 0, sizeof(entry)); + core->init(core); + core->loadROM(core, vf); + + core->getGameTitle(core, entry.internalTitle); + core->getGameCode(core, entry.internalCode); + core->checksum(core, &entry.crc32, mCHECKSUM_CRC32); + entry.platform = core->platform(core); + entry.title = NULL; + entry.base = base; + entry.filename = filename; + entry.filesize = vf->size(vf); + _mLibraryInsertEntry(library, &entry); + // Note: this destroys the VFile + core->deinit(core); + return true; } static void _mLibraryInsertEntry(struct mLibrary* library, struct mLibraryEntry* entry) {
M
src/platform/qt/library/LibraryController.cpp
→
src/platform/qt/library/LibraryController.cpp
@@ -108,10 +108,10 @@ LibraryEntryRef e = selectedEntry();
return e ? qMakePair(e->base(), e->filename()) : qMakePair<QString, QString>("", ""); } -void LibraryController::addDirectory(const QString& dir) { +void LibraryController::addDirectory(const QString& dir, bool recursive) { // The worker thread temporarily owns the library std::shared_ptr<mLibrary> library = m_library; - m_libraryJob = GBAApp::app()->submitWorkerJob(std::bind(&LibraryController::loadDirectory, this, dir), this, [this, library]() { + m_libraryJob = GBAApp::app()->submitWorkerJob(std::bind(&LibraryController::loadDirectory, this, dir, recursive), this, [this, library]() { m_libraryJob = -1; refresh(); });@@ -181,10 +181,10 @@ selectEntry(m_entries.value(lastfile));
} } -void LibraryController::loadDirectory(const QString& dir) { - // This class can get delted during this function (sigh) so we need to hold onto this +void LibraryController::loadDirectory(const QString& dir, bool recursive) { + // This class can get deleted during this function (sigh) so we need to hold onto this std::shared_ptr<mLibrary> library = m_library; - mLibraryLoadDirectory(library.get(), dir.toUtf8().constData()); + mLibraryLoadDirectory(library.get(), dir.toUtf8().constData(), recursive); } void LibraryController::freeLibrary() {@@ -192,4 +192,4 @@ for (size_t i = 0; i < mLibraryListingSize(&m_listing); ++i) {
mLibraryEntryFree(mLibraryListingGetPointer(&m_listing, i)); } mLibraryListingClear(&m_listing); -}+}
M
src/platform/qt/library/LibraryController.h
→
src/platform/qt/library/LibraryController.h
@@ -84,7 +84,7 @@ QPair<QString, QString> selectedPath();
void selectLastBootedGame(); - void addDirectory(const QString& dir); + void addDirectory(const QString& dir, bool recursive = true); public slots: void clear();@@ -97,7 +97,7 @@ private slots:
void refresh(); private: - void loadDirectory(const QString&); // Called on separate thread + void loadDirectory(const QString&, bool recursive = true); // Called on separate thread void freeLibrary(); ConfigController* m_config = nullptr;