Merge branch 'pr/40'
diff --git a/imconfig.h b/imconfig.h
index 0f5357c..ca55221 100644
--- a/imconfig.h
+++ b/imconfig.h
@@ -4,6 +4,18 @@
#pragma once
+//---- Define your own malloc/free/realloc functions if you want to override internal memory allocations for ImGui
+/*
+ #define IM_MALLOC(_SIZE) MyMalloc(_SIZE)
+ #define IM_FREE(_PTR) MyFree(_PTR)
+ #define IM_REALLOC(_PTR, _SIZE) MyRealloc(_PTR, _SIZE)
+
+ #include <stdlib.h> // size_t
+ void* MyMalloc(size_t size);
+ void MyFree(void *ptr);
+ void* MyRealloc(void *ptr, size_t size);
+*/
+
//---- Define your own ImVector<> type if you don't want to use the provided implementation defined in imgui.h
//#include <vector>
//#define ImVector std::vector
@@ -35,3 +47,4 @@
void Value(const char* prefix, const MyVec4& v, const char* float_format = NULL);
};
*/
+
diff --git a/imgui.cpp b/imgui.cpp
index cc9528a..683df5c 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -188,11 +188,13 @@
#include <stdint.h> // intptr_t
#include <stdio.h> // vsnprintf
#include <string.h> // memset
+#include <new> // new (ptr)
#ifdef _MSC_VER
#pragma warning (disable: 4996) // 'This function or variable may be unsafe': strcpy, strdup, sprintf, vsnprintf, sscanf, fopen
#endif
+
//-------------------------------------------------------------------------
// Forward Declarations
//-------------------------------------------------------------------------
@@ -373,6 +375,14 @@
return d;
}
+static char* ImStrdup(const char *str)
+{
+ char *buff = (char*)IM_MALLOC(strlen(str) + 1);
+ IM_ASSERT(buff);
+ strcpy(buff, str);
+ return buff;
+}
+
static const char* ImStristr(const char* haystack, const char* needle, const char* needle_end)
{
if (!needle_end)
@@ -615,7 +625,7 @@
bool Collapsed;
ImGuiIniData() { memset(this, 0, sizeof(*this)); }
- ~ImGuiIniData() { if (Name) { free(Name); Name = NULL; } }
+ ~ImGuiIniData() { if (Name) { IM_FREE(Name); Name = NULL; } }
};
struct ImGuiState
@@ -656,7 +666,7 @@
// Logging
bool LogEnabled;
FILE* LogFile;
- ImGuiTextBuffer LogClipboard;
+ ImGuiTextBuffer* LogClipboard;
int LogAutoExpandMaxDepth;
ImGuiState()
@@ -679,6 +689,7 @@
LogEnabled = false;
LogFile = NULL;
LogAutoExpandMaxDepth = 2;
+ LogClipboard = NULL;
}
};
@@ -944,7 +955,7 @@
ImGuiWindow::ImGuiWindow(const char* name, ImVec2 default_pos, ImVec2 default_size)
{
- Name = strdup(name);
+ Name = ImStrdup(name);
ID = GetID(name);
IDStack.push_back(ID);
@@ -971,14 +982,16 @@
FocusIdxRequestCurrent = IM_INT_MAX;
FocusIdxRequestNext = IM_INT_MAX;
- DrawList = new ImDrawList();
+ DrawList = (ImDrawList*)IM_MALLOC(sizeof(ImDrawList));
+ new(DrawList) ImDrawList();
}
ImGuiWindow::~ImGuiWindow()
{
- delete DrawList;
+ DrawList->~ImDrawList();
+ IM_FREE(DrawList);
DrawList = NULL;
- free(Name);
+ IM_FREE(Name);
Name = NULL;
}
@@ -1058,8 +1071,9 @@
if (ImStricmp(ini->Name, name) == 0)
return ini;
}
- ImGuiIniData* ini = new ImGuiIniData();
- ini->Name = strdup(name);
+ ImGuiIniData* ini = (ImGuiIniData*)IM_MALLOC(sizeof(ImGuiIniData));
+ new(ini) ImGuiIniData();
+ ini->Name = ImStrdup(name);
ini->Collapsed = false;
ini->Pos = ImVec2(FLT_MAX,FLT_MAX);
ini->Size = ImVec2(0,0);
@@ -1097,12 +1111,12 @@
fclose(f);
return;
}
- char* f_data = new char[f_size+1];
+ char* f_data = (char*)IM_MALLOC(f_size+1);
f_size = fread(f_data, 1, f_size, f); // Text conversion alter read size so let's not be fussy about return value
fclose(f);
if (f_size == 0)
{
- delete[] f_data;
+ IM_FREE(f_data);
return;
}
f_data[f_size] = 0;
@@ -1136,7 +1150,7 @@
line_start = line_end+1;
}
- delete[] f_data;
+ IM_FREE(f_data);
}
static void SaveSettings()
@@ -1208,6 +1222,9 @@
if (!g.Initialized)
{
// Initialize on first frame
+ g.LogClipboard = (ImGuiTextBuffer*)IM_MALLOC(sizeof(ImGuiTextBuffer));
+ new(g.LogClipboard) ImGuiTextBuffer();
+
IM_ASSERT(g.Settings.empty());
LoadSettings();
if (!g.IO.Font)
@@ -1216,7 +1233,8 @@
const void* fnt_data;
unsigned int fnt_size;
ImGui::GetDefaultFontData(&fnt_data, &fnt_size, NULL, NULL);
- g.IO.Font = new ImBitmapFont();
+ g.IO.Font = (ImBitmapFont*)IM_MALLOC(sizeof(ImBitmapFont));
+ new(g.IO.Font) ImBitmapFont();
g.IO.Font->LoadFromMemory(fnt_data, fnt_size);
g.IO.FontYOffset = +1;
}
@@ -1343,14 +1361,21 @@
SaveSettings();
for (size_t i = 0; i < g.Windows.size(); i++)
- delete g.Windows[i];
+ {
+ g.Windows[i]->~ImGuiWindow();
+ IM_FREE(g.Windows[i]);
+ }
g.Windows.clear();
g.CurrentWindowStack.clear();
+ g.RenderDrawLists.clear();
g.FocusedWindow = NULL;
g.HoveredWindow = NULL;
g.HoveredWindowExcludingChilds = NULL;
for (size_t i = 0; i < g.Settings.size(); i++)
- delete g.Settings[i];
+ {
+ g.Settings[i]->~ImGuiIniData();
+ IM_FREE(g.Settings[i]);
+ }
g.Settings.clear();
g.ColorEditModeStorage.Clear();
if (g.LogFile && g.LogFile != stdout)
@@ -1360,16 +1385,23 @@
}
if (g.IO.Font)
{
- delete g.IO.Font;
+ g.IO.Font->~ImBitmapFont();
+ IM_FREE(g.IO.Font);
g.IO.Font = NULL;
}
if (g.PrivateClipboard)
{
- free(g.PrivateClipboard);
+ IM_FREE(g.PrivateClipboard);
g.PrivateClipboard = NULL;
}
+ if (g.LogClipboard)
+ {
+ g.LogClipboard->~ImGuiTextBuffer();
+ IM_FREE(g.LogClipboard);
+ }
+
g.Initialized = false;
}
@@ -1534,9 +1566,9 @@
else
{
if (log_new_line || !is_first_line)
- g.LogClipboard.append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
+ g.LogClipboard->append("\n%*s%.*s", tree_depth*4, "", char_count, text_remaining);
else
- g.LogClipboard.append(" %.*s", char_count, text_remaining);
+ g.LogClipboard->append(" %.*s", char_count, text_remaining);
}
}
@@ -1859,7 +1891,8 @@
// Create window the first time, and load settings
if (flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip))
{
- window = new ImGuiWindow(name, ImVec2(0,0), size);
+ window = (ImGuiWindow*)IM_MALLOC(sizeof(ImGuiWindow));
+ new(window) ImGuiWindow(name, ImVec2(0,0), size);
}
else
{
@@ -1867,7 +1900,8 @@
if (settings && ImLength(settings->Size) > 0.0f && !(flags & ImGuiWindowFlags_NoResize))// && ImLengthsize) == 0.0f)
size = settings->Size;
- window = new ImGuiWindow(name, g.NewWindowDefaultPos, size);
+ window = (ImGuiWindow*)IM_MALLOC(sizeof(ImGuiWindow));
+ new(window) ImGuiWindow(name, g.NewWindowDefaultPos, size);
if (settings->Pos.x != FLT_MAX)
{
@@ -2267,12 +2301,12 @@
fclose(g.LogFile);
g.LogFile = NULL;
}
- if (g.LogClipboard.size() > 1)
+ if (g.LogClipboard->size() > 1)
{
- g.LogClipboard.append("\n");
+ g.LogClipboard->append("\n");
if (g.IO.SetClipboardTextFn)
- g.IO.SetClipboardTextFn(g.LogClipboard.begin(), g.LogClipboard.end());
- g.LogClipboard.clear();
+ g.IO.SetClipboardTextFn(g.LogClipboard->begin(), g.LogClipboard->end());
+ g.LogClipboard->clear();
}
}
@@ -3970,7 +4004,7 @@
{
// Remove new-line from pasted buffer
size_t clipboard_len = strlen(clipboard);
- char* clipboard_filtered = (char*)malloc(clipboard_len+1);
+ char* clipboard_filtered = (char*)IM_MALLOC(clipboard_len+1);
int clipboard_filtered_len = 0;
for (int i = 0; clipboard[i]; i++)
{
@@ -3981,7 +4015,7 @@
}
clipboard_filtered[clipboard_filtered_len] = 0;
stb_textedit_paste(&edit_state, &edit_state.StbState, clipboard_filtered, clipboard_filtered_len);
- free(clipboard_filtered);
+ IM_FREE(clipboard_filtered);
}
}
else if (g.IO.InputCharacters[0])
@@ -5100,7 +5134,7 @@
void ImBitmapFont::Clear()
{
if (Data && DataOwned)
- free(Data);
+ IM_FREE(Data);
Data = NULL;
DataOwned = false;
Info = NULL;
@@ -5127,7 +5161,7 @@
DataSize = (size_t)f_size;
if (fseek(f, 0, SEEK_SET))
return false;
- if ((Data = (unsigned char*)malloc(DataSize)) == NULL)
+ if ((Data = (unsigned char*)IM_MALLOC(DataSize)) == NULL)
{
fclose(f);
return false;
@@ -5135,7 +5169,7 @@
if (fread(Data, 1, DataSize, f) != DataSize)
{
fclose(f);
- free(Data);
+ IM_FREE(Data);
return false;
}
fclose(f);
@@ -5378,7 +5412,7 @@
static char* buf_local = NULL;
if (buf_local)
{
- free(buf_local);
+ IM_FREE(buf_local);
buf_local = NULL;
}
if (!OpenClipboard(NULL))
@@ -5387,7 +5421,7 @@
if (buf_handle == NULL)
return NULL;
if (char* buf_global = (char*)GlobalLock(buf_handle))
- buf_local = strdup(buf_global);
+ buf_local = ImStrdup(buf_global);
GlobalUnlock(buf_handle);
CloseClipboard();
return buf_local;
@@ -5426,12 +5460,12 @@
{
if (GImGui.PrivateClipboard)
{
- free(GImGui.PrivateClipboard);
+ IM_FREE(GImGui.PrivateClipboard);
GImGui.PrivateClipboard = NULL;
}
if (!text_end)
text_end = text + strlen(text);
- GImGui.PrivateClipboard = (char*)malloc((size_t)(text_end - text) + 1);
+ GImGui.PrivateClipboard = (char*)IM_MALLOC((size_t)(text_end - text) + 1);
memcpy(GImGui.PrivateClipboard, text, (size_t)(text_end - text));
GImGui.PrivateClipboard[(size_t)(text_end - text)] = 0;
}
@@ -5965,7 +5999,7 @@
/*
// Copyright (c) 2004, 2005 Tristan Grimmer
-// Permission is hereby granted, free of charge, to any person obtaining a copy
+// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
diff --git a/imgui.h b/imgui.h
index c8ffeed..3675c76 100644
--- a/imgui.h
+++ b/imgui.h
@@ -19,6 +19,18 @@
#include <stdarg.h> // va_list
#include <stdlib.h> // NULL
+#ifndef IM_MALLOC
+#define IM_MALLOC(_SIZE) malloc((_SIZE))
+#endif
+
+#ifndef IM_FREE
+#define IM_FREE(_PTR) free((_PTR))
+#endif
+
+#ifndef IM_REALLOC
+#define IM_REALLOC(_PTR, _SIZE) realloc((_PTR), (_SIZE))
+#endif
+
#ifndef IM_ASSERT
#include <assert.h>
#define IM_ASSERT(_EXPR) assert(_EXPR)
@@ -58,6 +70,7 @@
// std::vector<> like class to avoid dragging dependencies (also: windows implementation of STL with debug enabled is absurdly slow, so let's bypass it so our code runs fast in debug).
// this implementation does NOT call c++ constructors! we don't need them! also only provide the minimum functionalities we need.
#ifndef ImVector
+
template<typename T>
class ImVector
{
@@ -72,7 +85,7 @@
typedef const value_type* const_iterator;
ImVector() { Size = Capacity = 0; Data = NULL; }
- ~ImVector() { if (Data) free(Data); }
+ ~ImVector() { if (Data) IM_FREE(Data); }
inline bool empty() const { return Size == 0; }
inline size_t size() const { return Size; }
@@ -83,7 +96,7 @@
inline value_type& operator[](size_t i) { IM_ASSERT(i < Size); return Data[i]; }
inline const value_type& operator[](size_t i) const { IM_ASSERT(i < Size); return Data[i]; }
- inline void clear() { if (Data) { Size = Capacity = 0; free(Data); Data = NULL; } }
+ inline void clear() { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } }
inline iterator begin() { return Data; }
inline const_iterator begin() const { return Data; }
inline iterator end() { return Data + Size; }
@@ -94,7 +107,7 @@
inline const value_type& back() const { IM_ASSERT(Size > 0); return at(Size-1); }
inline void swap(ImVector<T>& rhs) { const size_t rhs_size = rhs.Size; rhs.Size = Size; Size = rhs_size; const size_t rhs_cap = rhs.Capacity; rhs.Capacity = Capacity; Capacity = rhs_cap; value_type* rhs_data = rhs.Data; rhs.Data = Data; Data = rhs_data; }
- inline void reserve(size_t new_capacity) { Data = (value_type*)realloc(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
+ inline void reserve(size_t new_capacity) { Data = (value_type*)IM_REALLOC(Data, new_capacity * sizeof(value_type)); Capacity = new_capacity; }
inline void resize(size_t new_size) { if (new_size > Capacity) reserve(new_size); Size = new_size; }
inline void push_back(const value_type& v) { if (Size == Capacity) reserve(Capacity ? Capacity * 2 : 4); Data[Size++] = v; }