Просмотр исходного кода

fix: crash when a dialog was closed while uiml api messages where processed for dialog children

Kolja Strohm 20 часов назад
Родитель
Сommit
4921b8fbf6
2 измененных файлов с 13 добавлено и 0 удалено
  1. 12 0
      FactoryCraft/Game.cpp
  2. 1 0
      FactoryCraft/Game.h

+ 12 - 0
FactoryCraft/Game.cpp

@@ -151,6 +151,7 @@ void Game::api(char* data)
             char* dialogName = new char[len + 1];
             memcpy(dialogName, data + 3, len);
             dialogName[len] = 0;
+            dialogCs.lock();
             for (UIMLDialog* dialog : dialogs)
             {
                 if (dialog->getName().istGleich(dialogName))
@@ -159,6 +160,7 @@ void Game::api(char* data)
                     break;
                 }
             }
+            dialogCs.unlock();
             delete[] dialogName;
             if (!exists)
             {
@@ -170,6 +172,7 @@ void Game::api(char* data)
                     = new UIMLDialog(uiml, [this](UIMLDialog* dialog) {
                           window->zBildschirm()->postAction([this, dialog]() {
                               int index = 0;
+                              dialogCs.lock();
                               for (UIMLDialog* d : dialogs)
                               {
                                   if (d == dialog)
@@ -184,9 +187,12 @@ void Game::api(char* data)
                                   }
                                   index++;
                               }
+                              dialogCs.unlock();
                           });
                       });
+                dialogCs.lock();
                 dialogs.add(dialog);
+                dialogCs.unlock();
                 updateRecipieVisibility();
                 World::INSTANCE->zKamera()->setControlEnabled(0);
                 window->zBildschirm()->addMember(dialog);
@@ -196,10 +202,12 @@ void Game::api(char* data)
         }
     case 1:
         { // element message
+            dialogCs.lock();
             for (UIMLDialog* dialog : dialogs)
             {
                 dialog->api(data + 1);
             }
+            dialogCs.unlock();
             short idLen = *(short*)(data + 1);
             char* id = new char[idLen + 1];
             memcpy(id, data + 3, idLen);
@@ -231,6 +239,7 @@ void Game::api(char* data)
             char* dialogName = new char[dialogNameLen + 1];
             memcpy(dialogName, data + 3, dialogNameLen);
             dialogName[dialogNameLen] = 0;
+            dialogCs.lock();
             for (UIMLDialog* dialog : dialogs)
             {
                 if (dialog->getName().istGleich(dialogName))
@@ -244,17 +253,20 @@ void Game::api(char* data)
                     break;
                 }
             }
+            dialogCs.unlock();
         }
     }
 }
 
 void Game::closeCurrentDialog()
 {
+    dialogCs.lock();
     if (dialogs.getEintragAnzahl() > 0)
     {
         UIMLDialog* d = dialogs.get(dialogs.getEintragAnzahl() - 1);
         d->close();
     }
+    dialogCs.unlock();
 }
 
 DragController<InventoryDragSource, int>* Game::zInventoryDragController()

+ 1 - 0
FactoryCraft/Game.h

@@ -29,6 +29,7 @@ private:
     MapWindow* mapWindow;
     Chat* chat;
     bool recipieVisible;
+    Critical dialogCs;
 
 public:
     // Konstruktor