mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Internals: Added ImChunkStream, used by window settings. (more generic followup to 4c13807
, the class will be used more extensively by Tables)
This commit is contained in:
parent
a337e219b6
commit
d003674f2c
36
imgui.cpp
36
imgui.cpp
@ -2525,7 +2525,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name)
|
|||||||
LastTimeActive = -1.0f;
|
LastTimeActive = -1.0f;
|
||||||
ItemWidthDefault = 0.0f;
|
ItemWidthDefault = 0.0f;
|
||||||
FontWindowScale = 1.0f;
|
FontWindowScale = 1.0f;
|
||||||
SettingsIdx = -1;
|
SettingsOffset = -1;
|
||||||
|
|
||||||
DrawList = &DrawListInst;
|
DrawList = &DrawListInst;
|
||||||
DrawList->_OwnerName = Name;
|
DrawList->_OwnerName = Name;
|
||||||
@ -3818,7 +3818,6 @@ void ImGui::Shutdown(ImGuiContext* context)
|
|||||||
g.PrivateClipboard.clear();
|
g.PrivateClipboard.clear();
|
||||||
g.InputTextState.ClearFreeMemory();
|
g.InputTextState.ClearFreeMemory();
|
||||||
|
|
||||||
g.SettingsWindowsNames.clear();
|
|
||||||
g.SettingsWindows.clear();
|
g.SettingsWindows.clear();
|
||||||
g.SettingsHandlers.clear();
|
g.SettingsHandlers.clear();
|
||||||
|
|
||||||
@ -4704,7 +4703,7 @@ static ImGuiWindow* CreateNewWindow(const char* name, ImVec2 size, ImGuiWindowFl
|
|||||||
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
if (ImGuiWindowSettings* settings = ImGui::FindWindowSettings(window->ID))
|
||||||
{
|
{
|
||||||
// Retrieve settings from .ini file
|
// Retrieve settings from .ini file
|
||||||
window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
|
window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
|
||||||
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
|
SetWindowConditionAllowFlags(window, ImGuiCond_FirstUseEver, false);
|
||||||
window->Pos = ImVec2(settings->Pos.x, settings->Pos.y);
|
window->Pos = ImVec2(settings->Pos.x, settings->Pos.y);
|
||||||
window->Collapsed = settings->Collapsed;
|
window->Collapsed = settings->Collapsed;
|
||||||
@ -9205,27 +9204,31 @@ void ImGui::MarkIniSettingsDirty(ImGuiWindow* window)
|
|||||||
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
|
ImGuiWindowSettings* ImGui::CreateNewWindowSettings(const char* name)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
g.SettingsWindows.push_back(ImGuiWindowSettings());
|
|
||||||
ImGuiWindowSettings* settings = &g.SettingsWindows.back();
|
|
||||||
#if !IMGUI_DEBUG_INI_SETTINGS
|
#if !IMGUI_DEBUG_INI_SETTINGS
|
||||||
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
// Skip to the "###" marker if any. We don't skip past to match the behavior of GetID()
|
||||||
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
|
// Preserve the full string when IMGUI_DEBUG_INI_SETTINGS is set to make .ini inspection easier.
|
||||||
if (const char* p = strstr(name, "###"))
|
if (const char* p = strstr(name, "###"))
|
||||||
name = p;
|
name = p;
|
||||||
#endif
|
#endif
|
||||||
size_t name_len = strlen(name);
|
const size_t name_len = strlen(name);
|
||||||
settings->NameOffset = g.SettingsWindowsNames.size();
|
|
||||||
g.SettingsWindowsNames.append(name, name + name_len + 1); // Append with zero terminator
|
// Allocate chunk
|
||||||
|
const size_t chunk_size = sizeof(ImGuiWindowSettings) + name_len + 1;
|
||||||
|
ImGuiWindowSettings* settings = g.SettingsWindows.alloc_chunk(chunk_size);
|
||||||
|
IM_PLACEMENT_NEW(settings) ImGuiWindowSettings();
|
||||||
settings->ID = ImHashStr(name, name_len);
|
settings->ID = ImHashStr(name, name_len);
|
||||||
|
memcpy(settings->GetName(), name, name_len + 1); // Store with zero terminator
|
||||||
|
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
|
ImGuiWindowSettings* ImGui::FindWindowSettings(ImGuiID id)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
for (int i = 0; i != g.SettingsWindows.Size; i++)
|
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
|
||||||
if (g.SettingsWindows[i].ID == id)
|
if (settings->ID == id)
|
||||||
return &g.SettingsWindows[i];
|
return settings;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9380,11 +9383,11 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
|
|||||||
if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
|
if (window->Flags & ImGuiWindowFlags_NoSavedSettings)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ImGuiWindowSettings* settings = (window->SettingsIdx != -1) ? &g.SettingsWindows[window->SettingsIdx] : ImGui::FindWindowSettings(window->ID);
|
ImGuiWindowSettings* settings = (window->SettingsOffset != -1) ? g.SettingsWindows.ptr_from_offset(window->SettingsOffset) : ImGui::FindWindowSettings(window->ID);
|
||||||
if (!settings)
|
if (!settings)
|
||||||
{
|
{
|
||||||
settings = ImGui::CreateNewWindowSettings(window->Name);
|
settings = ImGui::CreateNewWindowSettings(window->Name);
|
||||||
window->SettingsIdx = g.SettingsWindows.index_from_ptr(settings);
|
window->SettingsOffset = g.SettingsWindows.offset_from_ptr(settings);
|
||||||
}
|
}
|
||||||
IM_ASSERT(settings->ID == window->ID);
|
IM_ASSERT(settings->ID == window->ID);
|
||||||
settings->Pos = ImVec2ih((short)window->Pos.x, (short)window->Pos.y);
|
settings->Pos = ImVec2ih((short)window->Pos.x, (short)window->Pos.y);
|
||||||
@ -9393,11 +9396,10 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write to text buffer
|
// Write to text buffer
|
||||||
buf->reserve(buf->size() + g.SettingsWindows.Size * 96); // ballpark reserve
|
buf->reserve(buf->size() + g.SettingsWindows.size() * 6); // ballpark reserve
|
||||||
for (int i = 0; i != g.SettingsWindows.Size; i++)
|
for (ImGuiWindowSettings* settings = g.SettingsWindows.begin(); settings != NULL; settings = g.SettingsWindows.next_chunk(settings))
|
||||||
{
|
{
|
||||||
const ImGuiWindowSettings* settings = &g.SettingsWindows[i];
|
const char* settings_name = settings->GetName();
|
||||||
const char* settings_name = g.SettingsWindowsNames.c_str() + settings->NameOffset;
|
|
||||||
buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
|
buf->appendf("[%s][%s]\n", handler->TypeName, settings_name);
|
||||||
buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y);
|
buf->appendf("Pos=%d,%d\n", settings->Pos.x, settings->Pos.y);
|
||||||
buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
|
buf->appendf("Size=%d,%d\n", settings->Size.x, settings->Size.y);
|
||||||
|
@ -88,7 +88,6 @@ struct ImGuiTabItem; // Storage for a tab item (within a tab bar)
|
|||||||
struct ImGuiWindow; // Storage for one window
|
struct ImGuiWindow; // Storage for one window
|
||||||
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame)
|
struct ImGuiWindowTempData; // Temporary storage for one window (that's the data which in theory we could ditch at the end of the frame)
|
||||||
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
struct ImGuiWindowSettings; // Storage for a window .ini settings (we keep one of those even if the actual window wasn't instanced during this session)
|
||||||
template<typename T> struct ImPool; // Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID
|
|
||||||
|
|
||||||
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
// Use your programming IDE "Go to definition" facility on the names of the center columns to find the actual flags/enum lists.
|
||||||
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
|
typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // Enum: Horizontal or vertical
|
||||||
@ -145,6 +144,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit context pointer
|
|||||||
// - Helpers: Maths
|
// - Helpers: Maths
|
||||||
// - Helper: ImBoolVector
|
// - Helper: ImBoolVector
|
||||||
// - Helper: ImPool<>
|
// - Helper: ImPool<>
|
||||||
|
// - Helper: ImChunkStream<>
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
// Macros
|
// Macros
|
||||||
@ -326,6 +326,28 @@ struct IMGUI_API ImPool
|
|||||||
int GetSize() const { return Buf.Size; }
|
int GetSize() const { return Buf.Size; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Helper: ImChunkStream<>
|
||||||
|
// Build and iterate a contiguous stream of variable-sized structures.
|
||||||
|
// This is used by Settings to store persistent data while reducing allocation count.
|
||||||
|
// We store the chunk size first, and align the final size on 4 bytes boundaries (this what the '(X + 3) & ~3' statement is for)
|
||||||
|
// The tedious/zealous amount of casting is to avoid -Wcast-align warnings.
|
||||||
|
template<typename T>
|
||||||
|
struct IMGUI_API ImChunkStream
|
||||||
|
{
|
||||||
|
ImVector<char> Buf;
|
||||||
|
|
||||||
|
void clear() { Buf.clear(); }
|
||||||
|
bool empty() const { return Buf.Size == 0; }
|
||||||
|
int size() const { return Buf.Size; }
|
||||||
|
T* alloc_chunk(size_t sz) { size_t HDR_SZ = 4; sz = ((HDR_SZ + sz) + 3u) & ~3u; int off = Buf.Size; Buf.resize(off + (int)sz); ((int*)(void*)(Buf.Data + off))[0] = (int)sz; return (T*)(void*)(Buf.Data + off + (int)HDR_SZ); }
|
||||||
|
T* begin() { size_t HDR_SZ = 4; if (!Buf.Data) return NULL; return (T*)(void*)(Buf.Data + HDR_SZ); }
|
||||||
|
T* next_chunk(T* p) { size_t HDR_SZ = 4; IM_ASSERT(p >= begin() && p < end()); p = (T*)(void*)((char*)(void*)p + chunk_size(p)); if (p == (T*)(void*)((char*)end() + HDR_SZ)) return (T*)0; IM_ASSERT(p < end()); return p; }
|
||||||
|
int chunk_size(const T* p) { return ((const int*)p)[-1]; }
|
||||||
|
T* end() { return (T*)(void*)(Buf.Data + Buf.Size); }
|
||||||
|
int offset_from_ptr(const T* p) { IM_ASSERT(p >= begin() && p < end()); const ptrdiff_t off = (const char*)p - Buf.Data; return (int)off; }
|
||||||
|
T* ptr_from_offset(int off) { IM_ASSERT(off >= 4 && off < Buf.Size); return (T*)(void*)(Buf.Data + off); }
|
||||||
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// Misc data structures
|
// Misc data structures
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@ -681,15 +703,16 @@ struct IMGUI_API ImGuiInputTextState
|
|||||||
|
|
||||||
// Windows data saved in imgui.ini file
|
// Windows data saved in imgui.ini file
|
||||||
// Because we never destroy or rename ImGuiWindowSettings, we can store the names in a separate buffer easily.
|
// Because we never destroy or rename ImGuiWindowSettings, we can store the names in a separate buffer easily.
|
||||||
|
// (this is designed to be stored in a ImChunkStream buffer, with the variable-length Name following our structure)
|
||||||
struct ImGuiWindowSettings
|
struct ImGuiWindowSettings
|
||||||
{
|
{
|
||||||
int NameOffset; // Offset into SettingsWindowNames[]
|
|
||||||
ImGuiID ID;
|
ImGuiID ID;
|
||||||
ImVec2ih Pos;
|
ImVec2ih Pos;
|
||||||
ImVec2ih Size;
|
ImVec2ih Size;
|
||||||
bool Collapsed;
|
bool Collapsed;
|
||||||
|
|
||||||
ImGuiWindowSettings() { NameOffset = -1; ID = 0; Pos = Size = ImVec2ih(0, 0); Collapsed = false; }
|
ImGuiWindowSettings() { ID = 0; Pos = Size = ImVec2ih(0, 0); Collapsed = false; }
|
||||||
|
char* GetName() { return (char*)(this + 1); }
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ImGuiSettingsHandler
|
struct ImGuiSettingsHandler
|
||||||
@ -1057,8 +1080,7 @@ struct ImGuiContext
|
|||||||
float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero
|
float SettingsDirtyTimer; // Save .ini Settings to memory when time reaches zero
|
||||||
ImGuiTextBuffer SettingsIniData; // In memory .ini settings
|
ImGuiTextBuffer SettingsIniData; // In memory .ini settings
|
||||||
ImVector<ImGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
|
ImVector<ImGuiSettingsHandler> SettingsHandlers; // List of .ini settings handlers
|
||||||
ImVector<ImGuiWindowSettings> SettingsWindows; // ImGuiWindow .ini settings entries (parsed from the last loaded .ini file and maintained on saving)
|
ImChunkStream<ImGuiWindowSettings> SettingsWindows; // ImGuiWindow .ini settings entries
|
||||||
ImGuiTextBuffer SettingsWindowsNames; // Names for SettingsWindows
|
|
||||||
|
|
||||||
// Logging
|
// Logging
|
||||||
bool LogEnabled;
|
bool LogEnabled;
|
||||||
@ -1369,7 +1391,7 @@ struct IMGUI_API ImGuiWindow
|
|||||||
ImGuiStorage StateStorage;
|
ImGuiStorage StateStorage;
|
||||||
ImVector<ImGuiColumns> ColumnsStorage;
|
ImVector<ImGuiColumns> ColumnsStorage;
|
||||||
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
float FontWindowScale; // User scale multiplier per-window, via SetWindowFontScale()
|
||||||
int SettingsIdx; // Index into SettingsWindow[] (indices are always valid as we only grow the array from the back)
|
int SettingsOffset; // Offset into SettingsWindows[] (offsets are always valid as we only grow the array from the back)
|
||||||
|
|
||||||
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
ImDrawList* DrawList; // == &DrawListInst (for backward compatibility reason with code using imgui_internal.h we keep this a pointer)
|
||||||
ImDrawList DrawListInst;
|
ImDrawList DrawListInst;
|
||||||
|
Loading…
Reference in New Issue
Block a user