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

update is_enough_heap and check mem on start

jblanked 9 месяцев назад
Родитель
Сommit
87b0636883
6 измененных файлов с 49 добавлено и 4 удалено
  1. 7 0
      app.c
  2. 1 1
      callback/callback.c
  3. 20 1
      flip_world.c
  4. 1 1
      flip_world.h
  5. 19 0
      game/game.c
  6. 1 1
      game/level.c

+ 7 - 0
app.c

@@ -4,6 +4,13 @@
 // Entry point for the FlipWorld application
 int32_t flip_world_main(void *p)
 {
+    // check memory
+    if (!is_enough_heap(sizeof(FlipWorldApp) + sizeof(FlipperHTTP), true))
+    {
+        easy_flipper_dialog("Memory Error", "Not enough heap memory.\nPlease restart your Flipper Zero.");
+        return 0; // return success so the user can see the error
+    }
+
     // Suppress unused parameter warning
     UNUSED(p);
 

+ 1 - 1
callback/callback.c

@@ -1306,7 +1306,7 @@ static void run(FlipWorldApp *app)
         return;
     }
     free_all_views(app, true, true, false);
-    if (!is_enough_heap(60000))
+    if (!is_enough_heap(60000, false)) // only need to check if they have 60k free (a 60k memory block is highly unlikely anyways)
     {
         easy_flipper_dialog("Error", "Not enough heap memory.\nPlease restart your Flipper.");
         return;

+ 20 - 1
flip_world.c

@@ -14,4 +14,23 @@ int game_mode_index = 0;
 float atof_(const char *nptr) { return (float)strtod(nptr, NULL); }
 float atof_furi(const FuriString *nptr) { return atof_(furi_string_get_cstr(nptr)); }
 bool is_str(const char *src, const char *dst) { return strcmp(src, dst) == 0; }
-bool is_enough_heap(size_t heap_size) { return memmgr_get_free_heap() > (heap_size + 1024); } // 1KB buffer
+bool is_enough_heap(size_t heap_size, bool check_blocks)
+{
+    const size_t min_heap = heap_size + 1024; // 1KB buffer
+    const size_t min_free = memmgr_get_free_heap();
+    if (min_free < min_heap)
+    {
+        FURI_LOG_E(TAG, "Not enough heap memory: %zu bytes", min_free);
+        return false;
+    }
+    if (check_blocks)
+    {
+        const size_t max_free_block = memmgr_heap_get_max_free_block();
+        if (max_free_block < min_heap)
+        {
+            FURI_LOG_E(TAG, "Not enough free blocks: %zu bytes", max_free_block);
+            return false;
+        }
+    }
+    return true;
+}

+ 1 - 1
flip_world.h

@@ -104,4 +104,4 @@ extern int game_mode_index;
 float atof_(const char *nptr);
 float atof_furi(const FuriString *nptr);
 bool is_str(const char *src, const char *dst);
-bool is_enough_heap(size_t heap_size);
+bool is_enough_heap(size_t heap_size, bool check_blocks);

+ 19 - 0
game/game.c

@@ -11,6 +11,15 @@
 static void game_start(GameManager *game_manager, void *ctx)
 {
     // Do some initialization here, for example you can load score from storage.
+    // check if enough memory
+    if (!is_enough_heap(sizeof(GameContext), true))
+    {
+        FURI_LOG_E("Game", "Not enough heap memory.. ending game early.");
+        GameContext *game_context = ctx;
+        game_context->ended_early = true;
+        game_manager_game_stop(game_manager); // end game early
+        return;
+    }
     // For simplicity, we will just set it to 0.
     GameContext *game_context = ctx;
     game_context->fps = atof_(fps_choices_str[fps_index]);
@@ -73,10 +82,20 @@ static void game_start(GameManager *game_manager, void *ctx)
     // FlipperHTTP
     if (game_context->game_mode == GAME_MODE_PVP)
     {
+        // check if enough memory
+        if (!is_enough_heap(sizeof(FlipperHTTP), true))
+        {
+            FURI_LOG_E("Game", "Not enough heap memory.. ending game early.");
+            game_context->ended_early = true;
+            game_manager_game_stop(game_manager); // end game early
+            return;
+        }
         game_context->fhttp = flipper_http_alloc();
         if (!game_context->fhttp)
         {
             FURI_LOG_E("Game", "Failed to allocate FlipperHTTP");
+            game_context->ended_early = true;
+            game_manager_game_stop(game_manager); // end game early
             return;
         }
     }

+ 1 - 1
game/level.c

@@ -44,7 +44,7 @@ void set_world(Level *level, GameManager *manager, char *id)
         return;
     }
 
-    if (!is_enough_heap(28400))
+    if (!is_enough_heap(28400, true))
     {
         FURI_LOG_E("Game", "Not enough heap memory.. ending game early.");
         GameContext *game_context = game_manager_game_context_get(manager);