epic: refactor SDL2_Renderer usage to IRenderer and queued texture rendering
- Updated the testing guide to clarify the testing framework's organization and execution methods, improving user understanding. - Refactored CMakeLists to include new platform-specific files, ensuring proper integration of the rendering backend. - Modified main application files to utilize the new IRenderer interface, enhancing flexibility in rendering operations. - Implemented deferred texture management in various components, allowing for more efficient graphics handling and improved performance. - Introduced new methods for texture creation and updates, streamlining the rendering process across the application. - Enhanced logging and error handling in the rendering pipeline to facilitate better debugging and diagnostics.
This commit is contained in:
303
src/app/platform/file_dialog.mm
Normal file
303
src/app/platform/file_dialog.mm
Normal file
@@ -0,0 +1,303 @@
|
||||
#include "util/file_util.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "app/core/features.h"
|
||||
|
||||
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
|
||||
#include <nfd.h>
|
||||
#endif
|
||||
|
||||
#if defined(__APPLE__) && defined(__MACH__)
|
||||
/* Apple OSX and iOS (Darwin). */
|
||||
#include <Foundation/Foundation.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#import <CoreText/CoreText.h>
|
||||
|
||||
#if TARGET_IPHONE_SIMULATOR == 1 || TARGET_OS_IPHONE == 1
|
||||
/* iOS in Xcode simulator */
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
#include "app/platform/app_delegate.h"
|
||||
|
||||
namespace {
|
||||
static std::string selectedFile;
|
||||
|
||||
void ShowOpenFileDialogImpl(void (^completionHandler)(std::string)) {
|
||||
AppDelegate *appDelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
|
||||
[appDelegate PresentDocumentPickerWithCompletionHandler:^(NSString *filePath) {
|
||||
selectedFile = std::string([filePath UTF8String]);
|
||||
completionHandler(selectedFile);
|
||||
}];
|
||||
}
|
||||
|
||||
std::string ShowOpenFileDialogSync() {
|
||||
__block std::string result;
|
||||
|
||||
ShowOpenFileDialogImpl(^(std::string filePath) {
|
||||
result = filePath;
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() { return ShowOpenFileDialogSync(); }
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() { return ""; }
|
||||
|
||||
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
|
||||
const std::string &folder) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::vector<std::string> yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder(
|
||||
const std::string &folder) {
|
||||
return {};
|
||||
}
|
||||
|
||||
std::string yaze::util::GetBundleResourcePath() {
|
||||
NSBundle* bundle = [NSBundle mainBundle];
|
||||
NSString* resourceDirectoryPath = [bundle bundlePath];
|
||||
NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"];
|
||||
return [path UTF8String];
|
||||
}
|
||||
|
||||
#elif TARGET_OS_MAC == 1
|
||||
/* macOS */
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <UniformTypeIdentifiers/UniformTypeIdentifiers.h>
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogBespoke() {
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
[openPanel setCanChooseFiles:YES];
|
||||
[openPanel setCanChooseDirectories:NO];
|
||||
[openPanel setAllowsMultipleSelection:NO];
|
||||
|
||||
if ([openPanel runModal] == NSModalResponseOK) {
|
||||
NSURL* url = [[openPanel URLs] objectAtIndex:0];
|
||||
NSString* path = [url path];
|
||||
return std::string([path UTF8String]);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogBespoke(const std::string& default_name,
|
||||
const std::string& default_extension) {
|
||||
NSSavePanel* savePanel = [NSSavePanel savePanel];
|
||||
|
||||
if (!default_name.empty()) {
|
||||
[savePanel setNameFieldStringValue:[NSString stringWithUTF8String:default_name.c_str()]];
|
||||
}
|
||||
|
||||
if (!default_extension.empty()) {
|
||||
NSString* ext = [NSString stringWithUTF8String:default_extension.c_str()];
|
||||
[savePanel setAllowedFileTypes:@[ext]];
|
||||
}
|
||||
|
||||
if ([savePanel runModal] == NSModalResponseOK) {
|
||||
NSURL* url = [savePanel URL];
|
||||
NSString* path = [url path];
|
||||
return std::string([path UTF8String]);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
// Global feature flag-based dispatch methods
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialog() {
|
||||
if (core::FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowOpenFileDialogNFD();
|
||||
} else {
|
||||
return ShowOpenFileDialogBespoke();
|
||||
}
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialog() {
|
||||
if (core::FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowOpenFolderDialogNFD();
|
||||
} else {
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
}
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialog(const std::string& default_name,
|
||||
const std::string& default_extension) {
|
||||
if (core::FeatureFlags::get().kUseNativeFileDialog) {
|
||||
return ShowSaveFileDialogNFD(default_name, default_extension);
|
||||
} else {
|
||||
return ShowSaveFileDialogBespoke(default_name, default_extension);
|
||||
}
|
||||
}
|
||||
|
||||
// NFD implementation for macOS (fallback to bespoke if NFD not available)
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFileDialogNFD() {
|
||||
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
|
||||
NFD_Init();
|
||||
nfdu8char_t *out_path = NULL;
|
||||
nfdu8filteritem_t filters[1] = {{"Rom File", "sfc,smc"}};
|
||||
nfdopendialogu8args_t args = {0};
|
||||
args.filterList = filters;
|
||||
args.filterCount = 1;
|
||||
|
||||
nfdresult_t result = NFD_OpenDialogU8_With(&out_path, &args);
|
||||
if (result == NFD_OKAY) {
|
||||
std::string file_path(out_path);
|
||||
NFD_FreePath(out_path);
|
||||
NFD_Quit();
|
||||
return file_path;
|
||||
} else if (result == NFD_CANCEL) {
|
||||
NFD_Quit();
|
||||
return "";
|
||||
}
|
||||
NFD_Quit();
|
||||
return "";
|
||||
#else
|
||||
// NFD not compiled in, use bespoke
|
||||
return ShowOpenFileDialogBespoke();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogNFD() {
|
||||
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
|
||||
NFD_Init();
|
||||
nfdu8char_t *out_path = NULL;
|
||||
nfdresult_t result = NFD_PickFolderU8(&out_path, NULL);
|
||||
|
||||
if (result == NFD_OKAY) {
|
||||
std::string folder_path(out_path);
|
||||
NFD_FreePath(out_path);
|
||||
NFD_Quit();
|
||||
return folder_path;
|
||||
} else if (result == NFD_CANCEL) {
|
||||
NFD_Quit();
|
||||
return "";
|
||||
}
|
||||
NFD_Quit();
|
||||
return "";
|
||||
#else
|
||||
// NFD not compiled in, use bespoke
|
||||
return ShowOpenFolderDialogBespoke();
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowSaveFileDialogNFD(const std::string& default_name,
|
||||
const std::string& default_extension) {
|
||||
#if defined(YAZE_ENABLE_NFD) && YAZE_ENABLE_NFD
|
||||
NFD_Init();
|
||||
nfdu8char_t *out_path = NULL;
|
||||
|
||||
nfdsavedialogu8args_t args = {0};
|
||||
if (!default_extension.empty()) {
|
||||
// Create filter for the save dialog
|
||||
static nfdu8filteritem_t filters[3] = {
|
||||
{"Theme File", "theme"},
|
||||
{"Project File", "yaze"},
|
||||
{"ROM File", "sfc,smc"}
|
||||
};
|
||||
|
||||
if (default_extension == "theme") {
|
||||
args.filterList = &filters[0];
|
||||
args.filterCount = 1;
|
||||
} else if (default_extension == "yaze") {
|
||||
args.filterList = &filters[1];
|
||||
args.filterCount = 1;
|
||||
} else if (default_extension == "sfc" || default_extension == "smc") {
|
||||
args.filterList = &filters[2];
|
||||
args.filterCount = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!default_name.empty()) {
|
||||
args.defaultName = default_name.c_str();
|
||||
}
|
||||
|
||||
nfdresult_t result = NFD_SaveDialogU8_With(&out_path, &args);
|
||||
if (result == NFD_OKAY) {
|
||||
std::string file_path(out_path);
|
||||
NFD_FreePath(out_path);
|
||||
NFD_Quit();
|
||||
return file_path;
|
||||
} else if (result == NFD_CANCEL) {
|
||||
NFD_Quit();
|
||||
return "";
|
||||
}
|
||||
NFD_Quit();
|
||||
return "";
|
||||
#else
|
||||
// NFD not compiled in, use bespoke
|
||||
return ShowSaveFileDialogBespoke(default_name, default_extension);
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string yaze::util::FileDialogWrapper::ShowOpenFolderDialogBespoke() {
|
||||
NSOpenPanel* openPanel = [NSOpenPanel openPanel];
|
||||
[openPanel setCanChooseFiles:NO];
|
||||
[openPanel setCanChooseDirectories:YES];
|
||||
[openPanel setAllowsMultipleSelection:NO];
|
||||
|
||||
if ([openPanel runModal] == NSModalResponseOK) {
|
||||
NSURL* url = [[openPanel URLs] objectAtIndex:0];
|
||||
NSString* path = [url path];
|
||||
return std::string([path UTF8String]);
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
std::vector<std::string> yaze::util::FileDialogWrapper::GetFilesInFolder(
|
||||
const std::string& folder) {
|
||||
std::vector<std::string> filenames;
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSDirectoryEnumerator* enumerator =
|
||||
[fileManager enumeratorAtPath:[NSString stringWithUTF8String:folder.c_str()]];
|
||||
NSString* file;
|
||||
while (file = [enumerator nextObject]) {
|
||||
if ([file hasPrefix:@"."]) {
|
||||
continue;
|
||||
}
|
||||
filenames.push_back(std::string([file UTF8String]));
|
||||
}
|
||||
return filenames;
|
||||
}
|
||||
|
||||
std::vector<std::string> yaze::util::FileDialogWrapper::GetSubdirectoriesInFolder(
|
||||
const std::string& folder) {
|
||||
std::vector<std::string> subdirectories;
|
||||
NSFileManager* fileManager = [NSFileManager defaultManager];
|
||||
NSDirectoryEnumerator* enumerator =
|
||||
[fileManager enumeratorAtPath:[NSString stringWithUTF8String:folder.c_str()]];
|
||||
NSString* file;
|
||||
while (file = [enumerator nextObject]) {
|
||||
if ([file hasPrefix:@"."]) {
|
||||
continue;
|
||||
}
|
||||
BOOL isDirectory;
|
||||
NSString* path =
|
||||
[NSString stringWithFormat:@"%@/%@", [NSString stringWithUTF8String:folder.c_str()], file];
|
||||
[fileManager fileExistsAtPath:path isDirectory:&isDirectory];
|
||||
if (isDirectory) {
|
||||
subdirectories.push_back(std::string([file UTF8String]));
|
||||
}
|
||||
}
|
||||
return subdirectories;
|
||||
}
|
||||
|
||||
std::string yaze::util::GetBundleResourcePath() {
|
||||
NSBundle* bundle = [NSBundle mainBundle];
|
||||
NSString* resourceDirectoryPath = [bundle bundlePath];
|
||||
NSString* path = [resourceDirectoryPath stringByAppendingString:@"/"];
|
||||
return [path UTF8String];
|
||||
}
|
||||
|
||||
#else
|
||||
// Unsupported platform
|
||||
#endif // TARGET_OS_MAC
|
||||
|
||||
#endif // __APPLE__ && __MACH__
|
||||
Reference in New Issue
Block a user