OSDN Git Service

[Refactor] term_win にclone()、resize()メソッドを追加
authorHabu <habu1010+github@gmail.com>
Mon, 26 Apr 2021 15:33:16 +0000 (00:33 +0900)
committerHabu <habu1010+github@gmail.com>
Mon, 26 Apr 2021 15:33:16 +0000 (00:33 +0900)
term_win に自身をディープコピーするclone()メソッド、
画面サイズを変更するresize()メソッドを追加する。
これらを使用して term_load()、term_save()、term_resize() を
簡潔に書き換える。

src/term/z-term.cpp
src/term/z-term.h

index 9d9e37e..186fe23 100644 (file)
@@ -58,26 +58,34 @@ std::unique_ptr<term_win> term_win::create(TERM_LEN w, TERM_LEN h)
     return std::make_unique<impl>(w, h);
 }
 
-/*
- * Copy a "term_win" from another
- */
-static errr term_win_copy(std::unique_ptr<term_win> &s, const std::unique_ptr<term_win> &f, TERM_LEN w, TERM_LEN h)
+std::unique_ptr<term_win> term_win::clone() const
+{
+    return std::make_unique<term_win>(*this);
+}
+
+void term_win::resize(TERM_LEN w, TERM_LEN h)
 {
-    /* Copy contents */
+    /* Ignore non-changes */
+    if (this->a.size() == static_cast<size_t>(h) && this->a[0].size() == static_cast<size_t>(w))
+        return;
+
+    this->a.resize(h, std::vector<TERM_COLOR>(w));
+    this->c.resize(h, std::vector<char>(w));
+    this->ta.resize(h, std::vector<TERM_COLOR>(w));
+    this->tc.resize(h, std::vector<char>(w));
+
     for (TERM_LEN y = 0; y < h; y++) {
-        std::copy_n(f->a[y].begin(), w, s->a[y].begin());
-        std::copy_n(f->c[y].begin(), w, s->c[y].begin());
-        std::copy_n(f->ta[y].begin(), w, s->ta[y].begin());
-        std::copy_n(f->tc[y].begin(), w, s->tc[y].begin());
+        this->a[y].resize(w);
+        this->c[y].resize(w);
+        this->ta[y].resize(w);
+        this->tc[y].resize(w);
     }
 
-    /* Copy cursor */
-    s->cx = f->cx;
-    s->cy = f->cy;
-    s->cu = f->cu;
-    s->cv = f->cv;
-
-    return 0;
+    /* Illegal cursor */
+    if (this->cx >= w)
+        this->cu = 1;
+    if (this->cy >= h)
+        this->cu = 1;
 }
 
 /*** External hooks ***/
@@ -1851,14 +1859,8 @@ errr term_inkey(char *ch, bool wait, bool take)
  */
 errr term_save(void)
 {
-    TERM_LEN w = Term->wid;
-    TERM_LEN h = Term->hgt;
-
     /* Push stack */
-    Term->mem_stack.push(term_win::create(w, h));
-
-    /* Grab */
-    term_win_copy(Term->mem_stack.top(), Term->scr, w, h);
+    Term->mem_stack.push(Term->scr->clone());
 
     return 0;
 }
@@ -1883,7 +1885,8 @@ errr term_load(bool load_all)
     }
 
     /* Load */
-    term_win_copy(Term->scr, Term->mem_stack.top(), w, h);
+    Term->scr.swap(Term->mem_stack.top());
+    Term->scr->resize(w, h);
 
     /* Pop stack */
     Term->mem_stack.pop();
@@ -1936,8 +1939,6 @@ errr term_exchange(void)
  */
 errr term_resize(TERM_LEN w, TERM_LEN h)
 {
-    TERM_LEN wid, hgt;
-
     /* Resizing is forbidden */
     if (Term->fixed_shape)
         return -1;
@@ -1952,85 +1953,15 @@ errr term_resize(TERM_LEN w, TERM_LEN h)
 
     use_bigtile = arg_bigtile;
 
-    /* Minimum dimensions */
-    wid = MIN(Term->wid, w);
-    hgt = MIN(Term->hgt, h);
-
-    /* Save old window */
-    std::unique_ptr<term_win> hold_old = std::move(Term->old);
-
-    /* Save old window */
-    std::unique_ptr<term_win> hold_scr = std::move(Term->scr);
-
-    /* Save old window */
-    std::unique_ptr<term_win> hold_tmp = std::move(Term->tmp);
+    /* Resize windows */
+    Term->old->resize(w, h);
+    Term->scr->resize(w, h);
+    if (Term->tmp)
+        Term->tmp->resize(w, h);
 
-    // 画面情報保存スタックをバックアップ(ウィンドウサイズが変わるので単純なムーブやコピーでは対応できない)
-    std::stack<std::unique_ptr<term_win>> hold_mem_stack;
-    while (!Term->mem_stack.empty()) {
-        hold_mem_stack.push(std::move(Term->mem_stack.top()));
-        Term->mem_stack.pop();
-    }
-
-    /* Create new scanners */
-    Term->x1 = std::vector<TERM_LEN>(h);
-    Term->x2 = std::vector<TERM_LEN>(h);
-
-    /* Create new window */
-    Term->old = term_win::create(w, h);
-
-    /* Save the contents */
-    term_win_copy(Term->old, hold_old, wid, hgt);
-
-    /* Create new window */
-    Term->scr = term_win::create(w, h);
-
-    /* Save the contents */
-    term_win_copy(Term->scr, hold_scr, wid, hgt);
-
-    /* If needed */
-    if (hold_tmp) {
-        /* Create new window */
-        Term->tmp = term_win::create(w, h);
-
-        /* Save the contents */
-        term_win_copy(Term->tmp, hold_tmp, wid, hgt);
-    }
-
-    // 退避していた画面情報保存スタックをウィンドウサイズを変えながらリストア
-    while (!hold_mem_stack.empty()) {
-        Term->mem_stack.push(term_win::create(w, h));
-        auto &top = Term->mem_stack.top();
-        term_win_copy(top, hold_mem_stack.top(), wid, hgt);
-        hold_mem_stack.pop();
-
-        /* Illegal cursor */
-        if (top->cx >= w)
-            top->cu = 1;
-        if (top->cy >= h)
-            top->cu = 1;
-    }
-
-    /* Illegal cursor */
-    if (Term->old->cx >= w)
-        Term->old->cu = 1;
-    if (Term->old->cy >= h)
-        Term->old->cu = 1;
-
-    /* Illegal cursor */
-    if (Term->scr->cx >= w)
-        Term->scr->cu = 1;
-    if (Term->scr->cy >= h)
-        Term->scr->cu = 1;
-
-    /* If needed */
-    if (Term->tmp) {
-        /* Illegal cursor */
-        if (Term->tmp->cx >= w)
-            Term->tmp->cu = 1;
-        if (Term->tmp->cy >= h)
-            Term->tmp->cu = 1;
-    }
+    /* Resize scanners */
+    Term->x1.resize(h);
+    Term->x2.resize(h);
 
     /* Save new size */
     Term->wid = w;
index d1d225e..df70aed 100644 (file)
@@ -24,6 +24,8 @@
 class term_win {
 public:
     static std::unique_ptr<term_win> create(TERM_LEN w, TERM_LEN h);
+    std::unique_ptr<term_win> clone() const;
+    void resize(TERM_LEN w, TERM_LEN h);
 
     bool cu{}, cv{}; //!< Cursor Useless / Visible codes
     TERM_LEN cx{}, cy{}; //!< Cursor Location (see "Useless")