-
Notifications
You must be signed in to change notification settings - Fork 299
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Suggestion: Lazily initialize IDs #1382
Comments
FWIW, I implemented this as an extension trait, and it is way easier to use this way... use conrod_core::widget::Id;
use conrod_core::{UiCell, Widget};
pub trait WidgetExt: Widget {
fn set_opt<'a, 'b>(self, id: &mut Option<Id>, ui_cell: &'a mut UiCell<'b>) -> Self::Event;
}
impl<T: Widget> WidgetExt for T {
fn set_opt<'a, 'b>(
self,
maybe_id: &mut Option<Id>,
ui_cell: &'a mut UiCell<'b>,
) -> Self::Event {
let id = if let Some(id) = *maybe_id {
id
} else {
let id = ui_cell.widget_id_generator().next();
*maybe_id = Some(id);
id
};
self.set(id, ui_cell)
}
} |
If you do this, it gets a bit inconvenient when you need to refer to the widget by its ID, e.g. when positioning and parenting other widgets. TBH To me, the more annoying part is resizing the |
I think this is only an issue if you need to refer to the widget before drawing it, which doesn't seem too much of a burden since you can't have cycles when positioning or parenting anyway. Also, this doesn't prohibit you from initializing specific IDs early if you need to refer to them before drawing the component.
There are two problems with this beyond the ergonomics of zip.
That does seem like a bit of an oversight. If a frame is rendered without a component, then that component should be considered deleted, and the memory associated with its ID freed. To prevent IDs being exhausted, 64-bit ID should be used. |
This is somewhat true, but with your suggested API, one would still have to unwrap the
You have a point. In cases like yours it seems that an
In this case I think you can have a struct created with the In both of these cases I do agree that the ID list type provided by
I think the inherent issue is the requirement of explicit IDs, as opposed to generating IDs automatically like Dear ImGui or others. But I think it works fine for me.
I think this is debatable. Not setting a widget doesn't mean it'll not be used again, maybe the user just want it to be hidden for a while. I don't think it is really realistic for an application using |
I don't think it is a good idea. Rust has |
To ensure you handle the
Since the common case would be for IDs to be lazily initialized, it doesn't make sense for the caller to have to repeat |
TBH, you could even make the positioning/parenting operations initialize the ID if it is currently null, thereby making it completely transparent to the user. |
Nullable IDs still doesn't make much sense.
Also, using nullable IDs is a departure from idiomatic Rust. Passing
It would require taking I think nullable IDs are the wrong thing to ask for. It probably makes more sense to consider implicitly-generated IDs like other immediate mode GUIs and make explicit ID optional. However, I don't know @mitchmindtree's reasoning on making IDs explicit in |
I don't know if you can make them completely implicit - you need some way to track component state across frames.
|
Dear ImGui does it with an ID stack. The ID of a widget is typically generated from the label. Container widgets push its ID to the stack and the user can also push custom IDs to the stack to start a scope. The ID has to be popped at the end of the container or scope. A widget is identified by the hash of the widget "path", taken from the ID stack. |
Managing widget IDs feels like unnecessary boilerplate: every time I want an array of widgets I have to
zip
the widget state with myIdList
.I should just be able to put the widget ID inside my state struct, but I can't do this because initializing the ID requires a reference to the generator.
I think this boilerplate could be avoided by reserving a "null" ID value that can be default-constructed, and having the
set()
method on widgets take a&mut Id
as input. This method would check if the ID is "null" and initialize it using the ID generator from the UiCell if it is. The caller never has to do anything with the ID other than preserve it.The text was updated successfully, but these errors were encountered: