Handling of Begin/End pairs
sheaf opened this issue · comments
Is there any situation in which users might need to use beginXXX
/endXXX
in an atypical way? As far as I understand:
begin
/end
,beginChild
/endChild
,beginGroup
/endGroup
,beginTooltip
/endTooltip
,beginChildFrame
/endChildFrame
must always occur in matching pairs, so we can replace them with simplewith
-style functions,beginCombo
/endCombo
,beginListBox
/endListBox
,beginMenuBar
/endMenuBar
,beginMainMenuBar
/endMainMenuBar
,beginPopup
/endPopup
,beginTable
/endTable
,beginTabBar
/endTabBar
,beginDragDropSource
/endDragDropSource
,beginDragDropTarget
/endDragDropTarget
all require a matchingend
function precisely when thebegin
function returnedTrue
. Is there any other way to use them than with thewhenTrue
idiom we are currently using in the example?
If there is literally no other valid usage pattern, I would recommend entirely replacing the beginXXX
/endXXX
functions with bracketed functions. Then users aren't confused about which one to use, and can't get it wrong.
If there are valid usage patterns, then of course we should keep the individual beginXXX
/endXXX
functions, and provide additional helpers.
I think we're trying to be as faithful to the C bindings as possible. I was going to put bracket-like functions in DearImgui.Simple
or something (or maybe that's was DearImgui
is and we have DearImgui.Raw
, like SDL)
Mandating with
-style may mess with some nontrivial control flow that may be used to generate UI.
I'm (+) 1
on making them readily available and doing the right thing.
Stowing away SDL-style raw bindings is a good idea too.
I just tried adding a with
-wrapper with Control.Exception.bracket
and was instantly struck down by MonadIO
constraint clashing with rigid IO type.
That can be handled with at least the following options:
- Provide "sequential" brackets of the form
(beginXXX name >>= action) <* endXXX
. - Use
base
bracket and restrict actions to IO. - Switch to
unliftio
bracket (and useMonadUnliftIO
everywhere).
My preferences are 3 > 1 >> 2. But don't have a clear model of what should happen when some widget-emitting code errors out.
Given how unsound exception handling during UI construction is I went forth and made at least basic begin/action/end sequence wrappers.
Given how unsound exception handling during UI construction is I went forth and made at least basic begin/action/end sequence wrappers.
Nevermind, in the PR I added unliftio to deps and used its brackets.
Nevermind, in the PR I added unliftio to deps and used its brackets.
Yeah, I think that's the best way to go. We're already using unliftio
for the Vulkan backend anyway.