IgorTandetnik-1300, thanks, and here is how I apply it on my real project:
void draw_begin() {
EMC_VERIFY(layout.items.size() == 0); // There is no problem but this VERIFY is almost never evaluated because the layout is always empty before calling draw.
draw();
}
void draw_end() {
// Clear the layout because it's not needed anymore
layout.items.clear();
}
void Header::update_objs(int debug_displayFlags)
{
if (debug_displayFlags & 0x1) {
printf("%s: Update objs.\n", _.cls->emc_idName.c_str());
}
_.cls->draw_begin(); // <-- BEGIN A DRAW **************************************************
for (auto &it : _.cls->layout.items) {
if (it.itemType == ItemType_EditorType) { // Editor Type
EMC_VERIFY(_.editorType_menuComboBox == nullptr && "There's already an Editor Type.");
auto &it1 = it;
ClassBase *it1_cls = nullptr;
EMC_FINDCLASS(it1_cls, TYPE_TO_STRING(EDITORTYPE_MT));
MenuItem *menuItem = new MenuItem(this, Rect({ 0, 0 }, { 0, 0 }), this, it1.itemType, it1_cls);
_.editorType_menuComboBox = menuItem;
}
else if (it.itemType == ItemType_Prop) { // Mode
auto &it1 = it;
ClassBase *it1_cls = nullptr;
EMC_FINDCLASS(it1_cls, it1.idName);
MenuItem *menuItem = new MenuItem(this, Rect({ 0, 0 }, { 0, 0 }), this, it1.itemType, it1_cls);
_.mode_menuComboBox = menuItem;
}
else if (it.itemType == ItemType_Menu) { // Menu
ClassBase *it_cls = nullptr;
EMC_FINDCLASS(it_cls, it.idName);
if (_.showMenus) {
it_cls->draw_begin(); // <-- BEGIN A DRAW **************************************************
for (auto &it1 : it_cls->layout.items) {
ClassBase *it1_cls = nullptr;
EMC_FINDCLASS(it1_cls, it1.idName);
MenuItem *menuItem = new MenuItem(this, Rect({ 0, 0 }, { 0, 0 }), this, it1.itemType, it1_cls);
_.menuItems.push_back(menuItem);
}
it_cls->draw_end(); // <-- END A DRAW **************************************************
}
else {
auto &it1 = it;
ClassBase *it1_cls = it_cls;
_.collapsedMenu = new MenuItem(this, Rect({ 0, 0 }, { 0, 0 }), this, it1.itemType, it1_cls);
}
}
else {
EMC_ERROR_WRONGTYPE();
}
}
_.cls->draw_end(); // <-- END A DRAW **************************************************
}
The real checking function that shows warning about memory leak is like this:
// The warning is placed in one single function
void internal_imguiDebug_classStack() {
static int g_frame = 0;
g_frame++;
if (g_frame == 50) { // Performance reason
g_frame = 0;
for (auto &cls : g_classStack) { // This is placed here because no need to expand a TreeNode to evaluate it.
auto items = cls->layout.items;
if (items.size() != 0) {
static bool shown = false;
if (!shown) {
shown = true;
EMC_ERROR_NOBREAK((std::string("Class Stack > ") + cls->emc_idName + ": A layout must always be cleared after the items are created. You didn't call " + FUNCTION_TO_STRING(ClassBase::draw_end) + ".").c_str());
}
}
}
}
...
}