Skip to content

fix: unfreeze the export paths, repair shader error logging, validate the UI - #5

Merged
gridboy merged 3 commits into
mainfrom
fix/robustness-and-ui
Aug 11, 2026
Merged

gridboy merged 3 commits into
mainfrom
fix/robustness-and-ui

Conversation

@gridboy

@gridboy gridboy commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Replaces #2, which GitHub closed automatically when its base branch perf/render-hot-paths was deleted on merge of #1. Same commits, rebased onto main.

What this changes

Fixes a permanent UI freeze, a crash on the shader error path, unsound teardown, and the missing interface validation that made the freeze reachable.

Why

The freeze. All three export actions waited for a frame like this:

while (!depth) { depth = [self createDepthData]; }

No exit. With the device stopped or absent, _depthUpdate never turns YES, so this pinned a core on the main thread and froze the UI for good — force quit only. Nothing grayed the export menu items out, so they stayed clickable in exactly the state where they could not work. Now a bounded wait (-waitForDepthDataUntil:) that gives up after two seconds and says so in the status field, plus -validateMenuItem: / -validateUserInterfaceItem: so the actions gray out. AppKit validates menu and toolbar items only — plain buttons in the nib still need their enabled state bound there.

Shader errors. GLProgram.m logged compile failures with NSLog(@"...%s", desc, code) where desc is an NSString *. %s read the object pointer as a C string: garbage or a crash, on the single path whose job is to report shader errors. code was passed and never printed. Surfaced by -Wall.

Teardown. -[GLView dealloc] released the display link without stopping it first, while its callback still draws into the view, then let closeScene issue glDelete* calls without making the view's context current.

Threading. _device and _halt are each written on one thread and polled on the other with no barrier. Both are now volatile. This does not fix the race — it makes explicit what the polls already rely on. A real fix wants a condition variable.

Deprecated AppKit. runModalForDirectory:file: → setDirectoryURL: + runModal, NSOKButton → NSModalResponseOK, NSShiftKeyMask → NSEventModifierFlagShift, writeToFile:atomically: → the encoding:error: form. These will not compile against the 10.6 SDK the project declares.

Also: mesh indices now stream through an element buffer object instead of a client-side array copied inline at draw time, with an unbind before drawFrustrum, which still draws from a client array.

How it was verified

  • sh scripts/syntax-check.sh passes; GLProgram.m is now warning-clean
  • Behaviour-preserving comparison — not applicable, these are behaviour changes
  • Built
  • Run against real Kinect hardware

None of this is backed by observed behaviour — it is reasoning over the code plus what -Wall reports. The freeze, the %s crash and the teardown ordering are each clear from the source, but the export paths and the mesh should be confirmed on hardware.

Left alone deliberately

  • saveSTLB mixes && and || without parentheses (-Wlogical-op-parentheses). The precedence applied may not be what the author meant; parenthesising it would freeze one reading.
  • Point mode draws all 307200 points regardless of the detail setting.
  • setAllowedFileTypes: needs UniformTypeIdentifiers wired into the project file.

Provenance

  • No third-party licence header, copyright notice, CONTRIB or AUTHORS file altered
  • No new vendored code

…rdown

- The three export actions waited for a frame with an unbounded 'while (!depth)'
  spin. With the device stopped or absent - the menu items stay enabled then -
  _depthUpdate never turns YES, so this pinned a core on the main thread and froze
  the UI for good. Replaced by -waitForDepthDataUntil:, which gives up after two
  seconds and reports it in the status field.

- GLProgram logged shader compile failures with NSLog(@"...%s", desc, code) where
  desc is an NSString*. %s read the object pointer as a C string: garbage or a crash
  on the one path meant to report shader errors. code was never printed.

- -[GLView dealloc] released the display link without stopping it while its callback
  still draws into the view, then let closeScene issue glDelete* calls with no current
  context.

- Mark _device and _halt volatile. Each is written on one thread and polled on the
  other with no barrier; the polls only work because they call opaque functions that
  force a reload. The race itself is unchanged.

- Stream mesh indices through an element buffer object rather than a client-side array
  copied inline at draw time, unbinding before drawFrustrum, which still draws from a
  client array and would otherwise read its pointer as an offset.

Verified with clang -fsyntax-only -Wall against the current macOS SDK: no errors, and
GLProgram is now warning-clean. The remaining warnings are documented in the README as
deliberately untouched. Still not built or run against Kinect hardware.
The export menu items were never validated, so they stayed clickable with no device
running - the one state in which they had nothing to write and used to hang. Add
-validateMenuItem: and -validateUserInterfaceItem: so they gray out. AppKit validates
menu and toolbar items only; plain buttons in the nib still need their enabled state
bound there.

Replace AppKit calls that no longer exist or are deprecated:
- runModalForDirectory:file: -> setDirectoryURL: + runModal
- NSOKButton -> NSModalResponseOK
- NSShiftKeyMask -> NSEventModifierFlagShift
- NSString writeToFile:atomically: -> writeToFile:atomically:encoding:error:

This raises the effective deployment target well above the 10.6 the project declares.
It is a step toward building against a current SDK, not something Xcode 3 will still
compile. setAllowedFileTypes: is left alone: allowedContentTypes needs the
UniformTypeIdentifiers framework wired into the project file.

clang -fsyntax-only -Wall against the current SDK: no errors, and no new warnings
beyond the ones already documented as deliberately untouched.
Says what is true about the SDK rather than naming the IDE: the modernised AppKit calls
will not compile against the 10.6 SDK the project declares, and the UniformTypeIdentifiers
note refers to the project file.
@gridboy
gridboy merged commit 4d875ae into main Aug 11, 2026
1 check passed
@gridboy
gridboy deleted the fix/robustness-and-ui branch August 11, 2026 16:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant