mirror of
https://github.com/dborth/vbagx.git
synced 2024-11-29 05:54:17 +01:00
faster smb browsing - added thread to parse entries
This commit is contained in:
parent
014505c37c
commit
d941c4a02c
@ -33,6 +33,8 @@
|
|||||||
#include "filebrowser.h"
|
#include "filebrowser.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
|
|
||||||
|
#define THREAD_SLEEP 100
|
||||||
|
|
||||||
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN(32);
|
unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN(32);
|
||||||
static mutex_t bufferLock = LWP_MUTEX_NULL;
|
static mutex_t bufferLock = LWP_MUTEX_NULL;
|
||||||
FILE * file; // file pointer - the only one we should ever use!
|
FILE * file; // file pointer - the only one we should ever use!
|
||||||
@ -47,9 +49,13 @@ bool isMounted[9] = { false, false, false, false, false, false, false, false, fa
|
|||||||
const DISC_INTERFACE* cardb = &__io_gcsdb;
|
const DISC_INTERFACE* cardb = &__io_gcsdb;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
// folder parsing thread
|
||||||
* deviceThreading
|
static lwp_t parsethread = LWP_THREAD_NULL;
|
||||||
***************************************************************************/
|
static DIR_ITER * dirIter = NULL;
|
||||||
|
static bool parseHalt = true;
|
||||||
|
bool ParseDirEntries();
|
||||||
|
|
||||||
|
// device thread
|
||||||
static lwp_t devicethread = LWP_THREAD_NULL;
|
static lwp_t devicethread = LWP_THREAD_NULL;
|
||||||
static bool deviceHalt = true;
|
static bool deviceHalt = true;
|
||||||
|
|
||||||
@ -82,7 +88,7 @@ HaltDeviceThread()
|
|||||||
|
|
||||||
// wait for thread to finish
|
// wait for thread to finish
|
||||||
while(!LWP_ThreadIsSuspended(devicethread))
|
while(!LWP_ThreadIsSuspended(devicethread))
|
||||||
usleep(100);
|
usleep(THREAD_SLEEP);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -100,8 +106,8 @@ devicecallback (void *arg)
|
|||||||
{
|
{
|
||||||
if(deviceHalt)
|
if(deviceHalt)
|
||||||
LWP_SuspendThread(devicethread);
|
LWP_SuspendThread(devicethread);
|
||||||
usleep(100);
|
usleep(THREAD_SLEEP);
|
||||||
devsleep -= 100;
|
devsleep -= THREAD_SLEEP;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
@ -151,13 +157,25 @@ devicecallback (void *arg)
|
|||||||
{
|
{
|
||||||
if(deviceHalt)
|
if(deviceHalt)
|
||||||
LWP_SuspendThread(devicethread);
|
LWP_SuspendThread(devicethread);
|
||||||
usleep(100);
|
usleep(THREAD_SLEEP);
|
||||||
devsleep -= 100;
|
devsleep -= THREAD_SLEEP;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *
|
||||||
|
parsecallback (void *arg)
|
||||||
|
{
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
while(ParseDirEntries())
|
||||||
|
usleep(THREAD_SLEEP);
|
||||||
|
LWP_SuspendThread(parsethread);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* InitDeviceThread
|
* InitDeviceThread
|
||||||
*
|
*
|
||||||
@ -168,6 +186,7 @@ void
|
|||||||
InitDeviceThread()
|
InitDeviceThread()
|
||||||
{
|
{
|
||||||
LWP_CreateThread (&devicethread, devicecallback, NULL, NULL, 0, 40);
|
LWP_CreateThread (&devicethread, devicecallback, NULL, NULL, 0, 40);
|
||||||
|
LWP_CreateThread (&parsethread, parsecallback, NULL, NULL, 0, 80);
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -314,32 +333,107 @@ bool ChangeInterface(int method, bool silent)
|
|||||||
return mounted;
|
return mounted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ParseDirEntries()
|
||||||
|
{
|
||||||
|
if(!dirIter)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
char filename[MAXPATHLEN];
|
||||||
|
struct stat filestat;
|
||||||
|
|
||||||
|
int i, res;
|
||||||
|
|
||||||
|
for(i=0; i < 20; i++)
|
||||||
|
{
|
||||||
|
res = dirnext(dirIter,filename,&filestat);
|
||||||
|
|
||||||
|
if(res != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(strcmp(filename,".") == 0)
|
||||||
|
{
|
||||||
|
i--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (browser.numEntries+i+1) * sizeof(BROWSERENTRY));
|
||||||
|
|
||||||
|
if(!newBrowserList) // failed to allocate required memory
|
||||||
|
{
|
||||||
|
ResetBrowser();
|
||||||
|
ErrorPrompt("Out of memory: too many files!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
browserList = newBrowserList;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&(browserList[browser.numEntries+i]), 0, sizeof(BROWSERENTRY)); // clear the new entry
|
||||||
|
|
||||||
|
strncpy(browserList[browser.numEntries+i].filename, filename, MAXJOLIET);
|
||||||
|
browserList[browser.numEntries+i].length = filestat.st_size;
|
||||||
|
browserList[browser.numEntries+i].mtime = filestat.st_mtime;
|
||||||
|
browserList[browser.numEntries+i].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
|
||||||
|
|
||||||
|
if(browserList[browser.numEntries+i].isdir)
|
||||||
|
{
|
||||||
|
if(strcmp(filename, "..") == 0)
|
||||||
|
sprintf(browserList[browser.numEntries+i].displayname, "Up One Level");
|
||||||
|
else
|
||||||
|
strncpy(browserList[browser.numEntries+i].displayname, browserList[browser.numEntries+i].filename, MAXJOLIET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
StripExt(browserList[browser.numEntries+i].displayname, browserList[browser.numEntries+i].filename); // hide file extension
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the file list
|
||||||
|
if(i >= 0)
|
||||||
|
{
|
||||||
|
browser.numEntries += i;
|
||||||
|
qsort(browserList, browser.numEntries, sizeof(BROWSERENTRY), FileSortCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(res != 0 || parseHalt)
|
||||||
|
{
|
||||||
|
dirclose(dirIter); // close directory
|
||||||
|
dirIter = NULL;
|
||||||
|
return false; // no more entries
|
||||||
|
}
|
||||||
|
return true; // more entries
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* Browse subdirectories
|
* Browse subdirectories
|
||||||
**************************************************************************/
|
**************************************************************************/
|
||||||
int
|
int
|
||||||
ParseDirectory(int method)
|
ParseDirectory(int method)
|
||||||
{
|
{
|
||||||
DIR_ITER *dir = NULL;
|
|
||||||
char fulldir[MAXPATHLEN];
|
char fulldir[MAXPATHLEN];
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
struct stat filestat;
|
|
||||||
char msg[128];
|
char msg[128];
|
||||||
int retry = 1;
|
int retry = 1;
|
||||||
bool mounted = false;
|
bool mounted = false;
|
||||||
|
|
||||||
|
// halt parsing
|
||||||
|
parseHalt = true;
|
||||||
|
|
||||||
|
while(!LWP_ThreadIsSuspended(parsethread))
|
||||||
|
usleep(THREAD_SLEEP);
|
||||||
|
|
||||||
// reset browser
|
// reset browser
|
||||||
|
dirIter = NULL;
|
||||||
ResetBrowser();
|
ResetBrowser();
|
||||||
|
|
||||||
ShowAction("Loading...");
|
|
||||||
|
|
||||||
// open the directory
|
// open the directory
|
||||||
while(dir == NULL && retry == 1)
|
while(dirIter == NULL && retry == 1)
|
||||||
{
|
{
|
||||||
mounted = ChangeInterface(method, NOTSILENT);
|
mounted = ChangeInterface(method, NOTSILENT);
|
||||||
sprintf(fulldir, "%s%s", rootdir, browser.dir); // add device to path
|
sprintf(fulldir, "%s%s", rootdir, browser.dir); // add device to path
|
||||||
if(mounted) dir = diropen(fulldir);
|
if(mounted) dirIter = diropen(fulldir);
|
||||||
if(dir == NULL)
|
if(dirIter == NULL)
|
||||||
{
|
{
|
||||||
unmountRequired[method] = true;
|
unmountRequired[method] = true;
|
||||||
sprintf(msg, "Error opening %s", fulldir);
|
sprintf(msg, "Error opening %s", fulldir);
|
||||||
@ -348,14 +442,14 @@ ParseDirectory(int method)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if we can't open the dir, try opening the root dir
|
// if we can't open the dir, try opening the root dir
|
||||||
if (dir == NULL)
|
if (dirIter == NULL)
|
||||||
{
|
{
|
||||||
if(ChangeInterface(method, SILENT))
|
if(ChangeInterface(method, SILENT))
|
||||||
{
|
{
|
||||||
sprintf(browser.dir,"/");
|
sprintf(browser.dir,"/");
|
||||||
sprintf(fulldir, "%s%s", rootdir, browser.dir);
|
sprintf(fulldir, "%s%s", rootdir, browser.dir);
|
||||||
dir = diropen(fulldir);
|
dirIter = diropen(fulldir);
|
||||||
if (dir == NULL)
|
if (dirIter == NULL)
|
||||||
{
|
{
|
||||||
sprintf(msg, "Error opening %s", rootdir);
|
sprintf(msg, "Error opening %s", rootdir);
|
||||||
ErrorPrompt(msg);
|
ErrorPrompt(msg);
|
||||||
@ -364,59 +458,11 @@ ParseDirectory(int method)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// index files/folders
|
parseHalt = false;
|
||||||
int entryNum = 0;
|
ParseDirEntries(); // index first 50 entries
|
||||||
|
LWP_ResumeThread(parsethread); // index remaining entries
|
||||||
|
|
||||||
while(dirnext(dir,filename,&filestat) == 0)
|
return browser.numEntries;
|
||||||
{
|
|
||||||
if(strcmp(filename,".") != 0)
|
|
||||||
{
|
|
||||||
BROWSERENTRY * newBrowserList = (BROWSERENTRY *)realloc(browserList, (entryNum+1) * sizeof(BROWSERENTRY));
|
|
||||||
|
|
||||||
if(!newBrowserList) // failed to allocate required memory
|
|
||||||
{
|
|
||||||
ResetBrowser();
|
|
||||||
ErrorPrompt("Out of memory: too many files!");
|
|
||||||
entryNum = -1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
browserList = newBrowserList;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&(browserList[entryNum]), 0, sizeof(BROWSERENTRY)); // clear the new entry
|
|
||||||
|
|
||||||
strncpy(browserList[entryNum].filename, filename, MAXJOLIET);
|
|
||||||
browserList[entryNum].length = filestat.st_size;
|
|
||||||
browserList[entryNum].mtime = filestat.st_mtime;
|
|
||||||
browserList[entryNum].isdir = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir
|
|
||||||
|
|
||||||
if(browserList[entryNum].isdir)
|
|
||||||
{
|
|
||||||
if(strcmp(filename, "..") == 0)
|
|
||||||
sprintf(browserList[entryNum].displayname, "Up One Level");
|
|
||||||
else
|
|
||||||
strncpy(browserList[entryNum].displayname, browserList[entryNum].filename, MAXJOLIET);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StripExt(browserList[entryNum].displayname, browserList[entryNum].filename); // hide file extension
|
|
||||||
}
|
|
||||||
entryNum++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// close directory
|
|
||||||
dirclose(dir);
|
|
||||||
|
|
||||||
// Sort the file list
|
|
||||||
qsort(browserList, entryNum, sizeof(BROWSERENTRY), FileSortCallback);
|
|
||||||
|
|
||||||
CancelAction();
|
|
||||||
|
|
||||||
browser.numEntries = entryNum;
|
|
||||||
return entryNum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
@ -908,6 +908,7 @@ class GuiFileBrowser : public GuiElement
|
|||||||
GuiButton * fileList[FILE_PAGESIZE];
|
GuiButton * fileList[FILE_PAGESIZE];
|
||||||
protected:
|
protected:
|
||||||
int selectedItem;
|
int selectedItem;
|
||||||
|
int numEntries;
|
||||||
bool listChanged;
|
bool listChanged;
|
||||||
|
|
||||||
GuiText * fileListText[FILE_PAGESIZE];
|
GuiText * fileListText[FILE_PAGESIZE];
|
||||||
|
@ -18,6 +18,7 @@ GuiFileBrowser::GuiFileBrowser(int w, int h)
|
|||||||
{
|
{
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
|
numEntries = 0;
|
||||||
selectedItem = 0;
|
selectedItem = 0;
|
||||||
selectable = true;
|
selectable = true;
|
||||||
listChanged = true; // trigger an initial list update
|
listChanged = true; // trigger an initial list update
|
||||||
@ -329,7 +330,7 @@ void GuiFileBrowser::Update(GuiTrigger * t)
|
|||||||
|
|
||||||
for(int i=0; i<FILE_PAGESIZE; i++)
|
for(int i=0; i<FILE_PAGESIZE; i++)
|
||||||
{
|
{
|
||||||
if(listChanged)
|
if(listChanged || numEntries != browser.numEntries)
|
||||||
{
|
{
|
||||||
if(browser.pageIndex+i < browser.numEntries)
|
if(browser.pageIndex+i < browser.numEntries)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user