mirror of
https://github.com/libretro/RetroArch
synced 2025-02-28 22:13:51 +00:00
ios: Clean up directory listing code.
This commit is contained in:
parent
4d9233b02a
commit
2d04aefe5f
@ -10,7 +10,6 @@
|
||||
962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */; };
|
||||
962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; };
|
||||
962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; };
|
||||
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */ = {isa = PBXBuildFile; fileRef = 962979FF16C4767F00E6DCE0 /* dirent_list.c */; };
|
||||
96297A0916C59EC000E6DCE0 /* module_list.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0816C59EC000E6DCE0 /* module_list.m */; };
|
||||
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; };
|
||||
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; };
|
||||
@ -83,8 +82,6 @@
|
||||
962979EE16C3EA3E00E6DCE0 /* ioseagl_ctx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioseagl_ctx.c; sourceTree = "<group>"; };
|
||||
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
|
||||
962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = "<group>"; };
|
||||
962979FF16C4767F00E6DCE0 /* dirent_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dirent_list.c; sourceTree = "<group>"; };
|
||||
96297A0016C4767F00E6DCE0 /* dirent_list.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dirent_list.h; sourceTree = "<group>"; };
|
||||
96297A0816C59EC000E6DCE0 /* module_list.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = module_list.m; sourceTree = "<group>"; };
|
||||
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = "<group>"; };
|
||||
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = "<group>"; };
|
||||
@ -336,8 +333,6 @@
|
||||
96297A0D16C5ADDA00E6DCE0 /* views.h */,
|
||||
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */,
|
||||
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */,
|
||||
962979FF16C4767F00E6DCE0 /* dirent_list.c */,
|
||||
96297A0016C4767F00E6DCE0 /* dirent_list.h */,
|
||||
96AFAE4C16C1D4EA009DE44C /* ViewController_iPhone.xib */,
|
||||
96AFAE4F16C1D4EA009DE44C /* ViewController_iPad.xib */,
|
||||
96AFAE3416C1D4EA009DE44C /* Supporting Files */,
|
||||
@ -785,7 +780,6 @@
|
||||
96CF015016C2C0B700ABF9C9 /* overlay.c in Sources */,
|
||||
96CF015C16C2F72900ABF9C9 /* ios_input.c in Sources */,
|
||||
962979EF16C3EA3E00E6DCE0 /* ioseagl_ctx.c in Sources */,
|
||||
96297A0116C4767F00E6DCE0 /* dirent_list.c in Sources */,
|
||||
96297A0916C59EC000E6DCE0 /* module_list.m in Sources */,
|
||||
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */,
|
||||
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */,
|
||||
|
@ -6,76 +6,78 @@
|
||||
// Copyright (c) 2013 RetroArch. All rights reserved.
|
||||
//
|
||||
|
||||
#include "dirent_list.h"
|
||||
|
||||
@implementation directory_list
|
||||
{
|
||||
char* directory;
|
||||
struct dirent_list* files;
|
||||
NSString* directory;
|
||||
NSArray* list;
|
||||
};
|
||||
|
||||
- (id)initWithPath:(const char*)path
|
||||
- (id)initWithPath:(NSString*)path
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStylePlain];
|
||||
|
||||
directory = strdup(path);
|
||||
files = build_dirent_list(directory);
|
||||
directory = path;
|
||||
|
||||
list = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:directory error:nil];
|
||||
list = [directory stringsByAppendingPaths:list];
|
||||
|
||||
list = [list sortedArrayUsingComparator:^(id left, id right)
|
||||
{
|
||||
BOOL left_is_dir;
|
||||
BOOL right_is_dir;
|
||||
|
||||
[[NSFileManager defaultManager] fileExistsAtPath:left isDirectory:&left_is_dir];
|
||||
[[NSFileManager defaultManager] fileExistsAtPath:right isDirectory:&right_is_dir];
|
||||
|
||||
return (left_is_dir != right_is_dir) ? (left_is_dir < right_is_dir) : ([left caseInsensitiveCompare:right]);
|
||||
}];
|
||||
|
||||
self.navigationItem.rightBarButtonItem = [RetroArch_iOS get].settings_button;
|
||||
[self setTitle: [[[NSString alloc] initWithUTF8String:directory] lastPathComponent]];
|
||||
[self setTitle: [directory lastPathComponent]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
free_dirent_list(files);
|
||||
free(directory);
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
const struct dirent* item = get_dirent_at_index(files, indexPath.row);
|
||||
|
||||
if (!item) return;
|
||||
|
||||
char new_path[4096];
|
||||
snprintf(new_path, 4096, "%s/%s", directory, item->d_name);
|
||||
new_path[4095] = 0;
|
||||
|
||||
if (item->d_type)
|
||||
{
|
||||
[[RetroArch_iOS get].navigator
|
||||
pushViewController:[[directory_list alloc] initWithPath:new_path]
|
||||
animated:YES];
|
||||
}
|
||||
else
|
||||
NSString* path = [list objectAtIndex: indexPath.row];
|
||||
BOOL isdir;
|
||||
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir])
|
||||
{
|
||||
[RetroArch_iOS get].window.rootViewController = [[game_view alloc] init];
|
||||
if (isdir)
|
||||
{
|
||||
[[RetroArch_iOS get].navigator
|
||||
pushViewController:[[directory_list alloc] initWithPath:path]
|
||||
animated:YES];
|
||||
}
|
||||
else
|
||||
{
|
||||
[RetroArch_iOS get].window.rootViewController = [[game_view alloc] init];
|
||||
|
||||
extern void ios_load_game(const char*);
|
||||
ios_load_game(new_path);
|
||||
extern void ios_load_game(const char*);
|
||||
ios_load_game([path UTF8String]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return get_dirent_list_count(files);
|
||||
return [list count];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"];
|
||||
|
||||
const struct dirent* item = get_dirent_at_index(files, indexPath.row);
|
||||
|
||||
if (item)
|
||||
|
||||
NSString* path = [list objectAtIndex: indexPath.row];
|
||||
BOOL isdir;
|
||||
if([[NSFileManager defaultManager] fileExistsAtPath:path isDirectory:&isdir])
|
||||
{
|
||||
cell.textLabel.text = [[NSString string] initWithUTF8String:item->d_name];
|
||||
cell.accessoryType = (item->d_type) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
|
||||
cell.imageView.image = (item->d_type) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon;
|
||||
[cell.imageView sizeToFit];
|
||||
cell.textLabel.text = [path lastPathComponent];
|
||||
cell.accessoryType = (isdir) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
|
||||
cell.imageView.image = (isdir) ? [RetroArch_iOS get].folder_icon : [RetroArch_iOS get].file_icon;
|
||||
}
|
||||
|
||||
return cell;
|
||||
|
@ -1,97 +0,0 @@
|
||||
#include <sys/stat.h>
|
||||
#include <dirent.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include "general.h"
|
||||
#include "dirent_list.h"
|
||||
|
||||
static int compare_dirent(const void *left, const void *right)
|
||||
{
|
||||
const struct dirent* l = (const struct dirent*) left;
|
||||
const struct dirent* r = (const struct dirent*) right;
|
||||
|
||||
// Directories first
|
||||
if (l->d_type != r->d_type)
|
||||
return (l->d_type) ? -1 : 1;
|
||||
|
||||
// Name
|
||||
return strcmp(l->d_name, r->d_name);
|
||||
}
|
||||
|
||||
static bool is_dirent_verboten(const struct dirent* entry)
|
||||
{
|
||||
if (!entry) return true;
|
||||
if (strcmp(entry->d_name, ".") == 0) return true;
|
||||
if (strcmp(entry->d_name, "..") == 0) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
struct dirent_list* build_dirent_list(const char* path)
|
||||
{
|
||||
struct dirent_list* result = 0;
|
||||
|
||||
DIR* dir = opendir(path);
|
||||
if (dir)
|
||||
{
|
||||
struct dirent* ent = 0;
|
||||
|
||||
// Count the number of items
|
||||
size_t count = 0;
|
||||
while ((ent = readdir(dir)))
|
||||
{
|
||||
count += is_dirent_verboten(ent) ? 0 : 1;
|
||||
}
|
||||
rewinddir(dir);
|
||||
|
||||
// String buffer for 'stat'ing
|
||||
char* stat_path = malloc(strlen(path) + sizeof(ent->d_name));
|
||||
strcpy(stat_path, path);
|
||||
uint32_t last_index = strlen(stat_path);
|
||||
|
||||
// Build and fill the result
|
||||
result = malloc(sizeof(struct dirent_list));
|
||||
result->count = count;
|
||||
result->entries = malloc(sizeof(struct dirent) * count);
|
||||
|
||||
size_t index = 0;
|
||||
while ((ent = readdir(dir)))
|
||||
{
|
||||
if (is_dirent_verboten(ent)) continue;
|
||||
memcpy(&result->entries[index], ent, sizeof(struct dirent));
|
||||
|
||||
// Chage dirent.d_type to a boolean indication if it is a directory
|
||||
struct stat stat_buf;
|
||||
strcat(strcat(stat_path, "/"), ent->d_name);
|
||||
stat(stat_path, &stat_buf);
|
||||
result->entries[index].d_type = S_ISDIR(stat_buf.st_mode) ? 1 : 0;
|
||||
stat_path[last_index] = 0;
|
||||
|
||||
index ++;
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
free(stat_path);
|
||||
|
||||
qsort(result->entries, result->count, sizeof(struct dirent), &compare_dirent);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void free_dirent_list(struct dirent_list* list)
|
||||
{
|
||||
if (list) free(list->entries);
|
||||
free(list);
|
||||
}
|
||||
|
||||
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index)
|
||||
{
|
||||
if (!list) return 0;
|
||||
return (index < list->count) ? &list->entries[index] : 0;
|
||||
}
|
||||
|
||||
unsigned get_dirent_list_count(struct dirent_list* list)
|
||||
{
|
||||
return list ? list->count : 0;
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
/* RetroArch - A frontend for libretro.
|
||||
* Copyright (C) 2010-2013 - Hans-Kristian Arntzen
|
||||
*
|
||||
* RetroArch is free software: you can redistribute it and/or modify it under the terms
|
||||
* of the GNU General Public License as published by the Free Software Found-
|
||||
* ation, either version 3 of the License, or (at your option) any later version.
|
||||
*
|
||||
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
||||
* PURPOSE. See the GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with RetroArch.
|
||||
* If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __RARCH_IOS_DIRENT_LIST_H
|
||||
#define __RARCH_IOS_DIRENT_LIST_H
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
struct dirent_list
|
||||
{
|
||||
size_t count;
|
||||
struct dirent* entries;
|
||||
};
|
||||
|
||||
struct dirent_list* build_dirent_list(const char* path);
|
||||
void free_dirent_list(struct dirent_list* list);
|
||||
|
||||
const struct dirent* get_dirent_at_index(struct dirent_list* list, unsigned index);
|
||||
unsigned get_dirent_list_count(struct dirent_list* list);
|
||||
|
||||
#endif
|
@ -33,7 +33,7 @@
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[RetroArch_iOS get].module_path = [modules objectAtIndex:indexPath.row];
|
||||
[[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:"/"] animated:YES];
|
||||
[[RetroArch_iOS get].navigator pushViewController:[[directory_list alloc] initWithPath:@"/"] animated:YES];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
@ -46,7 +46,7 @@
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"];
|
||||
|
||||
cell.textLabel.text = [[modules objectAtIndex:indexPath.row] lastPathComponent];
|
||||
cell.textLabel.text = [[[modules objectAtIndex:indexPath.row] lastPathComponent] stringByDeletingPathExtension];
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
@ -10,5 +10,5 @@
|
||||
@end
|
||||
|
||||
@interface directory_list : UITableViewController
|
||||
- (id)initWithPath:(const char*)path;
|
||||
- (id)initWithPath:(NSString*)path;
|
||||
@end
|
||||
|
Loading…
x
Reference in New Issue
Block a user