Browse Source

Tables: Using same allocation for our Columns and DisplayOrder array. Mostly designed to facilitate adding new arrays.

omar 5 years ago
parent
commit
a956629b40
2 changed files with 23 additions and 21 deletions
  1. 4 3
      imgui_internal.h
  2. 19 18
      imgui_tables.cpp

+ 4 - 3
imgui_internal.h

@@ -1946,8 +1946,9 @@ struct ImGuiTable
 {
     ImGuiID                     ID;
     ImGuiTableFlags             Flags;
-    ImVector<ImGuiTableColumn>  Columns;
-    ImVector<ImU8>              DisplayOrder;               // Store display order of columns (when not reordered, the values are 0...Count-1)
+    ImVector<char>              RawData;
+    ImSpan<ImGuiTableColumn>    Columns;                    // Point within RawData[]
+    ImSpan<ImS8>                DisplayOrder;               // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
     ImU64                       ActiveMaskByIndex;          // Column Index -> IsActive map (Active == not hidden by user/api) in a format adequate for iterating column without touching cold data
     ImU64                       ActiveMaskByDisplayOrder;   // Column DisplayOrder -> IsActive map
     ImU64                       VisibleMaskByIndex;         // Visible (== Active and not Clipped)
@@ -1992,7 +1993,7 @@ struct ImGuiTable
     ImGuiWindow*                OuterWindow;                // Parent window for the table
     ImGuiWindow*                InnerWindow;                // Window holding the table data (== OuterWindow or a child window)
     ImGuiTextBuffer             ColumnsNames;               // Contiguous buffer holding columns names
-    ImDrawListSplitter          DrawSplitter;               // We carry our own ImDrawList splitter to allow recursion (could be stored outside?)
+    ImDrawListSplitter          DrawSplitter;               // We carry our own ImDrawList splitter to allow recursion (FIXME: could be stored outside, worst case we need 1 splitter per recursing table)
     ImVector<ImGuiTableSortSpecsColumn> SortSpecsData;      // FIXME-OPT: Fixed-size array / small-vector pattern, optimize for single sort spec
     ImGuiTableSortSpecs         SortSpecs;                  // Public facing sorts specs, this is what we return in TableGetSortSpecs()
     ImS8                        SortSpecsCount;

+ 19 - 18
imgui_tables.cpp

@@ -288,26 +288,27 @@ bool    ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
     if ((table_last_flags & ImGuiTableFlags_Reorderable) && !(flags & ImGuiTableFlags_Reorderable))
         table->IsResetDisplayOrderRequest = true;
 
-    // Clear data if columns count changed
-    if (table->Columns.Size != 0 && table->Columns.Size != columns_count)
-    {
-        table->Columns.resize(0);
-        table->DisplayOrder.resize(0);
-    }
+    // Setup default columns state. Clear data if columns count changed
+    const int stored_size = table->Columns.size();
+    if (stored_size != 0 && stored_size != columns_count)
+        table->RawData.resize(0);
+    if (table->RawData.Size == 0)
+    {
+        // Allocate single buffer for our arrays
+        ImSpanAllocator<2> span_allocator;
+        span_allocator.ReserveBytes(0, columns_count * sizeof(ImGuiTableColumn));
+        span_allocator.ReserveBytes(1, columns_count * sizeof(ImS8));
+        table->RawData.resize(span_allocator.GetArenaSizeInBytes());
+        span_allocator.SetArenaBasePtr(table->RawData.Data);
+        span_allocator.GetSpan(0, &table->Columns);
+        span_allocator.GetSpan(1, &table->DisplayOrder);
 
-    // Setup default columns state
-    if (table->Columns.Size == 0)
-    {
-        table->IsInitializing = table->IsSettingsRequestLoad = table->IsSortSpecsDirty = true;
-        table->Columns.reserve(columns_count);
-        table->DisplayOrder.reserve(columns_count);
         for (int n = 0; n < columns_count; n++)
         {
-            ImGuiTableColumn column;
-            column.IndexDisplayOrder = (ImS8)n;
-            table->Columns.push_back(column);
-            table->DisplayOrder.push_back(column.IndexDisplayOrder);
+            table->Columns[n] = ImGuiTableColumn();
+            table->Columns[n].IndexDisplayOrder = table->DisplayOrder[n] = (ImS8)n;
         }
+        table->IsInitializing = table->IsSettingsRequestLoad = table->IsSortSpecsDirty = true;
     }
 
     // Load settings
@@ -378,7 +379,7 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
     if (table->IsResetDisplayOrderRequest)
     {
         for (int n = 0; n < table->ColumnsCount; n++)
-            table->DisplayOrder[n] = table->Columns[n].IndexDisplayOrder = (ImU8)n;
+            table->DisplayOrder[n] = table->Columns[n].IndexDisplayOrder = (ImS8)n;
         table->IsResetDisplayOrderRequest = false;
         table->IsSettingsDirty = true;
     }
@@ -2376,7 +2377,7 @@ void ImGui::TableLoadSettings(ImGuiTable* table)
 
     // FIXME-TABLE: Need to validate .ini data
     for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
-        table->DisplayOrder[table->Columns[column_n].IndexDisplayOrder] = (ImU8)column_n;
+        table->DisplayOrder[table->Columns[column_n].IndexDisplayOrder] = (ImS8)column_n;
 }
 
 void*   ImGui::TableSettingsHandler_ReadOpen(ImGuiContext*, ImGuiSettingsHandler*, const char* name)