Date: Wed, 30 Mar 2022 13:32:08 -0400
From: Luke Iannini
Subject: Depth-first when unmatched
On re-encountering the Vulkan construction/destruction conundrum I had an idea I can’t remember if we’ve discussed before (apologies if so!)

If “When unmatched” was guaranteed to run deterministically "depth-first"...

i.e. I could write

-- Create displays
When (your_area) is the rendering area:
    Call create_display_object() returning /VkDisplay* display/.
    When unmatched [capturing (display)]:
vkDestroyDisplay(display);
    End
    Claim (display) is a “display”.
End

-- Create framebuffers
When /display/ is a “display":
    Call create_framebuffer_object_for_display(display) returning /VkFramebuffer* framebuffer/.
    When unmatched [capturing (framebuffer)]:
        vkDestroyFramebuffer(framebuffer);
    End
    Claim (display) has framebuffer (framebuffer).
End

-- Create color images
When /display/ has framebuffer /framebuffer/:
    Call create_color_image_for_framebuffer(framebuffer) returning /VkImage* color_image/.
    When unmatched [capturing (color_image)]:
        vkDestroyImage(color_image);
    End
    Claim (framebuffer) has color image (color_image).
End

and I could be sure that when “Create displays” is edited or removed, the When-unmatcheds will run in a deterministic order of “Create color images” -> then “Create framebuffers” -> then “Create displays”, then everything should work perfectly with no further external state tracking needed.

This is basically the Vulkan API decree — that any Object B that is created from Object A must be destroyed before destroying Object A, and I think it’s common enough in resource acquisition/release APIs that this would be a useful property in general.

I don’t have the latest reactor loaded into my brain at the moment so I don’t know how feasible this is!