(iOS) Cache the RAModuleInfo structures instead of reloading the each time a RAModuleList is created.

This commit is contained in:
meancoot 2013-03-26 22:38:38 -04:00
parent 8995ce2cb2
commit b0329be296
7 changed files with 144 additions and 101 deletions

View File

@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
9605EA9B170288EA001D47B0 /* RAModuleInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9605EA9A170288EA001D47B0 /* RAModuleInfo.m */; };
96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; };
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 */; };
@ -46,6 +47,8 @@
/* Begin PBXFileReference section */
960356BC1700652C008F55DA /* btpad_ps3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btpad_ps3.c; sourceTree = "<group>"; };
960356BD1700652C008F55DA /* btpad_wii.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btpad_wii.c; sourceTree = "<group>"; };
9605EA99170288EA001D47B0 /* RAModuleInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAModuleInfo.h; sourceTree = "<group>"; };
9605EA9A170288EA001D47B0 /* RAModuleInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfo.m; sourceTree = "<group>"; };
96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = "<group>"; };
9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = "<absolute>"; };
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
@ -256,6 +259,8 @@
96297A0E16C5AEA100E6DCE0 /* main.m */,
963F5AC516CC523B009BBD19 /* RAGameView.m */,
96F9C28216FFA55F002455B3 /* RALogView.m */,
9605EA9A170288EA001D47B0 /* RAModuleInfo.m */,
9605EA99170288EA001D47B0 /* RAModuleInfo.h */,
96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */,
96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */,
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */,
@ -411,6 +416,7 @@
966B9CB416E41C07005B61E1 /* RAModuleList.m in Sources */,
D48581DE16F823F9004BEB17 /* griffin.c in Sources */,
96F9C28316FFA55F002455B3 /* RALogView.m in Sources */,
9605EA9B170288EA001D47B0 /* RAModuleInfo.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -0,0 +1,31 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2013 - Jason Fetters
*
* 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/>.
*/
#include "conf/config_file.h"
@interface RAModuleInfo : NSObject
@property (strong) NSString* path;
@property config_file_t* data;
@property (strong) NSString* configPath;
@property (strong) NSString* displayName;
@property (strong) NSArray* supportedExtensions;
+ (NSArray*)getModules;
- (bool)supportsFileAtPath:(NSString*)path;
@end
@interface RAModuleInfoList : UITableViewController
- (id)initWithModuleInfo:(RAModuleInfo*)info;
@end

View File

@ -0,0 +1,83 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2013 - Jason Fetters
*
* 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/>.
*/
#include <glob.h>
#import "RAModuleInfo.h"
static NSMutableArray* moduleList;
@implementation RAModuleInfo
+ (NSArray*)getModules
{
if (!moduleList)
{
char pattern[PATH_MAX];
snprintf(pattern, PATH_MAX, "%s/modules/*.dylib", [[NSBundle mainBundle].bundlePath UTF8String]);
glob_t files = {0};
glob(pattern, 0, 0, &files);
moduleList = [NSMutableArray arrayWithCapacity:files.gl_pathc];
for (int i = 0; i != files.gl_pathc; i ++)
{
RAModuleInfo* newInfo = [RAModuleInfo new];
newInfo.path = [NSString stringWithUTF8String:files.gl_pathv[i]];
strcpy(pattern, files.gl_pathv[i]);
strcpy(strrchr(pattern, '.'), ".info");
newInfo.data = config_file_new(pattern);
char* dispname = 0;
char* extensions = 0;
if (newInfo.data)
{
config_get_string(newInfo.data, "display_name", &dispname);
config_get_string(newInfo.data, "supported_extensions", &extensions);
}
newInfo.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[newInfo.path lastPathComponent] stringByDeletingPathExtension]];
newInfo.displayName = dispname ? [NSString stringWithUTF8String:dispname] : [[newInfo.path lastPathComponent] stringByDeletingPathExtension];
newInfo.supportedExtensions = extensions ? [[NSString stringWithUTF8String:extensions] componentsSeparatedByString:@"|"] : [NSArray array];
free(dispname);
free(extensions);
[moduleList addObject:newInfo];
}
globfree(&files);
[moduleList sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right)
{
return [left.displayName caseInsensitiveCompare:right.displayName];
}];
}
return moduleList;
}
- (void)dealloc
{
config_file_free(self.data);
}
- (bool)supportsFileAtPath:(NSString*)path
{
return [self.supportedExtensions containsObject:[[path pathExtension] lowercaseString]];
}
@end

View File

@ -13,45 +13,6 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
@implementation RAModuleInfo
+ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData
{
RAModuleInfo* new = [RAModuleInfo new];
char* dispname = 0;
char* extensions = 0;
if (theData)
{
config_get_string(theData, "display_name", &dispname);
config_get_string(theData, "supported_extensions", &extensions);
}
new.displayName = dispname ? [NSString stringWithUTF8String:dispname] : [[thePath lastPathComponent] stringByDeletingPathExtension];
new.path = thePath;
new.configPath = [NSString stringWithFormat:@"%@/%@.cfg", [RetroArch_iOS get].system_directory, [[thePath lastPathComponent] stringByDeletingPathExtension]];
new.data = theData;
new.supportedExtensions = extensions ? [[NSString stringWithUTF8String:extensions] componentsSeparatedByString:@"|"] : [NSArray array];
free(dispname);
free(extensions);
return new;
}
- (void)dealloc
{
config_file_free(self.data);
}
- (bool)supportsFileAtPath:(NSString*)path
{
return [self.supportedExtensions containsObject:[[path pathExtension] lowercaseString]];
}
@end
static NSString* const labels[3] = {@"Emulator Name", @"Manufacturer", @"Name"};
static const char* const keys[3] = {"emuname", "manufacturer", "systemname"};
static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"};

