-
Notifications
You must be signed in to change notification settings - Fork 36
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
Persistent dataGet Function #126
Comments
I'm not understanding the nuance here. My mental model is that when a new textEntry is shown, we use dataGetSliceDefault() (with the default being what is already in result) and use the result directly as the buffer for textEntry (or equivalently, use textEntry in the way where it does that for you). Then, only if the contents have been changed, structEntry would handle copying that value into the result pointer (which might require reallocation). Does that not work? |
That does not work. Here is some code some of my code for handling u8 slice allocations const ProvidedPointerTreatment = enum {
mutate_value_and_realloc,
mutate_value_in_place_only,
display_only,
copy_value_and_alloc_new,
};
comptime var treatment: ProvidedPointerTreatment = .display_only;
comptime if (!alloc) {
if (@typeInfo(T).Pointer.is_const) {
//we can't allocate or mutate, so display
treatment = .display_only;
} else {
//we can't allocate memory, so we mutate the existing buffer
treatment = .mutate_value_in_place_only;
}
} else {
if (@typeInfo(T).Pointer.is_const) {
//we can't mutate the existing buffer, so we copy its value and allocate a new buffer
//we keep a handle on our new buffer using the dataGet api (so we know we have already allocated)
treatment = .copy_value_and_alloc_new;
} else {
//We mutate in place and realloc if necessary
treatment = .mutate_value_and_realloc;
}
}; Since we want allocations made in alloc mode to be persistent and made using the provided allocator, we can't use Rather we allocate using See if (memory_handle == null) { //memory handle is null, so we need to allocate
const memory = try allocator.?.alloc(u8, len); //allocate new memory
@memset(memory, 0); //set it to 0
std.mem.copyForwards(u8, memory, result.*); //copy any values out of the preexisting buffer
dvui.dataSet(null, box.widget().data().id, "memory_handle", memory); //store a handle to the mutable memory buffer
} The problem is that if the user closes an expander or otherwise prevents the var memory_handle = dvui.dataGet(null, box.widget().data().id, "memory_handle", []u8);
Without allocating in the manner, it would be impossible to edit a_str: []const u8 = &[_]u8{0} ** 20, impossible to edit with If we use
.font_body = .{ .disabled = true },
.font_heading = .{ .disabled = true },
.font_caption = .{ .disabled = true },
.font_caption_heading = .{ .disabled = true },
.font_title = .{ .disabled = true },
.font_title_1 = .{ .disabled = true },
.font_title_2 = .{ .disabled = true },
.font_title_3 = .{ .disabled = true },
.font_title_4 = .{ .disabled = true }, Hence we either need to allocate new persistent memory or become unable to generate I also spoke about this problem here |
Thanks for the detailed write up! It sounds like the issue is only with Can you commit what you have so far and leave that part commented out? I want to play with it. Either I'll figure out something or you'll get to see me bash my head against it. My goal is to be able to edit theme names (that start []const u8) and if they change, get backed by the passed allocator. |
Yes, the other situations don't have this problem, only
Sounds good.
Yes, that is what I am trying to get to work as well. The case of font name input is what made me create #123 |
Thanks very much for bearing with me. I think I am seeing the problem(s). In the example of editing a theme name (which starts out pointing to a read-only const string: Problem 1: The user can't directly edit that string, so what does the user edit? We modify TextEntryWidget to detect user edits. If so, structEntryAlloc can alloc a new slice and point the theme struct name field to that. Problem 2: How does structEntryAlloc know whether to free the old name field slice? This is the same as asking if this is the very first time the user has edited this field. Let's imagine some crazy solution that fixes problem 2, like a global hashmap of slices that structEntryAlloc has alloced by Allocator. Problem 3: When is it okay to free a slice we allocated to hold the new text? In the theme name case, the answer is never, so effectively we would leak the last slice we allocated. I think this is true for any const slice that didn't originally come from the allocator passed to structEntryAlloc. Even if we went to heroic lengths to solve problem 2, I can't see any way to solve problem 3 even in theory. I think we have to say any const slice must be display only. Am I wrong? |
Yes, it might be best to make this restriction for simplicity's sake. I'm sure we could come up with some way to solve all these problems but that would probably be quite complex and make things more confusing. |
I agree. I was thinking of crazy things like having a button that says "this allows you to edit this field but leaks memory", but it just seems too much at least for now. |
While working on the new allocation scheme for structEntry, I've ran into the need for a persistent dataGet function (ie, one that does not clear its data)
Example code demonstrating use case
I need some way of storing data that won't drop values and thereby leak memory. (Or a way of testing whether the pointer located at
result.*
was allocated using the providedallocator
parameter)The text was updated successfully, but these errors were encountered: