-
Notifications
You must be signed in to change notification settings - Fork 37
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
Better API for writing widget data #39
Comments
Zig 0.11.0's support for local (filesystem) packages is garbage. The latest dev version fixed it, but dvui can't compile with it. |
I didn't think about using dataSet/dataGet for large data, but you can get what you want. This example only calls dataSet() the first time. dataGet() will return a slice pointing to the internal data if given a slice type. var hbox = try dvui.box(@src(), .horizontal, .{});
defer hbox.deinit();
var buf: []u8 = undefined;
if (dvui.dataGet(null, hbox.wd.id, "data_key", []u8)) |data| {
buf = data;
} else {
var stack_buf: [1024]u8 = undefined;
@memset(&stack_buf, 0);
buf = &stack_buf;
dvui.dataSet(null, hbox.wd.id, "data_key", buf);
buf = dvui.dataGet(null, hbox.wd.id, "data_key", []u8).?;
}
var te = try dvui.textEntry(@src(), .{
.text = buf,
}, .{});
te.deinit(); For the other question, should we again follow zig master? I figured using a stable zig would be easier, but maybe everybody trying dvui right now is happy to keep up with the breakage? |
Zig master is breaking every day; not worth it in my opinion. I found a way to just edit content inside ~/.cache/zig/p/XXXXXXXX. |
This line, the lifetime seems weird. dvui.dataSet(null, hbox.wd.id, "data_key", buf); |
Good to know about zig master. We'll stay on 0.11.x for now. Options for the textEntry buffer if you don't want to manage the storage yourself:
Does 1 work for you? 2 seems like maybe we'll need that eventually but I'm less sure how useful it'd be without a clear use-case to drive the design. |
I think you have misunderstood me. I was confused because the behavior of the following two signatures are not the same. dvui.dataSet(_, _, _, []u8); // copy the slice content (external to []u8)
dvui.dataSet(_, _, _, struct{}); // copy the data (only struct{}) In Zig, |
Yep - sorry totally misunderstood. You are right that the behavior is a bit weird. It seemed okay when I wrote it, but it needs to be clearer. Thanks for pointing it out! How about we make dataSet() always copy only the given data, and add a dataSetSlice() (and dataGetSlice()) for the other case? |
This is ok. I think a better design is to have the API tied up as There's also the hashmap api const entry = dvui.dataGetOrPut(..., [1024]u8);
if (entry.exists) { ... } else {
entry.value_ptr.* = ...;
} |
I've committed what I hope is a better api for this. I spent a lot of time playing around with different versions of it.
Does this work for you? Also I was trying to think of a time when you would want to store only the ptr+len of a slice, and not the contents, but am having trouble. Do you have a use-case in mind for that? |
I still don't like this. Maybe the data is managed externally.
I think copy_slice=false should be the default and only behavior.
So
I don't know if this is necessary part of the API, since it uses
No. I have wrote an application, where I fetch JSON from network, and decode it. The result object is managed by libgc (bohem GC). I don't want to copy the strings since it's not necessary. |
I still think that Zig's HashMap API is good.
Why fill with undefined and return pointer: the "default" value may need some calculation; we should only calculate the value when it is needed. Of course, the user can pass in |
I'm confused by this. What data is being copied that you don't want? If you pass a slice to dataSetAdvanced with copy_slice false, then only the ptr+len is being stored. dataGetPtr will return a pointer to that ptr+len. Is that not what you are seeing? The problem with copying the hashmap api is precisely that many times I've wanted widgets to store short strings. Like a dialog will store the title and message, which are cleaned up once the dialog stops being shown. When I tried having a slice-specific version, then it was easy to use the regular one and end up with a slice to temporary storage. You are right that dataGet and the default is not strictly necessary. But dataGet is very useful for the common case of a widget wanting to store a bool, or a Rect. Any code that is using more of an immutable style. You are also right the Default variants aren't necessary either. Probably should remove them and live with that for a while. |
The problem about copying data is another small optimization issue. a different problem. Let's say you have some data already. In some cases, you don't have the data already. You want dvui to give you a location (pointer) to put those data. There's no copy here because you generate the data at the target location. |
Internal API doesn't have to be the same as public API. You can preserve the current |
Yes - thank you for the example of the JSON - that motivates wanting to store a slice but not the contents. I think we both have reasonable but different ideas of what the more common use cases are vs. less common. Does the api now at least support what you want to do? If it does, why don't we live with it for a while and revisit it with more experience at some point? |
My opinion is that API should be consistent. For generics, it means doing the same thing for every type in Zig. It means no surprises if people don't read the docs carefully.
If you say so. Can you explain clearly in the comments what is a "slice"? Currently it wrote:
Zig has so many slices... |
I've tried to make it better by listing the two possibilities ( Thanks for listing the sentinel slice, because those were broken. I've committed code to support them. I will look into whether zig's std.mem.sliceAsBytes should include the sentinel value. It doesn't right now, and I'm pretty sure it should. |
maybe only support It still feels weird to copy slice content, since slices in Zig are not owning. |
You convinced me to try it the explicit way. Thanks for being persistent! I changed it back so that your way is the default, and to copy the slice contents you call dataSetSlice/dataGetSlice. We'll try that for a while and see if it trips up anybody. I'm primarily worried about people doing Thanks very much! |
Currently
dvui.dataSet
copies too much data.I have the following code:
Here, 1024 bytes of data is copied per frame per widget.
I hope I can just get a slice to the memory location, then I can modify that directly.
The text was updated successfully, but these errors were encountered: