mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-30 20:51:06 +01:00 
			
		
		
		
	Misc: Added IM_MALLOC/IM_FREE macros mimicking IM_NEW/IM_DELETE so user doesn't need to revert to using the ImGui::MemAlloc()/MemFree() calls directly.
This commit is contained in:
		
							
								
								
									
										33
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -13,6 +13,7 @@ Index of this file: | ||||
| // Forward declarations and basic types | ||||
| // ImGui API (Dear ImGui end-user API) | ||||
| // Flags & Enumerations | ||||
| // Memory allocations macros | ||||
| // ImVector<> | ||||
| // ImGuiStyle | ||||
| // ImGuiIO | ||||
| @@ -1185,6 +1186,22 @@ enum ImGuiCond_ | ||||
| #endif | ||||
| }; | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // Helpers: Memory allocations macros | ||||
| // IM_MALLOC(), IM_FREE(), IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE() | ||||
| // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. | ||||
| // Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions. | ||||
| //----------------------------------------------------------------------------- | ||||
|  | ||||
| struct ImNewDummy {}; | ||||
| inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; } | ||||
| inline void  operator delete(void*, ImNewDummy, void*)   {} // This is only required so we can use the symmetrical new() | ||||
| #define IM_ALLOC(_SIZE)                     ImGui::MemAlloc(_SIZE) | ||||
| #define IM_FREE(_PTR)                       ImGui::MemFree(_PTR) | ||||
| #define IM_PLACEMENT_NEW(_PTR)              new(ImNewDummy(), _PTR) | ||||
| #define IM_NEW(_TYPE)                       new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE | ||||
| template<typename T> void IM_DELETE(T* p)   { if (p) { p->~T(); ImGui::MemFree(p); } } | ||||
|  | ||||
| //----------------------------------------------------------------------------- | ||||
| // Helper: ImVector<> | ||||
| // Lightweight std::vector<>-like class to avoid dragging dependencies (also, some implementations of STL with debug enabled are absurdly slow, we bypass it so our code runs fast in debug). | ||||
| @@ -1210,7 +1227,7 @@ struct ImVector | ||||
|     inline ImVector()                                       { Size = Capacity = 0; Data = NULL; } | ||||
|     inline ImVector(const ImVector<T>& src)                 { Size = Capacity = 0; Data = NULL; operator=(src); } | ||||
|     inline ImVector<T>& operator=(const ImVector<T>& src)   { clear(); resize(src.Size); memcpy(Data, src.Data, (size_t)Size * sizeof(T)); return *this; } | ||||
|     inline ~ImVector()                                      { if (Data) ImGui::MemFree(Data); } | ||||
|     inline ~ImVector()                                      { if (Data) IM_FREE(Data); } | ||||
|  | ||||
|     inline bool         empty() const                       { return Size == 0; } | ||||
|     inline int          size() const                        { return Size; } | ||||
| @@ -1219,7 +1236,7 @@ struct ImVector | ||||
|     inline T&           operator[](int i)                   { IM_ASSERT(i < Size); return Data[i]; } | ||||
|     inline const T&     operator[](int i) const             { IM_ASSERT(i < Size); return Data[i]; } | ||||
|  | ||||
|     inline void         clear()                             { if (Data) { Size = Capacity = 0; ImGui::MemFree(Data); Data = NULL; } } | ||||
|     inline void         clear()                             { if (Data) { Size = Capacity = 0; IM_FREE(Data); Data = NULL; } } | ||||
|     inline T*           begin()                             { return Data; } | ||||
|     inline const T*     begin() const                       { return Data; } | ||||
|     inline T*           end()                               { return Data + Size; } | ||||
| @@ -1233,7 +1250,7 @@ struct ImVector | ||||
|     inline int          _grow_capacity(int sz) const        { int new_capacity = Capacity ? (Capacity + Capacity/2) : 8; return new_capacity > sz ? new_capacity : sz; } | ||||
|     inline void         resize(int new_size)                { if (new_size > Capacity) reserve(_grow_capacity(new_size)); Size = new_size; } | ||||
|     inline void         resize(int new_size, const T& v)    { if (new_size > Capacity) reserve(_grow_capacity(new_size)); if (new_size > Size) for (int n = Size; n < new_size; n++) memcpy(&Data[n], &v, sizeof(v)); Size = new_size; } | ||||
|     inline void         reserve(int new_capacity)           { if (new_capacity <= Capacity) return; T* new_data = (T*)ImGui::MemAlloc((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); ImGui::MemFree(Data); } Data = new_data; Capacity = new_capacity; } | ||||
|     inline void         reserve(int new_capacity)           { if (new_capacity <= Capacity) return; T* new_data = (T*)IM_ALLOC((size_t)new_capacity * sizeof(T)); if (Data) { memcpy(new_data, Data, (size_t)Size * sizeof(T)); IM_FREE(Data); } Data = new_data; Capacity = new_capacity; } | ||||
|  | ||||
|     // NB: It is illegal to call push_back/push_front/insert with a reference pointing inside the ImVector data itself! e.g. v.push_back(v[10]) is forbidden. | ||||
|     inline void         push_back(const T& v)               { if (Size == Capacity) reserve(_grow_capacity(Size + 1)); memcpy(&Data[Size], &v, sizeof(v)); Size++; } | ||||
| @@ -1548,16 +1565,6 @@ typedef ImGuiInputTextCallbackData  ImGuiTextEditCallbackData; | ||||
| // Helpers | ||||
| //----------------------------------------------------------------------------- | ||||
|  | ||||
| // Helper: IM_NEW(), IM_PLACEMENT_NEW(), IM_DELETE() macros to call MemAlloc + Placement New, Placement Delete + MemFree | ||||
| // We call C++ constructor on own allocated memory via the placement "new(ptr) Type()" syntax. | ||||
| // Defining a custom placement new() with a dummy parameter allows us to bypass including <new> which on some platforms complains when user has disabled exceptions. | ||||
| struct ImNewDummy {}; | ||||
| inline void* operator new(size_t, ImNewDummy, void* ptr) { return ptr; } | ||||
| inline void  operator delete(void*, ImNewDummy, void*)   {} // This is only required so we can use the symmetrical new() | ||||
| #define IM_PLACEMENT_NEW(_PTR)              new(ImNewDummy(), _PTR) | ||||
| #define IM_NEW(_TYPE)                       new(ImNewDummy(), ImGui::MemAlloc(sizeof(_TYPE))) _TYPE | ||||
| template<typename T> void IM_DELETE(T* p)   { if (p) { p->~T(); ImGui::MemFree(p); } } | ||||
|  | ||||
| // Helper: Execute a block of code at maximum once a frame. Convenient if you want to quickly create an UI within deep-nested code that runs multiple times every frame. | ||||
| // Usage: static ImGuiOnceUponAFrame oaf; if (oaf) ImGui::Text("This will be called only once per frame"); | ||||
| struct ImGuiOnceUponAFrame | ||||
|   | ||||
		Reference in New Issue
	
	Block a user