From 0989b6478e0ed61853e7536e54972a3e952fae83 Mon Sep 17 00:00:00 2001 From: "M. Samil Atesoglu" Date: Sun, 19 Apr 2026 22:09:52 +0300 Subject: [PATCH] 1.4 macOS port --- .gitignore | 3 +- Plugins/nosAnimation/Source/AnimateNode.cpp | 2 +- .../nosCompositing/Source/FontRendering.cpp | 34 +++++++++++++++---- .../Source/Window/WindowNode.cpp | 4 +++ Plugins/nosFilters/Nodes/ColorCorrect.nosnode | 2 +- Plugins/nosFlow/Source/ConditionalTrigger.cpp | 2 +- Plugins/nosFlow/Source/ScheduleOnRequest.cpp | 2 +- Plugins/nosFlow/Source/SwitchTrigger.cpp | 2 +- Plugins/nosFlow/Source/TriggerOnAnyInput.cpp | 2 +- Plugins/nosUtilities/Source/Host.cpp | 10 ++++-- Subsystems/nosSync/Include/nosSync/nosSync.h | 4 +-- 11 files changed, 50 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index a9f8d80c..a9e6c80e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,5 @@ __pycache__ *_generated.h *.ptx -*.egg-info \ No newline at end of file +*.egg-info +.DS_Store diff --git a/Plugins/nosAnimation/Source/AnimateNode.cpp b/Plugins/nosAnimation/Source/AnimateNode.cpp index 65a2a6be..3578d3a4 100644 --- a/Plugins/nosAnimation/Source/AnimateNode.cpp +++ b/Plugins/nosAnimation/Source/AnimateNode.cpp @@ -132,7 +132,7 @@ struct AnimateNode : NodeContext return NOS_RESULT_SUCCESS; } - NOS_DECLARE_FUNCTIONS( + NOS_DECLARE_FUNCTIONS_FOR(AnimateNode, NOS_ADD_FUNCTION(NOS_NAME("Start"), Start), NOS_ADD_FUNCTION(NOS_NAME("Pause"), Pause), NOS_ADD_FUNCTION(NOS_NAME("Continue"), Continue), diff --git a/Plugins/nosCompositing/Source/FontRendering.cpp b/Plugins/nosCompositing/Source/FontRendering.cpp index d9b9b79d..8065a139 100644 --- a/Plugins/nosCompositing/Source/FontRendering.cpp +++ b/Plugins/nosCompositing/Source/FontRendering.cpp @@ -2,7 +2,6 @@ #include "DejaVuSansMono.hpp.dat" #define STB_IMAGE_IMPLEMENTATION #include -#include #include #include #include @@ -10,6 +9,33 @@ namespace nos::compositing { +// Decode one UTF-8 codepoint from [ptr, end). Returns bytes consumed, 0 at +// null terminator, or (size_t)-1 on invalid/truncated input. Avoids +// std::mbrtoc32 because macOS libc++ declares it with using_if_exists. +static std::size_t DecodeUtf8(const char* ptr, const char* end, char32_t& out) +{ + if (ptr >= end) + return 0; + unsigned char b0 = static_cast(ptr[0]); + if (b0 == 0) + return 0; + if (b0 < 0x80) { out = b0; return 1; } + auto cont = [](const char* p) { return static_cast(static_cast(*p) & 0x3F); }; + if ((b0 & 0xE0) == 0xC0 && ptr + 2 <= end) { + out = ((b0 & 0x1Fu) << 6) | cont(ptr + 1); + return 2; + } + if ((b0 & 0xF0) == 0xE0 && ptr + 3 <= end) { + out = ((b0 & 0x0Fu) << 12) | (cont(ptr + 1) << 6) | cont(ptr + 2); + return 3; + } + if ((b0 & 0xF8) == 0xF0 && ptr + 4 <= end) { + out = ((b0 & 0x07u) << 18) | (cont(ptr + 1) << 12) | (cont(ptr + 2) << 6) | cont(ptr + 3); + return 4; + } + return static_cast(-1); +} + static FontDescription DejaVuSansMono14pt = { DejaVuSansMono14pt_Image, sizeof(DejaVuSansMono14pt_Image), @@ -103,16 +129,12 @@ TextBuilder& TextBuilder::Add(std::string text, float cHeight, glm::vec2 positio float cUvHeight = float(Font.Description.CellHeightPx) / atlasHeight; std::vector characters; - std::mbstate_t state{}; char32_t c32; const char* ptr = text.c_str(); const char* end = text.c_str() + text.size() + 1; - while (std::size_t rc = std::mbrtoc32(&c32, ptr, end - ptr, &state)) { - assert(rc != (std::size_t)-3); + while (std::size_t rc = DecodeUtf8(ptr, end, c32)) { if (rc == (std::size_t)-1) break; - if (rc == (std::size_t)-2) - break; ptr += rc; // skip variation selectors diff --git a/Plugins/nosExperiment/Source/Window/WindowNode.cpp b/Plugins/nosExperiment/Source/Window/WindowNode.cpp index e666ddc5..17c52bc7 100644 --- a/Plugins/nosExperiment/Source/Window/WindowNode.cpp +++ b/Plugins/nosExperiment/Source/Window/WindowNode.cpp @@ -6,6 +6,8 @@ #define GLFW_EXPOSE_NATIVE_WIN32 #elif defined(__linux) #define GLFW_EXPOSE_NATIVE_X11 +#elif defined(__APPLE__) +#define GLFW_EXPOSE_NATIVE_COCOA #else #error "Unsupported platform" #endif @@ -153,6 +155,8 @@ void WindowNode::OnEnterRunnerThread(nosEnterRunnerThreadParams const& params) glfwGetWin32Window(Window) #elif defined(__linux) glfwGetX11Window(Window) +#elif defined(__APPLE__) + glfwGetCocoaWindow(Window) #else #error "Unsupported platform" #endif diff --git a/Plugins/nosFilters/Nodes/ColorCorrect.nosnode b/Plugins/nosFilters/Nodes/ColorCorrect.nosnode index 40c1afca..0a3b29f0 100644 --- a/Plugins/nosFilters/Nodes/ColorCorrect.nosnode +++ b/Plugins/nosFilters/Nodes/ColorCorrect.nosnode @@ -15,7 +15,7 @@ "contents": { "type": "nos.sys.vulkan.GPUNode", "options": { - "shader": "Shaders/ColorCorrect.hlsl", + "shader": "Shaders/ColorCorrect.frag", "stage": "FRAGMENT" } }, diff --git a/Plugins/nosFlow/Source/ConditionalTrigger.cpp b/Plugins/nosFlow/Source/ConditionalTrigger.cpp index e4fc965e..cde60885 100644 --- a/Plugins/nosFlow/Source/ConditionalTrigger.cpp +++ b/Plugins/nosFlow/Source/ConditionalTrigger.cpp @@ -19,7 +19,7 @@ struct ConditionalTrigger : NodeContext return NOS_RESULT_SUCCESS; } - NOS_DECLARE_FUNCTIONS( + NOS_DECLARE_FUNCTIONS_FOR(ConditionalTrigger, NOS_ADD_FUNCTION(NOS_NAME("Branch"), Branch), ); }; diff --git a/Plugins/nosFlow/Source/ScheduleOnRequest.cpp b/Plugins/nosFlow/Source/ScheduleOnRequest.cpp index 19ddec86..442961a3 100644 --- a/Plugins/nosFlow/Source/ScheduleOnRequest.cpp +++ b/Plugins/nosFlow/Source/ScheduleOnRequest.cpp @@ -68,7 +68,7 @@ struct ScheduleOnRequestNode : NodeContext return NOS_RESULT_SUCCESS; } - NOS_DECLARE_FUNCTIONS( + NOS_DECLARE_FUNCTIONS_FOR(ScheduleOnRequestNode, NOS_ADD_FUNCTION(NSN_Request, Request)) }; diff --git a/Plugins/nosFlow/Source/SwitchTrigger.cpp b/Plugins/nosFlow/Source/SwitchTrigger.cpp index 6d93d4f1..7b12d8a1 100644 --- a/Plugins/nosFlow/Source/SwitchTrigger.cpp +++ b/Plugins/nosFlow/Source/SwitchTrigger.cpp @@ -217,7 +217,7 @@ struct SwitchTrigger : NodeContext return NOS_RESULT_SUCCESS; } - NOS_DECLARE_FUNCTIONS( + NOS_DECLARE_FUNCTIONS_FOR(SwitchTrigger, NOS_ADD_FUNCTION(NOS_NAME("Switch"), Switch), ); }; diff --git a/Plugins/nosFlow/Source/TriggerOnAnyInput.cpp b/Plugins/nosFlow/Source/TriggerOnAnyInput.cpp index f3e7cfd5..893432e2 100644 --- a/Plugins/nosFlow/Source/TriggerOnAnyInput.cpp +++ b/Plugins/nosFlow/Source/TriggerOnAnyInput.cpp @@ -13,7 +13,7 @@ struct TriggerOnAnyInput : NodeContext return NOS_RESULT_SUCCESS; } - NOS_DECLARE_FUNCTIONS( + NOS_DECLARE_FUNCTIONS_FOR(TriggerOnAnyInput, NOS_ADD_FUNCTION(NOS_NAME("Trigger"), Branch), ); }; diff --git a/Plugins/nosUtilities/Source/Host.cpp b/Plugins/nosUtilities/Source/Host.cpp index c481c31c..af0cee3d 100644 --- a/Plugins/nosUtilities/Source/Host.cpp +++ b/Plugins/nosUtilities/Source/Host.cpp @@ -98,9 +98,15 @@ long long GetUpTime() // Windows-specific implementation return GetTickCount64() / 1000; // Returns uptime in seconds #elif __unix__ || __unix || __linux__ || __APPLE__ - // Unix-based (Linux, macOS, etc.) implementation + // Unix-based (Linux, macOS, etc.) implementation. + // macOS libc lacks CLOCK_BOOTTIME; CLOCK_MONOTONIC is the closest analogue. +#if defined(__APPLE__) + constexpr clockid_t kUptimeClock = CLOCK_MONOTONIC; +#else + constexpr clockid_t kUptimeClock = CLOCK_BOOTTIME; +#endif struct timespec ts; - if (clock_gettime(CLOCK_BOOTTIME, &ts) == 0) { + if (clock_gettime(kUptimeClock, &ts) == 0) { return ts.tv_sec; } else { diff --git a/Subsystems/nosSync/Include/nosSync/nosSync.h b/Subsystems/nosSync/Include/nosSync/nosSync.h index 6603da0c..68cb73cc 100644 --- a/Subsystems/nosSync/Include/nosSync/nosSync.h +++ b/Subsystems/nosSync/Include/nosSync/nosSync.h @@ -11,8 +11,8 @@ NOS_BEGIN_C_LINKAGE -#define NOS_SYNC_DEFAULT_EVENT_GROUP_ID 1UL -#define NOS_SYNC_NO_SYNC_EVENT_GROUP_ID 0UL +#define NOS_SYNC_DEFAULT_EVENT_GROUP_ID 1u +#define NOS_SYNC_NO_SYNC_EVENT_GROUP_ID 0u typedef struct nosWaitResult { uint64_t TimeSinceLastEventNs;