Obj-C Refactor: Port BLI_delete_soft from objc_* runtime calls to proper Obj-C
Port the macOS version of the `BLI_delete_soft` function from raw runtime `objc_*` calls function to proper Objective-C for increased readability and long-term maintainability. This new function is placed in a new `intern/fileops_apple.mm` file, analogous to the existing `intern/storage_apple.mm` file. Pull Request: https://projects.blender.org/blender/blender/pulls/126766
This commit is contained in:
committed by
Sergey Sharybin
parent
e5e5d5fe73
commit
fe93de1a91
@@ -487,6 +487,7 @@ endif()
|
||||
if(APPLE)
|
||||
list(APPEND SRC
|
||||
intern/storage_apple.mm
|
||||
intern/fileops_apple.mm
|
||||
)
|
||||
endif()
|
||||
|
||||
|
||||
33
source/blender/blenlib/intern/fileops_apple.mm
Normal file
33
source/blender/blenlib/intern/fileops_apple.mm
Normal file
@@ -0,0 +1,33 @@
|
||||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bli
|
||||
*
|
||||
* macOS specific implementations for fileops{_c}.cc.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_path_util.h"
|
||||
|
||||
int BLI_delete_soft(const char *filepath, const char **r_error_message)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
@autoreleasepool {
|
||||
NSString *pathString = [NSString stringWithUTF8String:filepath];
|
||||
NSFileManager *fileManager = [NSFileManager defaultManager];
|
||||
NSURL *targetURL = [NSURL fileURLWithPath:pathString];
|
||||
|
||||
BOOL deleteSuccessful = [fileManager trashItemAtURL:targetURL resultingItemURL:nil error:nil];
|
||||
|
||||
if (!deleteSuccessful) {
|
||||
*r_error_message = "The Cocoa API call to delete file or directory failed";
|
||||
}
|
||||
|
||||
return deleteSuccessful ? 0 : -1;
|
||||
}
|
||||
}
|
||||
@@ -1158,49 +1158,55 @@ static int delete_single_file(const char *from, const char * /*to*/)
|
||||
return RecursiveOp_Callback_OK;
|
||||
}
|
||||
|
||||
# ifdef __APPLE__
|
||||
static int delete_soft(const char *filepath, const char **r_error_message)
|
||||
FILE *BLI_fopen(const char *filepath, const char *mode)
|
||||
{
|
||||
int ret = -1;
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
Class NSAutoreleasePoolClass = objc_getClass("NSAutoreleasePool");
|
||||
SEL allocSel = sel_registerName("alloc");
|
||||
SEL initSel = sel_registerName("init");
|
||||
id poolAlloc = ((id(*)(Class, SEL))objc_msgSend)(NSAutoreleasePoolClass, allocSel);
|
||||
id pool = ((id(*)(id, SEL))objc_msgSend)(poolAlloc, initSel);
|
||||
|
||||
Class NSStringClass = objc_getClass("NSString");
|
||||
SEL stringWithUTF8StringSel = sel_registerName("stringWithUTF8String:");
|
||||
id pathString = ((id(*)(Class, SEL, const char *))objc_msgSend)(
|
||||
NSStringClass, stringWithUTF8StringSel, filepath);
|
||||
|
||||
Class NSFileManagerClass = objc_getClass("NSFileManager");
|
||||
SEL defaultManagerSel = sel_registerName("defaultManager");
|
||||
id fileManager = ((id(*)(Class, SEL))objc_msgSend)(NSFileManagerClass, defaultManagerSel);
|
||||
|
||||
Class NSURLClass = objc_getClass("NSURL");
|
||||
SEL fileURLWithPathSel = sel_registerName("fileURLWithPath:");
|
||||
id nsurl = ((id(*)(Class, SEL, id))objc_msgSend)(NSURLClass, fileURLWithPathSel, pathString);
|
||||
|
||||
SEL trashItemAtURLSel = sel_registerName("trashItemAtURL:resultingItemURL:error:");
|
||||
BOOL deleteSuccessful = ((BOOL(*)(id, SEL, id, id, id))objc_msgSend)(
|
||||
fileManager, trashItemAtURLSel, nsurl, nil, nil);
|
||||
|
||||
if (deleteSuccessful) {
|
||||
ret = 0;
|
||||
}
|
||||
else {
|
||||
*r_error_message = "The Cocoa API call to delete file or directory failed";
|
||||
}
|
||||
|
||||
SEL drainSel = sel_registerName("drain");
|
||||
((void (*)(id, SEL))objc_msgSend)(pool, drainSel);
|
||||
|
||||
return ret;
|
||||
return fopen(filepath, mode);
|
||||
}
|
||||
# else
|
||||
static int delete_soft(const char *filepath, const char **r_error_message)
|
||||
|
||||
void *BLI_gzopen(const char *filepath, const char *mode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return gzopen(filepath, mode);
|
||||
}
|
||||
|
||||
int BLI_open(const char *filepath, int oflag, int pmode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return open(filepath, oflag, pmode);
|
||||
}
|
||||
|
||||
int BLI_access(const char *filepath, int mode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return access(filepath, mode);
|
||||
}
|
||||
|
||||
int BLI_delete(const char *path, bool dir, bool recursive)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(path));
|
||||
/* Not an error but avoid ambiguous arguments (recursive file deletion isn't meaningful). */
|
||||
BLI_assert(!(dir == false && recursive == true));
|
||||
|
||||
if (recursive) {
|
||||
return recursive_operation(path, nullptr, nullptr, delete_single_file, delete_callback_post);
|
||||
}
|
||||
if (dir) {
|
||||
return rmdir(path);
|
||||
}
|
||||
return remove(path);
|
||||
}
|
||||
|
||||
/* Apple version is defined in fileops_apple.mm */
|
||||
# ifndef __APPLE__
|
||||
int BLI_delete_soft(const char *filepath, const char **r_error_message)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
const char *args[5];
|
||||
const char *process_failed;
|
||||
|
||||
@@ -1278,56 +1284,6 @@ static int delete_soft(const char *filepath, const char **r_error_message)
|
||||
}
|
||||
# endif
|
||||
|
||||
FILE *BLI_fopen(const char *filepath, const char *mode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return fopen(filepath, mode);
|
||||
}
|
||||
|
||||
void *BLI_gzopen(const char *filepath, const char *mode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return gzopen(filepath, mode);
|
||||
}
|
||||
|
||||
int BLI_open(const char *filepath, int oflag, int pmode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return open(filepath, oflag, pmode);
|
||||
}
|
||||
|
||||
int BLI_access(const char *filepath, int mode)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return access(filepath, mode);
|
||||
}
|
||||
|
||||
int BLI_delete(const char *path, bool dir, bool recursive)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(path));
|
||||
/* Not an error but avoid ambiguous arguments (recursive file deletion isn't meaningful). */
|
||||
BLI_assert(!(dir == false && recursive == true));
|
||||
|
||||
if (recursive) {
|
||||
return recursive_operation(path, nullptr, nullptr, delete_single_file, delete_callback_post);
|
||||
}
|
||||
if (dir) {
|
||||
return rmdir(path);
|
||||
}
|
||||
return remove(path);
|
||||
}
|
||||
|
||||
int BLI_delete_soft(const char *filepath, const char **r_error_message)
|
||||
{
|
||||
BLI_assert(!BLI_path_is_rel(filepath));
|
||||
|
||||
return delete_soft(filepath, r_error_message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the two paths denote the same file-system object?
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user