Add iOS platform (refactor Mac into shared Apple platform impl)
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
|
||||
#include "MacPlatform.h"
|
||||
#include "MacWindow.h"
|
||||
#include "MacUtils.h"
|
||||
#include "Engine/Platform/Apple/AppleUtils.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
@@ -17,8 +17,8 @@
|
||||
#include "Engine/Core/Math/Color32.h"
|
||||
#include "Engine/Platform/CPUInfo.h"
|
||||
#include "Engine/Platform/MemoryStats.h"
|
||||
#include "Engine/Platform/StringUtils.h"
|
||||
#include "Engine/Platform/MessageBox.h"
|
||||
#include "Engine/Platform/StringUtils.h"
|
||||
#include "Engine/Platform/WindowsManager.h"
|
||||
#include "Engine/Platform/Clipboard.h"
|
||||
#include "Engine/Platform/IGuiData.h"
|
||||
@@ -48,117 +48,16 @@
|
||||
#include <execinfo.h>
|
||||
#endif
|
||||
|
||||
CPUInfo MacCpu;
|
||||
Guid DeviceId;
|
||||
String UserLocale, ComputerName;
|
||||
double SecondsPerCycle;
|
||||
String ComputerName;
|
||||
NSAutoreleasePool* AutoreleasePool = nullptr;
|
||||
|
||||
float MacPlatform::ScreenScale = 1.0f;
|
||||
|
||||
String MacUtils::ToString(CFStringRef str)
|
||||
{
|
||||
if (!str)
|
||||
return String::Empty;
|
||||
String result;
|
||||
const int32 length = CFStringGetLength(str);
|
||||
if (length > 0)
|
||||
{
|
||||
CFRange range = CFRangeMake(0, length);
|
||||
result.ReserveSpace(length);
|
||||
CFStringGetBytes(str, range, kCFStringEncodingUTF16LE, '?', false, (uint8*)result.Get(), length * sizeof(Char), nullptr);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
CFStringRef MacUtils::ToString(const StringView& str)
|
||||
{
|
||||
return CFStringCreateWithBytes(nullptr, (const UInt8*)str.GetText(), str.Length() * sizeof(Char), kCFStringEncodingUTF16LE, false);
|
||||
}
|
||||
|
||||
Float2 MacUtils::PosToCoca(const Float2& pos)
|
||||
{
|
||||
// MacOS uses y-coordinate starting at the bottom of the screen
|
||||
Float2 result = pos;// / MacPlatform::ScreenScale;
|
||||
result.Y *= -1;
|
||||
result += GetScreensOrigin();
|
||||
return result;
|
||||
}
|
||||
|
||||
Float2 MacUtils::CocaToPos(const Float2& pos)
|
||||
{
|
||||
// MacOS uses y-coordinate starting at the bottom of the screen
|
||||
Float2 result = pos;// * MacPlatform::ScreenScale;
|
||||
result -= GetScreensOrigin();
|
||||
result.Y *= -1;
|
||||
return result;// * MacPlatform::ScreenScale;
|
||||
}
|
||||
|
||||
Float2 MacUtils::GetScreensOrigin()
|
||||
{
|
||||
Float2 result = Float2::Zero;
|
||||
NSArray* screenArray = [NSScreen screens];
|
||||
for (NSUInteger i = 0; i < [screenArray count]; i++)
|
||||
{
|
||||
NSRect rect = [[screenArray objectAtIndex:i] frame];
|
||||
Float2 pos(rect.origin.x, rect.origin.y + rect.size.height);
|
||||
pos *= MacPlatform::ScreenScale;
|
||||
if (pos.X < result.X)
|
||||
result.X = pos.X;
|
||||
if (pos.Y > result.Y)
|
||||
result.Y = pos.Y;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MacClipboard::Clear()
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard clearContents];
|
||||
}
|
||||
|
||||
void MacClipboard::SetText(const StringView& text)
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard clearContents];
|
||||
[pasteboard writeObjects:[NSArray arrayWithObject:(NSString*)MacUtils::ToString(text)]];
|
||||
}
|
||||
|
||||
void MacClipboard::SetRawData(const Span<byte>& data)
|
||||
{
|
||||
}
|
||||
|
||||
void MacClipboard::SetFiles(const Array<String>& files)
|
||||
{
|
||||
}
|
||||
|
||||
String MacClipboard::GetText()
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSArray* classes = [NSArray arrayWithObject:[NSString class]];
|
||||
NSDictionary* options = [NSDictionary dictionary];
|
||||
if (![pasteboard canReadObjectForClasses:classes options:options])
|
||||
return String::Empty;
|
||||
NSArray* objects = [pasteboard readObjectsForClasses:classes options:options];
|
||||
return MacUtils::ToString((CFStringRef)[objects objectAtIndex:0]);
|
||||
}
|
||||
|
||||
Array<byte> MacClipboard::GetRawData()
|
||||
{
|
||||
return Array<byte>();
|
||||
}
|
||||
|
||||
Array<String> MacClipboard::GetFiles()
|
||||
{
|
||||
return Array<String>();
|
||||
}
|
||||
|
||||
DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon)
|
||||
{
|
||||
if (CommandLine::Options.Headless)
|
||||
return DialogResult::None;
|
||||
CFStringRef textRef = MacUtils::ToString(text);
|
||||
CFStringRef captionRef = MacUtils::ToString(caption);
|
||||
CFStringRef textRef = AppleUtils::ToString(text);
|
||||
CFStringRef captionRef = AppleUtils::ToString(caption);
|
||||
CFOptionFlags flags = 0;
|
||||
switch (buttons)
|
||||
{
|
||||
@@ -189,6 +88,83 @@ DialogResult MessageBox::Show(Window* parent, const StringView& text, const Stri
|
||||
return DialogResult::OK;
|
||||
}
|
||||
|
||||
Float2 AppleUtils::PosToCoca(const Float2& pos)
|
||||
{
|
||||
// MacOS uses y-coordinate starting at the bottom of the screen
|
||||
Float2 result = pos;// / ApplePlatform::ScreenScale;
|
||||
result.Y *= -1;
|
||||
result += GetScreensOrigin();
|
||||
return result;
|
||||
}
|
||||
|
||||
Float2 AppleUtils::CocaToPos(const Float2& pos)
|
||||
{
|
||||
// MacOS uses y-coordinate starting at the bottom of the screen
|
||||
Float2 result = pos;// * ApplePlatform::ScreenScale;
|
||||
result -= GetScreensOrigin();
|
||||
result.Y *= -1;
|
||||
return result;// * ApplePlatform::ScreenScale;
|
||||
}
|
||||
|
||||
Float2 AppleUtils::GetScreensOrigin()
|
||||
{
|
||||
Float2 result = Float2::Zero;
|
||||
NSArray* screenArray = [NSScreen screens];
|
||||
for (NSUInteger i = 0; i < [screenArray count]; i++)
|
||||
{
|
||||
NSRect rect = [[screenArray objectAtIndex:i] frame];
|
||||
Float2 pos(rect.origin.x, rect.origin.y + rect.size.height);
|
||||
pos *= ApplePlatform::ScreenScale;
|
||||
if (pos.X < result.X)
|
||||
result.X = pos.X;
|
||||
if (pos.Y > result.Y)
|
||||
result.Y = pos.Y;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MacClipboard::Clear()
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard clearContents];
|
||||
}
|
||||
|
||||
void MacClipboard::SetText(const StringView& text)
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
[pasteboard clearContents];
|
||||
[pasteboard writeObjects:[NSArray arrayWithObject:(NSString*)AppleUtils::ToString(text)]];
|
||||
}
|
||||
|
||||
void MacClipboard::SetRawData(const Span<byte>& data)
|
||||
{
|
||||
}
|
||||
|
||||
void MacClipboard::SetFiles(const Array<String>& files)
|
||||
{
|
||||
}
|
||||
|
||||
String MacClipboard::GetText()
|
||||
{
|
||||
NSPasteboard* pasteboard = [NSPasteboard generalPasteboard];
|
||||
NSArray* classes = [NSArray arrayWithObject:[NSString class]];
|
||||
NSDictionary* options = [NSDictionary dictionary];
|
||||
if (![pasteboard canReadObjectForClasses:classes options:options])
|
||||
return String::Empty;
|
||||
NSArray* objects = [pasteboard readObjectsForClasses:classes options:options];
|
||||
return AppleUtils::ToString((CFStringRef)[objects objectAtIndex:0]);
|
||||
}
|
||||
|
||||
Array<byte> MacClipboard::GetRawData()
|
||||
{
|
||||
return Array<byte>();
|
||||
}
|
||||
|
||||
Array<String> MacClipboard::GetFiles()
|
||||
{
|
||||
return Array<String>();
|
||||
}
|
||||
|
||||
class MacKeyboard : public Keyboard
|
||||
{
|
||||
public:
|
||||
@@ -217,215 +193,28 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
typedef uint16_t offset_t;
|
||||
#define align_mem_up(num, align) (((num) + ((align) - 1)) & ~((align) - 1))
|
||||
|
||||
bool MacPlatform::Is64BitPlatform()
|
||||
{
|
||||
return PLATFORM_64BITS;
|
||||
}
|
||||
|
||||
CPUInfo MacPlatform::GetCPUInfo()
|
||||
{
|
||||
return MacCpu;
|
||||
}
|
||||
|
||||
int32 MacPlatform::GetCacheLineSize()
|
||||
{
|
||||
return MacCpu.CacheLineSize;
|
||||
}
|
||||
|
||||
MemoryStats MacPlatform::GetMemoryStats()
|
||||
{
|
||||
MemoryStats result;
|
||||
int64 value64;
|
||||
size_t value64Size = sizeof(value64);
|
||||
if (sysctlbyname("hw.memsize", &value64, &value64Size, nullptr, 0) != 0)
|
||||
value64 = 1024 * 1024;
|
||||
result.TotalPhysicalMemory = value64;
|
||||
int id[] = { CTL_HW, HW_MEMSIZE };
|
||||
if (sysctl(id, 2, &value64, &value64Size, nullptr, 0) != 0)
|
||||
value64Size = 1024;
|
||||
result.UsedPhysicalMemory = value64Size;
|
||||
xsw_usage swapusage;
|
||||
size_t swapusageSize = sizeof(swapusage);
|
||||
result.TotalVirtualMemory = result.TotalPhysicalMemory;
|
||||
result.UsedVirtualMemory = result.UsedPhysicalMemory;
|
||||
if (sysctlbyname("vm.swapusage", &swapusage, &swapusageSize, nullptr, 0) == 0)
|
||||
{
|
||||
result.TotalVirtualMemory += swapusage.xsu_total;
|
||||
result.UsedVirtualMemory += swapusage.xsu_used;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
ProcessMemoryStats MacPlatform::GetProcessMemoryStats()
|
||||
{
|
||||
ProcessMemoryStats result;
|
||||
result.UsedPhysicalMemory = 1024;
|
||||
result.UsedVirtualMemory = 1024;
|
||||
return result;
|
||||
}
|
||||
|
||||
uint64 MacPlatform::GetCurrentThreadID()
|
||||
{
|
||||
return (uint64)pthread_mach_thread_np(pthread_self());
|
||||
}
|
||||
|
||||
void MacPlatform::SetThreadPriority(ThreadPriority priority)
|
||||
{
|
||||
// TODO: impl this
|
||||
}
|
||||
|
||||
void MacPlatform::SetThreadAffinityMask(uint64 affinityMask)
|
||||
{
|
||||
// TODO: impl this
|
||||
}
|
||||
|
||||
void MacPlatform::Sleep(int32 milliseconds)
|
||||
{
|
||||
usleep(milliseconds * 1000);
|
||||
}
|
||||
|
||||
double MacPlatform::GetTimeSeconds()
|
||||
{
|
||||
return SecondsPerCycle * mach_absolute_time();
|
||||
}
|
||||
|
||||
uint64 MacPlatform::GetTimeCycles()
|
||||
{
|
||||
return mach_absolute_time();
|
||||
}
|
||||
|
||||
uint64 MacPlatform::GetClockFrequency()
|
||||
{
|
||||
return (uint64)(1.0 / SecondsPerCycle);
|
||||
}
|
||||
|
||||
void MacPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
||||
{
|
||||
// Query for calendar time
|
||||
struct timeval time;
|
||||
gettimeofday(&time, nullptr);
|
||||
|
||||
// Convert to local time
|
||||
struct tm localTime;
|
||||
localtime_r(&time.tv_sec, &localTime);
|
||||
|
||||
// Extract time
|
||||
year = localTime.tm_year + 1900;
|
||||
month = localTime.tm_mon + 1;
|
||||
dayOfWeek = localTime.tm_wday;
|
||||
day = localTime.tm_mday;
|
||||
hour = localTime.tm_hour;
|
||||
minute = localTime.tm_min;
|
||||
second = localTime.tm_sec;
|
||||
millisecond = time.tv_usec / 1000;
|
||||
}
|
||||
|
||||
void MacPlatform::GetUTCTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
|
||||
{
|
||||
// Get the calendar time
|
||||
struct timeval time;
|
||||
gettimeofday(&time, nullptr);
|
||||
|
||||
// Convert to UTC time
|
||||
struct tm localTime;
|
||||
gmtime_r(&time.tv_sec, &localTime);
|
||||
|
||||
// Extract time
|
||||
year = localTime.tm_year + 1900;
|
||||
month = localTime.tm_mon + 1;
|
||||
dayOfWeek = localTime.tm_wday;
|
||||
day = localTime.tm_mday;
|
||||
hour = localTime.tm_hour;
|
||||
minute = localTime.tm_min;
|
||||
second = localTime.tm_sec;
|
||||
millisecond = time.tv_usec / 1000;
|
||||
}
|
||||
|
||||
bool MacPlatform::Init()
|
||||
{
|
||||
if (UnixPlatform::Init())
|
||||
if (ApplePlatform::Init())
|
||||
return true;
|
||||
|
||||
// Init timing
|
||||
{
|
||||
mach_timebase_info_data_t info;
|
||||
mach_timebase_info(&info);
|
||||
SecondsPerCycle = 1e-9 * (double)info.numer / (double)info.denom;
|
||||
}
|
||||
|
||||
// Get CPU info
|
||||
int32 value32;
|
||||
int64 value64;
|
||||
size_t value32Size = sizeof(value32), value64Size = sizeof(value64);
|
||||
if (sysctlbyname("hw.packages", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 1;
|
||||
MacCpu.ProcessorPackageCount = value32;
|
||||
if (sysctlbyname("hw.physicalcpu", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 1;
|
||||
MacCpu.ProcessorCoreCount = value32;
|
||||
if (sysctlbyname("hw.logicalcpu", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 1;
|
||||
MacCpu.LogicalProcessorCount = value32;
|
||||
if (sysctlbyname("hw.l1icachesize", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 0;
|
||||
MacCpu.L1CacheSize = value32;
|
||||
if (sysctlbyname("hw.l2cachesize", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 0;
|
||||
MacCpu.L2CacheSize = value32;
|
||||
if (sysctlbyname("hw.l3cachesize", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = 0;
|
||||
MacCpu.L3CacheSize = value32;
|
||||
if (sysctlbyname("hw.pagesize", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = vm_page_size;
|
||||
MacCpu.PageSize = value32;
|
||||
if (sysctlbyname("hw.cpufrequency_max", &value64, &value64Size, nullptr, 0) != 0)
|
||||
value64 = GetClockFrequency();
|
||||
MacCpu.ClockSpeed = value64;
|
||||
if (sysctlbyname("hw.cachelinesize", &value32, &value32Size, nullptr, 0) != 0)
|
||||
value32 = PLATFORM_CACHE_LINE_SIZE;
|
||||
MacCpu.CacheLineSize = value32;
|
||||
|
||||
// Get device id
|
||||
{
|
||||
io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/");
|
||||
CFStringRef deviceUuid = (CFStringRef)IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0);
|
||||
IOObjectRelease(ioRegistryRoot);
|
||||
String uuidStr = MacUtils::ToString(deviceUuid);
|
||||
String uuidStr = AppleUtils::ToString(deviceUuid);
|
||||
Guid::Parse(uuidStr, DeviceId);
|
||||
CFRelease(deviceUuid);
|
||||
}
|
||||
|
||||
// Get locale
|
||||
{
|
||||
CFLocaleRef locale = CFLocaleCopyCurrent();
|
||||
CFStringRef localeLang = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleLanguageCode);
|
||||
CFStringRef localeCountry = (CFStringRef)CFLocaleGetValue(locale, kCFLocaleCountryCode);
|
||||
UserLocale = MacUtils::ToString(localeLang);
|
||||
String localeCountryStr = MacUtils::ToString(localeCountry);
|
||||
if (localeCountryStr.HasChars())
|
||||
UserLocale += TEXT("-") + localeCountryStr;
|
||||
CFRelease(locale);
|
||||
CFRelease(localeLang);
|
||||
CFRelease(localeCountry);
|
||||
}
|
||||
|
||||
// Get computer name
|
||||
{
|
||||
CFStringRef computerName = SCDynamicStoreCopyComputerName(nullptr, nullptr);
|
||||
ComputerName = MacUtils::ToString(computerName);
|
||||
ComputerName = AppleUtils::ToString(computerName);
|
||||
CFRelease(computerName);
|
||||
}
|
||||
|
||||
// Init user
|
||||
{
|
||||
String username;
|
||||
GetEnvironmentVariable(TEXT("USER"), username);
|
||||
OnPlatformUserAdd(New<User>(username));
|
||||
}
|
||||
|
||||
// Find the maximum scale of the display to handle high-dpi displays scaling factor
|
||||
{
|
||||
NSArray* screenArray = [NSScreen screens];
|
||||
@@ -442,10 +231,12 @@ bool MacPlatform::Init()
|
||||
// Init application
|
||||
[NSApplication sharedApplication];
|
||||
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
|
||||
AutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
// Init main menu
|
||||
NSMenu* mainMenu = [[[NSMenu alloc] initWithTitle:@""] autorelease];
|
||||
[NSApp setMainMenu:mainMenu];
|
||||
// TODO: expose main menu for app (eg. to be used by Game or Editor on macOS-only)
|
||||
AutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
Input::Mouse = New<MacMouse>();
|
||||
Input::Keyboard = New<MacKeyboard>();
|
||||
@@ -455,7 +246,7 @@ bool MacPlatform::Init()
|
||||
|
||||
void MacPlatform::LogInfo()
|
||||
{
|
||||
UnixPlatform::LogInfo();
|
||||
ApplePlatform::LogInfo();
|
||||
|
||||
char str[250];
|
||||
size_t strSize = sizeof(str);
|
||||
@@ -488,24 +279,6 @@ void MacPlatform::Tick()
|
||||
AutoreleasePool = [[NSAutoreleasePool alloc] init];
|
||||
}
|
||||
|
||||
void MacPlatform::BeforeExit()
|
||||
{
|
||||
}
|
||||
|
||||
void MacPlatform::Exit()
|
||||
{
|
||||
}
|
||||
|
||||
void MacPlatform::SetHighDpiAwarenessEnabled(bool enable)
|
||||
{
|
||||
// Disable resolution scaling in low dpi mode
|
||||
if (!enable)
|
||||
{
|
||||
CustomDpiScale /= ScreenScale;
|
||||
ScreenScale = 1.0f;
|
||||
}
|
||||
}
|
||||
|
||||
int32 MacPlatform::GetDpi()
|
||||
{
|
||||
CGDirectDisplayID mainDisplay = CGMainDisplayID();
|
||||
@@ -515,9 +288,9 @@ int32 MacPlatform::GetDpi()
|
||||
return Math::Max(dpi, 72.0f);
|
||||
}
|
||||
|
||||
String MacPlatform::GetUserLocaleName()
|
||||
Guid MacPlatform::GetUniqueDeviceId()
|
||||
{
|
||||
return UserLocale;
|
||||
return DeviceId;
|
||||
}
|
||||
|
||||
String MacPlatform::GetComputerName()
|
||||
@@ -525,40 +298,6 @@ String MacPlatform::GetComputerName()
|
||||
return ComputerName;
|
||||
}
|
||||
|
||||
bool MacPlatform::GetHasFocus()
|
||||
{
|
||||
// Check if any window is focused
|
||||
ScopeLock lock(WindowsManager::WindowsLocker);
|
||||
for (auto window : WindowsManager::Windows)
|
||||
{
|
||||
if (window->IsFocused())
|
||||
return true;
|
||||
}
|
||||
|
||||
// Default to true if has no windows open
|
||||
return WindowsManager::Windows.IsEmpty();
|
||||
}
|
||||
|
||||
void MacPlatform::CreateGuid(Guid& result)
|
||||
{
|
||||
uuid_t uuid;
|
||||
uuid_generate(uuid);
|
||||
auto ptr = (uint32*)&uuid;
|
||||
result.A = ptr[0];
|
||||
result.B = ptr[1];
|
||||
result.C = ptr[2];
|
||||
result.D = ptr[3];
|
||||
}
|
||||
|
||||
bool MacPlatform::CanOpenUrl(const StringView& url)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
void MacPlatform::OpenUrl(const StringView& url)
|
||||
{
|
||||
}
|
||||
|
||||
Float2 MacPlatform::GetMousePosition()
|
||||
{
|
||||
CGEventRef event = CGEventCreate(nullptr);
|
||||
@@ -584,7 +323,7 @@ Float2 MacPlatform::GetDesktopSize()
|
||||
Rectangle GetDisplayBounds(CGDirectDisplayID display)
|
||||
{
|
||||
CGRect rect = CGDisplayBounds(display);
|
||||
float screnScale = MacPlatform::ScreenScale;
|
||||
float screnScale = ApplePlatform::ScreenScale;
|
||||
return Rectangle(rect.origin.x * screnScale, rect.origin.y * screnScale, rect.size.width * screnScale, rect.size.height * screnScale);
|
||||
}
|
||||
|
||||
@@ -625,54 +364,11 @@ String MacPlatform::GetMainDirectory()
|
||||
return path;
|
||||
}
|
||||
|
||||
String MacPlatform::GetExecutableFilePath()
|
||||
{
|
||||
char buf[PATH_MAX];
|
||||
uint32 size = PATH_MAX;
|
||||
String result;
|
||||
if (_NSGetExecutablePath(buf, &size) == 0)
|
||||
result.SetUTF8(buf, StringUtils::Length(buf));
|
||||
return result;
|
||||
}
|
||||
|
||||
Guid MacPlatform::GetUniqueDeviceId()
|
||||
{
|
||||
return DeviceId;
|
||||
}
|
||||
|
||||
String MacPlatform::GetWorkingDirectory()
|
||||
{
|
||||
char buffer[256];
|
||||
getcwd(buffer, ARRAY_COUNT(buffer));
|
||||
return String(buffer);
|
||||
}
|
||||
|
||||
bool MacPlatform::SetWorkingDirectory(const String& path)
|
||||
{
|
||||
return chdir(StringAsANSI<>(*path).Get()) != 0;
|
||||
}
|
||||
|
||||
Window* MacPlatform::CreateWindow(const CreateWindowSettings& settings)
|
||||
{
|
||||
return New<MacWindow>(settings);
|
||||
}
|
||||
|
||||
bool MacPlatform::GetEnvironmentVariable(const String& name, String& value)
|
||||
{
|
||||
char* env = getenv(StringAsANSI<>(*name).Get());
|
||||
if (env)
|
||||
{
|
||||
value = String(env);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MacPlatform::SetEnvironmentVariable(const String& name, const String& value)
|
||||
{
|
||||
return setenv(StringAsANSI<>(*name).Get(), StringAsANSI<>(*value).Get(), true) != 0;
|
||||
}
|
||||
|
||||
int32 MacProcess(const StringView& cmdLine, const StringView& workingDir, const Dictionary<String, String>& environment, bool waitForEnd, bool logOutput)
|
||||
{
|
||||
LOG(Info, "Command: {0}", cmdLine);
|
||||
@@ -731,7 +427,7 @@ int32 MacPlatform::StartProcess(const StringView& filename, const StringView& ar
|
||||
// Special case if filename points to the app package (use actual executable)
|
||||
String exePath = filename;
|
||||
{
|
||||
NSString* processPath = (NSString*)MacUtils::ToString(filename);
|
||||
NSString* processPath = (NSString*)AppleUtils::ToString(filename);
|
||||
if (![[NSFileManager defaultManager] fileExistsAtPath: processPath])
|
||||
{
|
||||
NSString* appName = [[processPath lastPathComponent] stringByDeletingPathExtension];
|
||||
@@ -746,7 +442,7 @@ int32 MacPlatform::StartProcess(const StringView& filename, const StringView& ar
|
||||
{
|
||||
processPath = [bundle executablePath];
|
||||
if (processPath != nil)
|
||||
exePath = MacUtils::ToString((CFStringRef)processPath);
|
||||
exePath = AppleUtils::ToString((CFStringRef)processPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -766,57 +462,4 @@ int32 MacPlatform::RunProcess(const StringView& cmdLine, const StringView& worki
|
||||
return MacProcess(cmdLine, workingDir, environment, true, true);
|
||||
}
|
||||
|
||||
void* MacPlatform::LoadLibrary(const Char* filename)
|
||||
{
|
||||
const StringAsANSI<> filenameANSI(filename);
|
||||
void* result = dlopen(filenameANSI.Get(), RTLD_LAZY | RTLD_LOCAL);
|
||||
if (!result)
|
||||
{
|
||||
LOG(Error, "Failed to load {0} because {1}", filename, String(dlerror()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void MacPlatform::FreeLibrary(void* handle)
|
||||
{
|
||||
dlclose(handle);
|
||||
}
|
||||
|
||||
void* MacPlatform::GetProcAddress(void* handle, const char* symbol)
|
||||
{
|
||||
return dlsym(handle, symbol);
|
||||
}
|
||||
|
||||
Array<MacPlatform::StackFrame> MacPlatform::GetStackFrames(int32 skipCount, int32 maxDepth, void* context)
|
||||
{
|
||||
Array<StackFrame> result;
|
||||
#if CRASH_LOG_ENABLE
|
||||
void* callstack[120];
|
||||
skipCount = Math::Min<int32>(skipCount, ARRAY_COUNT(callstack));
|
||||
int32 maxCount = Math::Min<int32>(ARRAY_COUNT(callstack), skipCount + maxDepth);
|
||||
int32 count = backtrace(callstack, maxCount);
|
||||
int32 useCount = count - skipCount;
|
||||
if (useCount > 0)
|
||||
{
|
||||
char** names = backtrace_symbols(callstack + skipCount, useCount);
|
||||
result.Resize(useCount);
|
||||
for (int32 i = 0; i < useCount; i++)
|
||||
{
|
||||
char* name = names[i];
|
||||
StackFrame& frame = result[i];
|
||||
frame.ProgramCounter = callstack[skipCount + i];
|
||||
frame.ModuleName[0] = 0;
|
||||
frame.FileName[0] = 0;
|
||||
frame.LineNumber = 0;
|
||||
int32 nameLen = Math::Min<int32>(StringUtils::Length(name), ARRAY_COUNT(frame.FunctionName) - 1);
|
||||
Platform::MemoryCopy(frame.FunctionName, name, nameLen);
|
||||
frame.FunctionName[nameLen] = 0;
|
||||
|
||||
}
|
||||
free(names);
|
||||
}
|
||||
#endif
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user