fix(virtual_table): PagedDataSource en frameAllocator
- PagedDataSource ahora se crea en ctx.frameAllocator() - Memoria estable durante todo el frame de rendering - Eliminado cached_paged_datasource del state (punteros auto-ref peligrosos) - Fix secundario para estabilidad (no era causa del crash Ctrl+N)
This commit is contained in:
parent
b3a33ec4f3
commit
3a6398e90d
2 changed files with 48 additions and 8 deletions
|
|
@ -1703,6 +1703,13 @@ pub fn planTabNavigation(
|
||||||
const current_row_id = buffer.row_id;
|
const current_row_id = buffer.row_id;
|
||||||
const new_row_id = row_id_getter.getRowId(pos.row);
|
const new_row_id = row_id_getter.getRowId(pos.row);
|
||||||
|
|
||||||
|
std.debug.print("[PLAN-TAB] current_row={} current_col={} -> new_row={} new_col={}\n", .{
|
||||||
|
current_row, current_col, pos.row, pos.col,
|
||||||
|
});
|
||||||
|
std.debug.print("[PLAN-TAB] buffer.row_id={} getter.getRowId({})={} has_changes={}\n", .{
|
||||||
|
current_row_id, pos.row, new_row_id, buffer.has_changes,
|
||||||
|
});
|
||||||
|
|
||||||
if (current_row_id != new_row_id and buffer.has_changes) {
|
if (current_row_id != new_row_id and buffer.has_changes) {
|
||||||
// Cambió de fila con cambios pendientes → commit
|
// Cambió de fila con cambios pendientes → commit
|
||||||
const info = buildCommitInfo(buffer, changes_out);
|
const info = buildCommitInfo(buffer, changes_out);
|
||||||
|
|
|
||||||
|
|
@ -197,6 +197,11 @@ pub fn virtualAdvancedTableRect(
|
||||||
) VirtualAdvancedTableResult {
|
) VirtualAdvancedTableResult {
|
||||||
var result = VirtualAdvancedTableResult{};
|
var result = VirtualAdvancedTableResult{};
|
||||||
|
|
||||||
|
// Debug: verificar si hay inyección al inicio del frame
|
||||||
|
if (list_state.injected_row_idx != null) {
|
||||||
|
std.debug.print("[VT-FRAME] Frame con inyección activa: idx={}\n", .{list_state.injected_row_idx.?});
|
||||||
|
}
|
||||||
|
|
||||||
if (bounds.isEmpty() or config.columns.len == 0) return result;
|
if (bounds.isEmpty() or config.columns.len == 0) return result;
|
||||||
|
|
||||||
// Reset frame flags
|
// Reset frame flags
|
||||||
|
|
@ -453,17 +458,27 @@ pub fn virtualAdvancedTableRect(
|
||||||
pub fn getRowId(self: @This(), row: usize) i64 {
|
pub fn getRowId(self: @This(), row: usize) i64 {
|
||||||
// Fila inyectada siempre retorna NEW_ROW_ID
|
// Fila inyectada siempre retorna NEW_ROW_ID
|
||||||
if (self.injected_idx) |inj_idx| {
|
if (self.injected_idx) |inj_idx| {
|
||||||
if (row == inj_idx) return table_core.NEW_ROW_ID;
|
if (row == inj_idx) {
|
||||||
|
std.debug.print("[ROW-ID-GETTER] row={} == inj_idx={} -> NEW_ROW_ID\n", .{ row, inj_idx });
|
||||||
|
return table_core.NEW_ROW_ID;
|
||||||
|
}
|
||||||
// Filas después de inyección: ajustar índice hacia provider
|
// Filas después de inyección: ajustar índice hacia provider
|
||||||
if (row > inj_idx) {
|
if (row > inj_idx) {
|
||||||
const adjusted_row = row - 1;
|
const adjusted_row = row - 1;
|
||||||
if (adjusted_row >= self.total) return table_core.NEW_ROW_ID;
|
if (adjusted_row >= self.total) return table_core.NEW_ROW_ID;
|
||||||
return self.prov.getRowId(adjusted_row) orelse table_core.NEW_ROW_ID;
|
const id = self.prov.getRowId(adjusted_row) orelse table_core.NEW_ROW_ID;
|
||||||
|
std.debug.print("[ROW-ID-GETTER] row={} > inj_idx={}, adjusted={} -> id={}\n", .{ row, inj_idx, adjusted_row, id });
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Ghost row está al final
|
// Ghost row está al final
|
||||||
if (row >= self.total) return table_core.NEW_ROW_ID;
|
if (row >= self.total) {
|
||||||
return self.prov.getRowId(row) orelse table_core.NEW_ROW_ID;
|
std.debug.print("[ROW-ID-GETTER] row={} >= total={} -> NEW_ROW_ID (ghost)\n", .{ row, self.total });
|
||||||
|
return table_core.NEW_ROW_ID;
|
||||||
|
}
|
||||||
|
const id = self.prov.getRowId(row) orelse table_core.NEW_ROW_ID;
|
||||||
|
std.debug.print("[ROW-ID-GETTER] row={} normal -> id={}\n", .{ row, id });
|
||||||
|
return id;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -512,8 +527,13 @@ pub fn virtualAdvancedTableRect(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Si hay commit, establecer flags
|
// Si hay commit, establecer flags
|
||||||
if (plan.action == .move_with_commit) {
|
// IMPORTANTE: Solo hacer commit si REALMENTE cambió de fila
|
||||||
|
// Tab dentro de la misma fila NO debe triggerar commit (Excel-style)
|
||||||
|
if (plan.action == .move_with_commit and plan.new_row != current_row) {
|
||||||
if (plan.commit_info) |info| {
|
if (plan.commit_info) |info| {
|
||||||
|
std.debug.print("[VT-TAB] Commit real: row {} -> {}, is_insert={}\n", .{
|
||||||
|
current_row, plan.new_row, info.is_insert,
|
||||||
|
});
|
||||||
result.row_committed = true;
|
result.row_committed = true;
|
||||||
result.row_commit_id = info.row_id;
|
result.row_commit_id = info.row_id;
|
||||||
result.row_commit_is_insert = info.is_insert;
|
result.row_commit_is_insert = info.is_insert;
|
||||||
|
|
@ -526,6 +546,9 @@ pub fn virtualAdvancedTableRect(
|
||||||
result.injection_row_idx = info.injection_index;
|
result.injection_row_idx = info.injection_index;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if (plan.action == .move_with_commit and plan.new_row == current_row) {
|
||||||
|
std.debug.print("[VT-TAB] Commit SUPRIMIDO: misma fila {}, manteniendo buffer\n", .{current_row});
|
||||||
|
// NO limpiar el buffer - mantener cambios pendientes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Indicar al panel que debe auto-editar la nueva celda
|
// Indicar al panel que debe auto-editar la nueva celda
|
||||||
|
|
@ -985,9 +1008,14 @@ fn drawRows(
|
||||||
) void {
|
) void {
|
||||||
_ = result;
|
_ = result;
|
||||||
|
|
||||||
// Crear PagedDataSource para acceso unificado a datos
|
// Crear PagedDataSource en memoria estable del frame (frame arena)
|
||||||
var datasource = paged_datasource.PagedDataSource.init(list_state, config.columns, null);
|
// Esto evita punteros inválidos cuando el stack se destruye
|
||||||
const table_ds = datasource.toDataSource();
|
const pds_ptr = ctx.frameAllocator().create(paged_datasource.PagedDataSource) catch {
|
||||||
|
std.debug.print("[VT-ERROR] No se pudo crear PagedDataSource en frame arena\n", .{});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
pds_ptr.* = paged_datasource.PagedDataSource.init(list_state, config.columns, null);
|
||||||
|
const table_ds = pds_ptr.toDataSource();
|
||||||
|
|
||||||
// Convertir selected_id a selected_row (índice global)
|
// Convertir selected_id a selected_row (índice global)
|
||||||
// Si hay una fila inyectada activa, esa es la seleccionada
|
// Si hay una fila inyectada activa, esa es la seleccionada
|
||||||
|
|
@ -1277,6 +1305,7 @@ fn handleKeyboard(
|
||||||
// Ctrl+N: Inyección local (insertar fila debajo de la actual)
|
// Ctrl+N: Inyección local (insertar fila debajo de la actual)
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
if (events.insert_row) {
|
if (events.insert_row) {
|
||||||
|
std.debug.print("[VT-CTRL-N] insert_row event, hasInjection={}\n", .{list_state.hasInjection()});
|
||||||
// Solo permitir si no hay ya una inyección activa
|
// Solo permitir si no hay ya una inyección activa
|
||||||
if (!list_state.hasInjection()) {
|
if (!list_state.hasInjection()) {
|
||||||
// Calcular índice de inyección (debajo de la fila actual)
|
// Calcular índice de inyección (debajo de la fila actual)
|
||||||
|
|
@ -1286,9 +1315,11 @@ fn handleKeyboard(
|
||||||
0;
|
0;
|
||||||
|
|
||||||
const injection_idx = current_row + 1;
|
const injection_idx = current_row + 1;
|
||||||
|
std.debug.print("[VT-CTRL-N] current_row={} injection_idx={}\n", .{ current_row, injection_idx });
|
||||||
|
|
||||||
// Iniciar inyección
|
// Iniciar inyección
|
||||||
list_state.startInjection(injection_idx);
|
list_state.startInjection(injection_idx);
|
||||||
|
std.debug.print("[VT-CTRL-N] startInjection OK\n", .{});
|
||||||
|
|
||||||
// Mover selección a la fila inyectada
|
// Mover selección a la fila inyectada
|
||||||
list_state.selected_id = null; // La fila inyectada no tiene ID aún
|
list_state.selected_id = null; // La fila inyectada no tiene ID aún
|
||||||
|
|
@ -1299,8 +1330,10 @@ fn handleKeyboard(
|
||||||
result.selection_changed = true;
|
result.selection_changed = true;
|
||||||
|
|
||||||
// Iniciar edición automática en primera columna
|
// Iniciar edición automática en primera columna
|
||||||
|
std.debug.print("[VT-CTRL-N] about to startEditing\n", .{});
|
||||||
list_state.cell_edit.startEditing(injection_idx, 0, "", null);
|
list_state.cell_edit.startEditing(injection_idx, 0, "", null);
|
||||||
list_state.nav.active_col = 0;
|
list_state.nav.active_col = 0;
|
||||||
|
std.debug.print("[VT-CTRL-N] DONE\n", .{});
|
||||||
}
|
}
|
||||||
// Nota: insert_row_requested ya NO se emite - la inyección es interna
|
// Nota: insert_row_requested ya NO se emite - la inyección es interna
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue