Mac impl progress

This commit is contained in:
Wojtek Figat
2021-12-28 18:45:40 +01:00
parent a1ef7ddcf7
commit 378ddc66c7
12 changed files with 111 additions and 326 deletions

View File

@@ -8,6 +8,8 @@
#include "Unix/UnixConditionVariable.h" #include "Unix/UnixConditionVariable.h"
#elif PLATFORM_SWITCH #elif PLATFORM_SWITCH
#include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h" #include "Platforms/Switch/Engine/Platform/SwitchConditionVariable.h"
#elif PLATFORM_MAC
#include "Mac/MacConditionVariable.h"
#else #else
#error Missing Condition Variable implementation! #error Missing Condition Variable implementation!
#endif #endif

View File

@@ -8,6 +8,8 @@
#include "Unix/UnixCriticalSection.h" #include "Unix/UnixCriticalSection.h"
#elif PLATFORM_SWITCH #elif PLATFORM_SWITCH
#include "Platforms/Switch/Engine/Platform/SwitchCriticalSection.h" #include "Platforms/Switch/Engine/Platform/SwitchCriticalSection.h"
#elif PLATFORM_MAC
#include "Mac/MacCriticalSection.h"
#else #else
#error Missing Critical Section implementation! #error Missing Critical Section implementation!
#endif #endif

View File

@@ -15,7 +15,6 @@ class MacConditionVariable;
class FLAXENGINE_API MacCriticalSection class FLAXENGINE_API MacCriticalSection
{ {
friend MacConditionVariable; friend MacConditionVariable;
private: private:
pthread_mutex_t _mutex; pthread_mutex_t _mutex;

View File

@@ -73,7 +73,6 @@ MacFile* MacFile::Open(const StringView& path, FileMode mode, FileAccess access,
auto handle = open(pathANSI.Get(), flags, omode); auto handle = open(pathANSI.Get(), flags, omode);
if (handle == -1) if (handle == -1)
{ {
LOG_Mac_LAST_ERROR;
return nullptr; return nullptr;
} }
@@ -91,7 +90,6 @@ bool MacFile::Read(void* buffer, uint32 bytesToRead, uint32* bytesRead)
} }
if (bytesRead) if (bytesRead)
*bytesRead = 0; *bytesRead = 0;
LOG_Mac_LAST_ERROR;
return true; return true;
} }
@@ -106,7 +104,6 @@ bool MacFile::Write(const void* buffer, uint32 bytesToWrite, uint32* bytesWritte
} }
if (bytesWritten) if (bytesWritten)
*bytesWritten = 0; *bytesWritten = 0;
LOG_Mac_LAST_ERROR;
return true; return true;
} }

View File

@@ -12,7 +12,6 @@
#include "Engine/Utilities/StringConverter.h" #include "Engine/Utilities/StringConverter.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/sendfile.h>
#include <unistd.h> #include <unistd.h>
#include <stdio.h> #include <stdio.h>
#include <cerrno> #include <cerrno>
@@ -309,37 +308,24 @@ bool MacFileSystem::CopyFile(const StringView& dst, const StringView& src)
if (dstFile < 0) if (dstFile < 0)
goto out_error; goto out_error;
// first try the kernel method while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0)
struct stat statBuf;
fstat(srcFile, &statBuf);
readSize = 1;
while (readSize > 0)
{ {
readSize = sendfile(dstFile, srcFile, 0, statBuf.st_size); char* ptr = buffer;
} ssize_t writeSize;
// sendfile could fail for example if the input file is not nmap'able
// in this case we fall back to the read/write loop
if (readSize < 0)
{
while (readSize = read(srcFile, buffer, sizeof(buffer)), readSize > 0)
{
char* ptr = buffer;
ssize_t writeSize;
do do
{
writeSize = write(dstFile, ptr, readSize);
if (writeSize >= 0)
{ {
writeSize = write(dstFile, ptr, readSize); readSize -= writeSize;
if (writeSize >= 0) ptr += writeSize;
{ }
readSize -= writeSize; else if (errno != EINTR)
ptr += writeSize; {
} goto out_error;
else if (errno != EINTR) }
{ } while (readSize > 0);
goto out_error;
}
} while (readSize > 0);
}
} }
if (readSize == 0) if (readSize == 0)

View File

@@ -32,17 +32,21 @@
#include <unistd.h> #include <unistd.h>
#include <cstdint> #include <cstdint>
#include <stdlib.h> #include <stdlib.h>
#include <sys/time.h>
#include <mach/mach_time.h>
CPUInfo MacCpu; CPUInfo MacCpu;
Guid DeviceId; Guid DeviceId;
String UserLocale, ComputerName; String UserLocale, ComputerName;
byte MacAddress[6]; byte MacAddress[6];
double SecondsPerCycle;
DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon) DialogResult MessageBox::Show(Window* parent, const StringView& text, const StringView& caption, MessageBoxButtons buttons, MessageBoxIcon icon)
{ {
if (CommandLine::Options.Headless) if (CommandLine::Options.Headless)
return DialogResult::None; return DialogResult::None;
todo; // TODO: impl message box on Mac
return DialogResult::None;
} }
class MacKeyboard : public Keyboard class MacKeyboard : public Keyboard
@@ -147,7 +151,7 @@ ProcessMemoryStats MacPlatform::GetProcessMemoryStats()
return ProcessMemoryStats(); // TODO: platform stats on Mac return ProcessMemoryStats(); // TODO: platform stats on Mac
} }
uint64 UnixPlatform::GetCurrentProcessId() uint64 MacPlatform::GetCurrentProcessId()
{ {
return getpid(); return getpid();
} }
@@ -176,20 +180,17 @@ void MacPlatform::Sleep(int32 milliseconds)
double MacPlatform::GetTimeSeconds() double MacPlatform::GetTimeSeconds()
{ {
MISSING_CODE("MacPlatform::GetTimeSeconds"); return SecondsPerCycle * mach_absolute_time();
return 0.0; // TODO: clock on Mac
} }
uint64 MacPlatform::GetTimeCycles() uint64 MacPlatform::GetTimeCycles()
{ {
MISSING_CODE("MacPlatform::GetTimeCycles"); return mach_absolute_time();
return 0; // TODO: clock on Mac
} }
uint64 MacPlatform::GetClockFrequency() uint64 MacPlatform::GetClockFrequency()
{ {
MISSING_CODE("MacPlatform::GetClockFrequency"); return (uint64)(1.0 / SecondsPerCycle);
return 0; // TODO: clock on Mac
} }
void MacPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond) void MacPlatform::GetSystemTime(int32& year, int32& month, int32& dayOfWeek, int32& day, int32& hour, int32& minute, int32& second, int32& millisecond)
@@ -238,7 +239,14 @@ bool MacPlatform::Init()
{ {
if (PlatformBase::Init()) if (PlatformBase::Init())
return true; return true;
// Init timing
{
mach_timebase_info_data_t info;
mach_timebase_info(&info);
SecondsPerCycle = 1e-9 * (double)info.numer / (double)info.denom;
}
// TODO: get MacCpu // TODO: get MacCpu
// TODO: get MacAddress // TODO: get MacAddress
@@ -250,8 +258,8 @@ bool MacPlatform::Init()
// TODO: get UserLocale // TODO: get UserLocale
// TODO: get ComputerName // TODO: get ComputerName
Input::Mouse = Impl::Mouse = New<MacMouse>(); Input::Mouse = New<MacMouse>();
Input::Keyboard = Impl::Keyboard = New<MacKeyboard>(); Input::Keyboard = New<MacKeyboard>();
return false; return false;
} }
@@ -275,7 +283,8 @@ void MacPlatform::Exit()
int32 MacPlatform::GetDpi() int32 MacPlatform::GetDpi()
{ {
return todo; // TODO: Screen DPI on Mac
return 96;
} }
String MacPlatform::GetUserLocaleName() String MacPlatform::GetUserLocaleName()

View File

@@ -9,269 +9,8 @@
#include <cstring> #include <cstring>
#include <stdlib.h> #include <stdlib.h>
bool StringUtils::IsUpper(char c) // Reuse Unix-impl
{ #define PLATFORM_UNIX 1
return isupper(c) != 0; #include "../Unix/UnixStringUtils.cpp"
}
bool StringUtils::IsLower(char c)
{
return islower(c) != 0;
}
bool StringUtils::IsAlpha(char c)
{
return iswalpha(c) != 0;
}
bool StringUtils::IsPunct(char c)
{
return ispunct(c) != 0;
}
bool StringUtils::IsAlnum(char c)
{
return isalnum(c) != 0;
}
bool StringUtils::IsDigit(char c)
{
return isdigit(c) != 0;
}
bool StringUtils::IsHexDigit(char c)
{
return isxdigit(c) != 0;
}
bool StringUtils::IsWhitespace(char c)
{
return isspace(c) != 0;
}
char StringUtils::ToUpper(char c)
{
return toupper(c);
}
char StringUtils::ToLower(char c)
{
return tolower(c);
}
bool StringUtils::IsUpper(Char c)
{
return iswupper(c) != 0;
}
bool StringUtils::IsLower(Char c)
{
return iswlower(c) != 0;
}
bool StringUtils::IsAlpha(Char c)
{
return iswalpha(c) != 0;
}
bool StringUtils::IsPunct(Char c)
{
return iswpunct(c) != 0;
}
bool StringUtils::IsAlnum(Char c)
{
return iswalnum(c) != 0;
}
bool StringUtils::IsDigit(Char c)
{
return iswdigit(c) != 0;
}
bool StringUtils::IsHexDigit(Char c)
{
return iswxdigit(c) != 0;
}
bool StringUtils::IsWhitespace(Char c)
{
return iswspace(c) != 0;
}
Char StringUtils::ToUpper(Char c)
{
return towupper(c);
}
Char StringUtils::ToLower(Char c)
{
return towlower(c);
}
int32 StringUtils::Compare(const Char* str1, const Char* str2)
{
Char c1, c2;
int32 i;
do
{
c1 = *str1++;
c2 = *str2++;
i = (int32)c1 - (int32)c2;
} while (i == 0 && c1 && c2);
return i;
}
int32 StringUtils::Compare(const Char* str1, const Char* str2, int32 maxCount)
{
Char c1, c2;
int32 i;
if (maxCount == 0)
return 0;
do
{
c1 = *str1++;
c2 = *str2++;
i = (int32)c1 - (int32)c2;
maxCount--;
} while (i == 0 && c1 && c2 && maxCount);
return i;
}
int32 StringUtils::CompareIgnoreCase(const Char* str1, const Char* str2)
{
Char c1, c2;
int32 i;
do
{
c1 = ToLower(*str1++);
c2 = ToLower(*str2++);
i = (int32)c1 - (int32)c2;
} while (i == 0 && c1 && c2);
return i;
}
int32 StringUtils::CompareIgnoreCase(const Char* str1, const Char* str2, int32 maxCount)
{
Char c1, c2;
int32 i;
if (maxCount == 0)
return 0;
do
{
c1 = ToLower(*str1++);
c2 = ToLower(*str2++);
i = (int32)c1 - (int32)c2;
maxCount--;
} while (i == 0 && c1 && c2 && maxCount);
return i;
}
int32 StringUtils::Length(const Char* str)
{
if (!str)
return 0;
const Char* ptr = str;
for (; *ptr; ++ptr)
{
}
return ptr - str;
}
int32 StringUtils::Length(const char* str)
{
if (!str)
return 0;
return static_cast<int32>(strlen(str));
}
int32 StringUtils::Compare(const char* str1, const char* str2)
{
return strcmp(str1, str2);
}
int32 StringUtils::Compare(const char* str1, const char* str2, int32 maxCount)
{
return strncmp(str1, str2, maxCount);
}
int32 StringUtils::CompareIgnoreCase(const char* str1, const char* str2)
{
return strcasecmp(str1, str2);
}
int32 StringUtils::CompareIgnoreCase(const char* str1, const char* str2, int32 maxCount)
{
return strncasecmp(str1, str2, maxCount);
}
Char* StringUtils::Copy(Char* dst, const Char* src)
{
Char* q = dst;
const Char* p = src;
Char ch;
do
{
*q++ = ch = *p++;
} while (ch);
return dst;
}
Char* StringUtils::Copy(Char* dst, const Char* src, int32 count)
{
Char* q = dst;
const Char* p = src;
char ch;
while (count)
{
count--;
*q++ = ch = *p++;
if (!ch)
break;
}
*q = 0;
return dst;
}
const Char* StringUtils::Find(const Char* str, const Char* toFind)
{
while (*str)
{
const Char* start = str;
const Char* sub = toFind;
// If first character of sub string match, check for whole string
while (*str && *sub && *str == *sub)
{
str++;
sub++;
}
// If complete substring match, return starting address
if (!*sub)
return (Char*)start;
// Increment main string
str = start + 1;
}
// No matches
return nullptr;
}
const char* StringUtils::Find(const char* str, const char* toFind)
{
return strstr(str, toFind);
}
void StringUtils::ConvertANSI2UTF16(const char* from, Char* to, int32 len)
{
todo;
}
void StringUtils::ConvertUTF162ANSI(const Char* from, char* to, int32 len)
{
todo;
}
#endif #endif

View File

@@ -3,21 +3,66 @@
#if PLATFORM_MAC #if PLATFORM_MAC
#include "MacThread.h" #include "MacThread.h"
#include "Engine/Core/Log.h"
#include "Engine/Threading/IRunnable.h" #include "Engine/Threading/IRunnable.h"
#include "Engine/Threading/ThreadRegistry.h" #include "Engine/Threading/ThreadRegistry.h"
MacThread::MacThread(IRunnable* runnable, const String& name, ThreadPriority priority) MacThread::MacThread(IRunnable* runnable, const String& name, ThreadPriority priority)
: ThreadBase(runnable, name, priority) : ThreadBase(runnable, name, priority)
, _thread(0)
{ {
} }
MacThread::~MacThread() MacThread::~MacThread()
{ {
ASSERT(_thread == 0);
} }
MacThread* Create(IRunnable* runnable, const String& name, ThreadPriority priority = ThreadPriority::Normal, uint32 stackSize = 0) MacThread* MacThread::Create(IRunnable* runnable, const String& name, ThreadPriority priority, uint32 stackSize)
{ {
// TODO: imp this auto thread = New<MacThread>(runnable, name, priority);
pthread_attr_t attr;
pthread_attr_init(&attr);
if (stackSize != 0)
pthread_attr_setstacksize(&attr, stackSize);
const int32 result = pthread_create(&thread->_thread, &attr, ThreadProc, thread);
if (result != 0)
{
LOG(Warning, "Failed to spawn a thread. Result code: {0}", result);
Delete(thread);
return nullptr;
}
thread->SetPriorityInternal(thread->GetPriority());
return thread;
}
void MacThread::Join()
{
pthread_join(_thread, nullptr);
}
void* MacThread::ThreadProc(void* pThis)
{
auto thread = (MacThread*)pThis;
const int32 exitCode = thread->Run();
return (void*)(uintptr)exitCode;
}
void MacThread::ClearHandleInternal()
{
_thread = 0;
}
void MacThread::SetPriorityInternal(ThreadPriority priority)
{
// TODO: impl this
}
void MacThread::KillInternal(bool waitForJoin)
{
if (waitForJoin)
pthread_join(_thread, nullptr);
pthread_kill(_thread, SIGKILL);
} }
#endif #endif

View File

@@ -11,6 +11,10 @@
/// </summary> /// </summary>
class MacThread : public ThreadBase class MacThread : public ThreadBase
{ {
protected:
pthread_t _thread;
public: public:
MacThread(IRunnable* runnable, const String& name, ThreadPriority priority); MacThread(IRunnable* runnable, const String& name, ThreadPriority priority);
@@ -22,10 +26,12 @@ public:
protected: protected:
static void* ThreadProc(void* pThis);
// [ThreadBase] // [ThreadBase]
void ClearHandleInternal(); void ClearHandleInternal() override;
void SetPriorityInternal(ThreadPriority priority); void SetPriorityInternal(ThreadPriority priority) override;
void KillInternal(bool waitForJoin); void KillInternal(bool waitForJoin) override;
}; };
#endif #endif

View File

@@ -3,6 +3,7 @@
#if PLATFORM_MAC #if PLATFORM_MAC
#include "../Window.h" #include "../Window.h"
#include "Engine/Graphics/RenderTask.h"
MacWindow::MacWindow(const CreateWindowSettings& settings) MacWindow::MacWindow(const CreateWindowSettings& settings)
: WindowBase(settings) : WindowBase(settings)
@@ -91,13 +92,4 @@ void MacWindow::SetIsFullscreen(bool isFullscreen)
{ {
} }
void MacWindow::GetScreenInfo(int32& x, int32& y, int32& width, int32& height) const
{
// TODO: proper screen info
x = 0;
y = 0;
width = (int32)_clientSize.X;
height = (int32)_clientSize.Y;
}
#endif #endif

View File

@@ -234,6 +234,8 @@ namespace Flax.Build
{ {
if (options.Platform.Target == TargetPlatform.PS5) if (options.Platform.Target == TargetPlatform.PS5)
return false; // TODO: mono for ps5 return false; // TODO: mono for ps5
if (options.Platform.Target == TargetPlatform.Mac)
return false; // TODO: mono for Mac
return UseCSharp || options.Target.IsEditor; return UseCSharp || options.Target.IsEditor;
} }
} }

View File

@@ -14,6 +14,8 @@ namespace Flax.Build.Platforms
/// <seealso cref="Toolchain" /> /// <seealso cref="Toolchain" />
public sealed class MacToolchain : Toolchain public sealed class MacToolchain : Toolchain
{ {
private string MinMacOSXVer = "10.14";
public string ToolchainPath; public string ToolchainPath;
public string SdkPath; public string SdkPath;
public string ClangPath; public string ClangPath;
@@ -118,12 +120,16 @@ namespace Flax.Build.Platforms
commonArgs.Add("c++"); commonArgs.Add("c++");
commonArgs.Add("-std=c++14"); commonArgs.Add("-std=c++14");
commonArgs.Add("-stdlib=libc++"); commonArgs.Add("-stdlib=libc++");
commonArgs.Add("-mmacosx-version-min=" + MinMacOSXVer);
commonArgs.Add("-Wdelete-non-virtual-dtor"); commonArgs.Add("-Wdelete-non-virtual-dtor");
commonArgs.Add("-fno-math-errno"); commonArgs.Add("-fno-math-errno");
commonArgs.Add("-fasm-blocks"); commonArgs.Add("-fasm-blocks");
commonArgs.Add("-fdiagnostics-format=msvc"); commonArgs.Add("-fdiagnostics-format=msvc");
commonArgs.Add("-Wno-absolute-value");
commonArgs.Add("-Wno-nullability-completeness");
// Hide all symbols by default // Hide all symbols by default
commonArgs.Add("-fvisibility-inlines-hidden"); commonArgs.Add("-fvisibility-inlines-hidden");
commonArgs.Add("-fvisibility-ms-compat"); commonArgs.Add("-fvisibility-ms-compat");
@@ -218,14 +224,12 @@ namespace Flax.Build.Platforms
{ {
var linkEnvironment = options.LinkEnv; var linkEnvironment = options.LinkEnv;
var task = graph.Add<LinkTask>(); var task = graph.Add<LinkTask>();
Console.WriteLine("Linking " + outputFilePath + " as " + linkEnvironment.Output);
foreach (var f in linkEnvironment.InputFiles)
Console.WriteLine(f);
// Setup arguments // Setup arguments
var args = new List<string>(); var args = new List<string>();
{ {
args.Add(string.Format("-o \"{0}\"", outputFilePath)); args.Add(string.Format("-o \"{0}\"", outputFilePath));
args.Add("-mmacosx-version-min=" + MinMacOSXVer);
if (!options.LinkEnv.DebugInformation) if (!options.LinkEnv.DebugInformation)
args.Add("-Wl,--strip-debug"); args.Add("-Wl,--strip-debug");
@@ -233,7 +237,9 @@ namespace Flax.Build.Platforms
switch (linkEnvironment.Output) switch (linkEnvironment.Output)
{ {
case LinkerOutput.Executable: case LinkerOutput.Executable:
break;
case LinkerOutput.SharedLibrary: case LinkerOutput.SharedLibrary:
args.Add("-dynamiclib");
break; break;
case LinkerOutput.StaticLibrary: case LinkerOutput.StaticLibrary:
case LinkerOutput.ImportLibrary: case LinkerOutput.ImportLibrary: