]> granicus.if.org Git - nethack/commitdiff
move lua context out of dungeons[]
authorPatR <rankin@nethack.org>
Wed, 6 May 2020 01:06:00 +0000 (18:06 -0700)
committerPatR <rankin@nethack.org>
Wed, 6 May 2020 01:06:00 +0000 (18:06 -0700)
and out of save files so restore doesn't need to clear stale data.
Behavior should be the same as before, except that when entering
the endgame branch and discarding the main dungeon and its other
branches, lua theme context is now discarded for those too.

include/decl.h
include/dungeon.h
include/extern.h
include/patchlevel.h
src/decl.c
src/do.c
src/dungeon.c
src/mklev.c
src/save.c

index 6b7142e577cd15ac5947dbba6ededdb293c8d1a9..1caf4c5bc3c7abd87635a5225787bb228fc1c28e 100644 (file)
@@ -949,6 +949,7 @@ struct instance_globals {
     int mhitu_dieroll;
 
     /* mklev.c */
+    genericptr_t luathemes[MAXDUNGEON];
     xchar vault_x;
     xchar vault_y;
     boolean made_branch; /* used only during level creation */
index eba96d8bd8b4f96e4290392b8b1337f7373d427d..b0e3c1b93661dd94543cca777c48c6d668c0cd14 100644 (file)
@@ -67,7 +67,6 @@ typedef struct dungeon {   /* basic dungeon identifier */
     xchar dunlev_ureached; /* how deep you have been in this dungeon */
     int ledger_start,      /* the starting depth in "real" terms */
         depth_start;       /* the starting depth in "logical" terms */
-    lua_State *themelua;   /* themerms compiled lua */
 } dungeon;
 
 /*
index a5730affcd0f1f4d96b51ce2d3f82e4017425fce..6d177cb8c35e07a2099831a487e2d1c3b6617746 100644 (file)
@@ -1325,6 +1325,7 @@ E void NDECL(sort_rooms);
 E void FDECL(add_room, (int, int, int, int, BOOLEAN_P, SCHAR_P, BOOLEAN_P));
 E void FDECL(add_subroom, (struct mkroom *, int, int, int, int, BOOLEAN_P,
                            SCHAR_P, BOOLEAN_P));
+E void FDECL(free_luathemes, (BOOLEAN_P));
 E void NDECL(makecorridors);
 E void FDECL(add_door, (int, int, struct mkroom *));
 E void NDECL(clear_level_structures);
index b02d2d613632043012135e740c23d9969ca95675..24b92cf36ec20161805c17d7d41186aed8c2d900 100644 (file)
@@ -14,7 +14,7 @@
  * Incrementing EDITLEVEL can be used to force invalidation of old bones
  * and save files.
  */
-#define EDITLEVEL 19
+#define EDITLEVEL 20
 
 #define COPYRIGHT_BANNER_A "NetHack, Copyright 1985-2020"
 #define COPYRIGHT_BANNER_B \
index a6de86e358353a1c83909fcb53dba08afb5f34d8..0f078496b24167875caff0c8360015fd041f4501 100644 (file)
@@ -413,7 +413,7 @@ const struct instance_globals g_init = {
     DUMMY, /* warnsyms */
 
     /* dungeon.c */
-    UNDEFINED_VALUE, /* n_dgns */
+    0, /* n_dgns */
     NULL, /* branches */
     NULL, /* mapseenchn */
 
@@ -478,6 +478,7 @@ const struct instance_globals g_init = {
     UNDEFINED_VALUE, /* mhitu_dieroll */
 
     /* mklev.c */
+    UNDEFINED_VALUES, /* luathemes[] */
     UNDEFINED_VALUE, /* vault_x */
     UNDEFINED_VALUE, /* vault_y */
     UNDEFINED_VALUE, /* made_branch */
index 530f09a61b333c20ece13c357630e89532ae2cb4..8feb069a56fd2910c3486546f36708daf0c68118 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -1420,6 +1420,8 @@ boolean at_stairs, falling, portal;
         update_mlstmv(); /* current monsters are becoming inactive */
         if (nhfp->structlevel)
             bufon(nhfp->fd);       /* use buffered output */
+    } else {
+        free_luathemes(TRUE);
     }
     save_mode = nhfp->mode;
     nhfp->mode = cant_go_back ? FREEING : (WRITING | FREEING);
index e5c2be68bfd29750a3485eb42289aa8b45026846..f376e5237bfcc48f10a8a97a8cd31e935964787d 100644 (file)
@@ -144,23 +144,24 @@ boolean perform_write, free_data;
             bwrite(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns);
             bwrite(nhfp->fd, (genericptr_t) g.dungeons,
                    sizeof(dungeon) * (unsigned) g.n_dgns);
-            bwrite(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
+            bwrite(nhfp->fd, (genericptr_t) &g.dungeon_topology,
+                   sizeof g.dungeon_topology);
             bwrite(nhfp->fd, (genericptr_t) g.tune, sizeof tune);
         }
         for (count = 0, curr = g.branches; curr; curr = curr->next)
             count++;
         if (nhfp->structlevel)
-            bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count));
+            bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
 
         for (curr = g.branches; curr; curr = curr->next) {
           if (nhfp->structlevel)
-              bwrite(nhfp->fd, (genericptr_t) curr, sizeof(branch));
+              bwrite(nhfp->fd, (genericptr_t) curr, sizeof *curr);
         }
         count = maxledgerno();
         if (nhfp->structlevel) { 
             bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
             bwrite(nhfp->fd, (genericptr_t) g.level_info,
-                   (unsigned) count * sizeof(struct linfo));
+                   (unsigned) count * sizeof (struct linfo));
             bwrite(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
         }
         for (count = 0, curr_ms = g.mapseenchn; curr_ms;
@@ -168,7 +169,7 @@ boolean perform_write, free_data;
             count++;
 
         if (nhfp->structlevel)
-            bwrite(nhfp->fd, (genericptr_t) &count, sizeof(count));
+            bwrite(nhfp->fd, (genericptr_t) &count, sizeof count);
 
         for (curr_ms = g.mapseenchn; curr_ms; curr_ms = curr_ms->next) {
             save_mapseen(nhfp, curr_ms);
@@ -203,23 +204,22 @@ NHFILE *nhfp;
     mapseen *curr_ms, *last_ms;
 
     if (nhfp->structlevel) {
-        mread(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof(g.n_dgns));
-        mread(nhfp->fd, (genericptr_t) g.dungeons, sizeof(dungeon) * (unsigned) g.n_dgns);
-        mread(nhfp->fd, (genericptr_t) &g.dungeon_topology, sizeof g.dungeon_topology);
+        mread(nhfp->fd, (genericptr_t) &g.n_dgns, sizeof g.n_dgns);
+        mread(nhfp->fd, (genericptr_t) g.dungeons,
+              sizeof (dungeon) * (unsigned) g.n_dgns);
+        mread(nhfp->fd, (genericptr_t) &g.dungeon_topology,
+              sizeof g.dungeon_topology);
         mread(nhfp->fd, (genericptr_t) g.tune, sizeof tune);
     }
     last = g.branches = (branch *) 0;
 
-    for (i = 0; i < g.n_dgns; i++)
-        g.dungeons[i].themelua = (lua_State *) 0;
-
     if (nhfp->structlevel)
-        mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
+        mread(nhfp->fd, (genericptr_t) &count, sizeof count);
 
     for (i = 0; i < count; i++) {
-        curr = (branch *) alloc(sizeof(branch));
+        curr = (branch *) alloc(sizeof *curr);
         if (nhfp->structlevel)
-            mread(nhfp->fd, (genericptr_t) curr, sizeof(branch));
+            mread(nhfp->fd, (genericptr_t) curr, sizeof *curr);
         curr->next = (branch *) 0;
         if (last)
             last->next = curr;
@@ -229,18 +229,18 @@ NHFILE *nhfp;
     }
 
     if (nhfp->structlevel)
-        mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
+        mread(nhfp->fd, (genericptr_t) &count, sizeof count);
 
     if (count >= MAXLINFO)
         panic("level information count larger (%d) than allocated size",
               count);
     if (nhfp->structlevel)
         mread(nhfp->fd, (genericptr_t) g.level_info,
-              (unsigned) count * sizeof(struct linfo));
+              (unsigned) count * sizeof (struct linfo));
 
     if (nhfp->structlevel) {
         mread(nhfp->fd, (genericptr_t) &g.inv_pos, sizeof g.inv_pos);
-        mread(nhfp->fd, (genericptr_t) &count, sizeof(count));
+        mread(nhfp->fd, (genericptr_t) &count, sizeof count);
     }
 
     last_ms = (mapseen *) 0;
@@ -1030,7 +1030,6 @@ init_dungeons()
         Strcpy(g.dungeons[i].dname, dgn_name); /* FIXME: dname length */
         Strcpy(g.dungeons[i].proto, dgn_protoname); /* FIXME: proto length */
         Strcpy(g.dungeons[i].themerms, dgn_themerms); /* FIXME: length */
-        g.dungeons[i].themelua = (lua_State *) 0;
         g.dungeons[i].boneid = *dgn_bonetag ? *dgn_bonetag : 0;
         free((genericptr) dgn_fill);
         /* free((genericptr) dgn_protoname); -- stored in pd.tmpdungeon[] */
index 71f6f4bef312dee62ab73a26ce031a2882b99ff7..007262ea036b6ceb37b5fdacc9604df60c5db4b9 100644 (file)
@@ -239,30 +239,46 @@ boolean special;
     g.nsubroom++;
 }
 
+void
+free_luathemes(keependgame)
+boolean keependgame; /* False: exiting, True: discarding main dungeon */
+{
+    int i;
+
+    for (i = 0; i < g.n_dgns; ++i) {
+        if (keependgame && i == astral_level.dnum)
+            continue;
+        if (g.luathemes[i]) {
+            lua_close((lua_State *) g.luathemes[i]);
+            g.luathemes[i] = (lua_State *) 0;
+        }
+    }
+}
+
 static void
 makerooms()
 {
     boolean tried_vault = FALSE;
     int themeroom_tries = 0;
-    boolean dothemes = (g.dungeons[u.uz.dnum].themelua != NULL);
-    char *fname = g.dungeons[u.uz.dnum].themerms;
+    char *fname;
+    lua_State *themes = (lua_State *) g.luathemes[u.uz.dnum];
 
-    if (*fname && !g.dungeons[u.uz.dnum].themelua) {
-        g.dungeons[u.uz.dnum].themelua = nhl_init();
-        if (g.dungeons[u.uz.dnum].themelua) {
-            if (!nhl_loadlua(g.dungeons[u.uz.dnum].themelua, fname)) {
+    if (!themes && *(fname = g.dungeons[u.uz.dnum].themerms)) {
+        if ((themes = nhl_init()) != 0) {
+            if (!nhl_loadlua(themes, fname)) {
                 /* loading lua failed, don't use themed rooms */
-                g.dungeons[u.uz.dnum].themerms[0] = '\0';
-                lua_close(g.dungeons[u.uz.dnum].themelua);
-                g.dungeons[u.uz.dnum].themelua = NULL;
-                dothemes = FALSE;
+                lua_close(themes);
+                themes = (lua_State *) 0;
             } else {
-                dothemes = TRUE;
+                /* success; save state for this dungeon branch */
+                g.luathemes[u.uz.dnum] = (genericptr_t) themes;
             }
         }
+        if (!themes) /* don't try again when making next level */
+            *fname = '\0'; /* g.dungeons[u.uz.dnum].themerms */
     }
 
-    if (dothemes) {
+    if (themes) {
         create_des_coder();
     }
 
@@ -277,12 +293,11 @@ makerooms()
                 g.rooms[g.nroom].hx = -1;
             }
         } else {
-            if (dothemes) {
+            if (themes) {
                 g.in_mk_themerooms = TRUE;
                 g.themeroom_failed = FALSE;
-                lua_getglobal(g.dungeons[u.uz.dnum].themelua,
-                              "themerooms_generate");
-                lua_call(g.dungeons[u.uz.dnum].themelua, 0, 0);
+                lua_getglobal(themes, "themerooms_generate");
+                lua_call(themes, 0, 0);
                 g.in_mk_themerooms = FALSE;
                 if (g.themeroom_failed
                     && ((themeroom_tries++ > 10)
@@ -294,7 +309,7 @@ makerooms()
             }
         }
     }
-    if (dothemes) {
+    if (themes) {
         wallification(1, 0, COLNO - 1, ROWNO - 1);
         free(g.coder);
         g.coder = NULL;
index c2d710f4c87cb9f4fd897a788603ea1d51bfca85..b3fe866564cf119a30483bac65f85f5eaaa95e07 100644 (file)
@@ -1070,17 +1070,12 @@ free_dungeons()
 {
 #ifdef FREE_ALL_MEMORY
     NHFILE tnhfp;
-    int i;
 
     zero_nhfile(&tnhfp);    /* also sets fd to -1 */
     tnhfp.mode = FREEING;
     savelevchn(&tnhfp);
     save_dungeon(&tnhfp, FALSE, TRUE);
-    for (i = 0; i < g.n_dgns; i++)
-        if (g.dungeons[i].themelua) {
-            lua_close(g.dungeons[i].themelua);
-            g.dungeons[i].themelua = (lua_State *) 0;
-        }
+    free_luathemes(TRUE);
 #endif
     return;
 }