View File

@ -13,6 +13,7 @@
* If not, see <http://www.gnu.org/licenses/>.
*/
#import "RAMOduleInfo.h"
#import "browser.h"
@implementation RAModuleList
@ -26,56 +27,37 @@
- (id)initWithGame:(NSString*)path
{
self = [super initWithStyle:UITableViewStyleGrouped];
[self setTitle:[path lastPathComponent]];
_game = path;
// Get the contents of the modules directory of the bundle.
NSString* module_dir = [NSString stringWithFormat:@"%@/modules", [[NSBundle mainBundle] bundlePath]];
//
NSArray* moduleList = [RAModuleInfo getModules];
NSArray* moduleList = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:module_dir error:nil];
if (moduleList != nil)
{
moduleList = [module_dir stringsByAppendingPaths:moduleList];
moduleList = [moduleList pathsMatchingExtensions:[NSArray arrayWithObject:@"dylib"]];
}
if (moduleList == nil || [moduleList count] == 0)
{
if (moduleList.count == 0)
[RetroArch_iOS displayErrorMessage:@"No libretro cores were found."];
}
// Load the modules with their data
_supported = [NSMutableArray array];
_other = [NSMutableArray array];
for (int i = 0; i != [moduleList count]; i ++)
for (RAModuleInfo* i in moduleList)
{
NSString* modulePath = [moduleList objectAtIndex:i];
NSString* baseName = [[modulePath stringByDeletingPathExtension] stringByAppendingPathExtension:@"info"];
RAModuleInfo* module = [RAModuleInfo moduleWithPath:modulePath data:config_file_new([baseName UTF8String])];
if ([module supportsFileAtPath:_game])
[_supported addObject:module];
else
[_other addObject:module];
NSMutableArray* target = [i supportsFileAtPath:_game] ? _supported : _other;
[target addObject:i];
}
// Sort
[_supported sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right)
{
return [left.displayName caseInsensitiveCompare:right.displayName];
}];
// No sort, [RAModuleInfo getModules] is already sorted by display name
[_other sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right)
{
return [left.displayName caseInsensitiveCompare:right.displayName];
}];
[self setTitle:[_game lastPathComponent]];
return self;
}
- (RAModuleInfo*)moduleInfoForIndexPath:(NSIndexPath*)path
{
NSMutableArray* sectionData = (_supported.count && path.section == 0) ? _supported : _other;
return (RAModuleInfo*)sectionData[path.row];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
{
return _supported.count ? 2 : 1;
@ -97,27 +79,22 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other;
[RetroArch_iOS get].moduleInfo = (RAModuleInfo*)sectionData[indexPath.row];
[RetroArch_iOS get].moduleInfo = [self moduleInfoForIndexPath:indexPath];
[[RetroArch_iOS get] runGame:_game];
}
- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath
{
NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other;
[RetroArch_iOS get].moduleInfo = (RAModuleInfo*)sectionData[indexPath.row];
[RetroArch_iOS get].moduleInfo = [self moduleInfoForIndexPath:indexPath];
[[RetroArch_iOS get] showSettings];
}
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"module"];
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"];
cell = (cell) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"module"];
NSMutableArray* sectionData = (_supported.count && indexPath.section == 0) ? _supported : _other;
RAModuleInfo* info = (RAModuleInfo*)sectionData[indexPath.row];
RAModuleInfo* info = [self moduleInfoForIndexPath:indexPath];
cell.textLabel.text = info.displayName;
cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;

View File

@ -133,9 +133,9 @@ static RASettingData* custom_action(NSString* action)
(void)[[RASettingsList alloc] init];
}
- (id)init
- (RASettingsList*)initWithModule:(RAModuleInfo*)module
{
config_file_t* config = config_file_new([[RetroArch_iOS get].moduleInfo.configPath UTF8String]);
config_file_t* config = config_file_new([module.configPath UTF8String]);
NSString* overlay_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/overlays/"];
NSString* shader_path = [[[NSBundle mainBundle] bundlePath] stringByAppendingString:@"/shaders/"];

View File

@ -16,7 +16,7 @@
#import <UIKit/UIKit.h>
#import <GLKit/GLKit.h>
#include "conf/config_file.h"
#import "RAModuleInfo.h"
@interface RAGameView : UIViewController
+ (RAGameView*)get;
@ -26,18 +26,3 @@
@interface RALogView : UITableViewController
@end
@interface RAModuleInfo : NSObject
@property (strong) NSString* displayName;
@property (strong) NSString* path;
@property (strong) NSString* configPath;
@property config_file_t* data;
@property (strong) NSArray* supportedExtensions;
+ (RAModuleInfo*)moduleWithPath:(NSString*)thePath data:(config_file_t*)theData;
- (bool)supportsFileAtPath:(NSString*)path;
@end
@interface RAModuleInfoList : UITableViewController
- (id)initWithModuleInfo:(RAModuleInfo*)info;
@end