OSDN Git Service

[Refactor] メッセージ履歴の処理をC++機能で書き直す
authorHabu <habu1010+github@gmail.com>
Mon, 3 May 2021 23:52:41 +0000 (08:52 +0900)
committerHabu <habu1010+github@gmail.com>
Tue, 4 May 2021 05:42:54 +0000 (14:42 +0900)
現在のメッセージ履歴の処理は自前でメッセージ保存用リングバッファと
メッセージを指すポインタのリングバッファを管理しており、およそ
人間の読めるコードではない。
dequeとstringを使用して分かりやすく書き直す。

src/main/game-data-initializer.cpp
src/view/display-messages.cpp
src/view/display-messages.h

index 6137e80..d0865d8 100644 (file)
@@ -70,10 +70,6 @@ errr init_other(player_type *player_ptr)
     C_MAKE(macro__buf, FILE_READ_BUFF_SIZE, char);
     quark_init();
 
-    C_MAKE(message__ptr, MESSAGE_MAX, u32b);
-    C_MAKE(message__buf, MESSAGE_BUF, char);
-    message__tail = MESSAGE_BUF;
-
     for (int i = 0; option_info[i].o_desc; i++) {
         int os = option_info[i].o_set;
         int ob = option_info[i].o_bit;
index 4e8bbc6..787c117 100644 (file)
 #include "util/int-char-converter.h"
 #include "world/world.h"
 
-/* The next "free" index to use */
-u32b message__next;
-
-/* The index of the oldest message (none yet) */
-u32b message__last;
-
-/* The next "free" offset */
-u32b message__head;
-
-/* The offset to the oldest used char (none yet) */
-u32b message__tail;
-
-/* The array of offsets, by index [MESSAGE_MAX] */
-u32b *message__ptr;
-
-/* The array of chars, by offset [MESSAGE_BUF] */
-char *message__buf;
+#include <deque>
+#include <string>
 
 /* Used in msg_print() for "buffering" */
 bool msg_flag;
 
 COMMAND_CODE now_message;
 
+namespace {
+std::deque<std::string> message_history;
+}
+
 /*!
  * @brief 保存中の過去ゲームメッセージの数を返す。 / How many messages are "available"?
  * @return 残っているメッセージの数
  */
 s32b message_num(void)
 {
-    int n;
-    int last = message__last;
-    int next = message__next;
-
-    if (next < last)
-        next += MESSAGE_MAX;
-
-    n = (next - last);
-    return (n);
+    return message_history.size();
 }
 
 /*!
@@ -62,37 +43,22 @@ concptr message_str(int age)
     if ((age < 0) || (age >= message_num()))
         return ("");
 
-    s32b x = (message__next + MESSAGE_MAX - (age + 1)) % MESSAGE_MAX;
-    s32b o = message__ptr[x];
-    concptr s = &message__buf[o];
-    return (s);
+    return message_history[age].c_str();
 }
 
-/*!
- * @brief ゲームメッセージをログに追加する。 / Add a new message, with great efficiency
- * @param str 保存したいメッセージ
- */
-void message_add(concptr str)
+static void message_add_aux(std::string str)
 {
-    u32b i;
-    int x, m;
-    char u[4096];
-    char splitted1[81];
-    concptr splitted2;
-
-    if (!str)
-        return;
+    std::string splitted;
 
-    u32b n = strlen(str);
-    if (n >= MESSAGE_BUF / 4)
+    if (str.empty())
         return;
 
-    if (n > 80) {
+    // 80桁を超えるメッセージは80桁ずつ分割する
+    if (str.length() > 80) {
+        int n;
 #ifdef JP
-        concptr t = str;
-        for (n = 0; n < 80; n++, t++) {
-            if (iskanji(*t)) {
-                t++;
+        for (n = 0; n < 80; n++) {
+            if (iskanji(str[n])) {
                 n++;
             }
         }
@@ -107,53 +73,33 @@ void message_add(concptr str)
         if (n == 60)
             n = 80;
 #endif
-        splitted2 = str + n;
-        strncpy(splitted1, str, n);
-        splitted1[n] = '\0';
-        str = splitted1;
-    } else {
-        splitted2 = NULL;
+        splitted = str.substr(n);
+        str = str.substr(0, n);
     }
 
-    m = message_num();
-    int k = m / 4;
-    if (k > MESSAGE_MAX / 32)
-        k = MESSAGE_MAX / 32;
-    for (i = message__next; m; m--) {
-        int j = 1;
-        char buf[1024];
-        char *t;
-        concptr old;
-        if (i-- == 0)
-            i = MESSAGE_MAX - 1;
-
-        old = &message__buf[message__ptr[i]];
-        if (!old)
-            continue;
-
-        strcpy(buf, old);
+    // 直前と同じメッセージの場合、「~ <xNN>」と表示する
+    if (!message_history.empty()) {
+        const char *t;
+        std::string_view last_message = message_history.front();
 #ifdef JP
-        for (t = buf; *t && (*t != '<' || (*(t + 1) != 'x')); t++)
+        for (t = last_message.data(); *t && (*t != '<' || (*(t + 1) != 'x')); t++)
             if (iskanji(*t))
                 t++;
 #else
-        for (t = buf; *t && (*t != '<'); t++)
+        for (t = last_message.data(); *t && (*t != '<'); t++)
             ;
 #endif
-        if (*t) {
-            if (strlen(buf) < A_MAX)
-                break;
-
-            *(t - 1) = '\0';
-            j = atoi(t + 2);
+        int j = 1;
+        if (*t && t != last_message.data()) {
+            if (last_message.length() >= sizeof(" <xN>") - 1) {
+                last_message = last_message.substr(0, t - last_message.data() - 1);
+                j = atoi(t + 2);
+            }
         }
 
-        if (streq(buf, str) && (j < 1000)) {
-            j++;
-            message__next = i;
-            str = u;
-            sprintf(u, "%s <x%d>", buf, j);
-            n = strlen(str);
+        if (str == last_message && (j < 1000)) {
+            str = format("%s <x%d>", str.c_str(), j + 1);
+            message_history.pop_front();
             if (!now_message)
                 now_message++;
         } else {
@@ -161,97 +107,25 @@ void message_add(concptr str)
             num_more++;
             now_message++;
         }
-
-        break;
     }
 
-    for (i = message__next; k; k--) {
-        int q;
-        concptr old;
-
-        if (i-- == 0)
-            i = MESSAGE_MAX - 1;
-
-        if (i == message__last)
-            break;
-
-        q = (message__head + MESSAGE_BUF - message__ptr[i]) % MESSAGE_BUF;
+    message_history.push_front(std::move(str));
 
-        if (q > MESSAGE_BUF / 2)
-            continue;
+    if (message_history.size() == MESSAGE_MAX)
+        message_history.pop_back();
 
-        old = &message__buf[message__ptr[i]];
-        if (!streq(old, str))
-            continue;
-
-        x = message__next++;
-        if (message__next == MESSAGE_MAX)
-            message__next = 0;
-        if (message__next == message__last)
-            message__last++;
-        if (message__last == MESSAGE_MAX)
-            message__last = 0;
-
-        message__ptr[x] = message__ptr[i];
-        if (splitted2 != NULL) {
-            message_add(splitted2);
-        }
-
-        return;
-    }
-
-    if (message__head + n + 1 >= MESSAGE_BUF) {
-        for (i = message__last; TRUE; i++) {
-            if (i == MESSAGE_MAX)
-                i = 0;
-            if (i == message__next)
-                break;
-            if (message__ptr[i] >= message__head) {
-                message__last = i + 1;
-            }
-        }
-
-        if (message__tail >= message__head)
-            message__tail = 0;
-
-        message__head = 0;
+    if (!splitted.empty()) {
+        message_add_aux(std::move(splitted));
     }
+}
 
-    if (message__head + n + 1 > message__tail) {
-        message__tail = message__head + n + 1;
-        while (message__buf[message__tail - 1])
-            message__tail++;
-
-        for (i = message__last; TRUE; i++) {
-            if (i == MESSAGE_MAX)
-                i = 0;
-            if (i == message__next)
-                break;
-            if ((message__ptr[i] >= message__head) && (message__ptr[i] < message__tail)) {
-                message__last = i + 1;
-            }
-        }
-    }
-
-    x = message__next++;
-    if (message__next == MESSAGE_MAX)
-        message__next = 0;
-    if (message__next == message__last)
-        message__last++;
-    if (message__last == MESSAGE_MAX)
-        message__last = 0;
-
-    message__ptr[x] = message__head;
-    for (i = 0; i < n; i++) {
-        message__buf[message__head + i] = str[i];
-    }
-
-    message__buf[message__head + i] = '\0';
-    message__head += n + 1;
-
-    if (splitted2 != NULL) {
-        message_add(splitted2);
-    }
+/*!
+ * @brief ゲームメッセージをログに追加する。 / Add a new message, with great efficiency
+ * @param msg 保存したいメッセージ
+ */
+void message_add(concptr msg)
+{
+    message_add_aux(msg);
 }
 
 bool is_msg_window_flowed(void)
index f48eba8..2519c65 100644 (file)
@@ -8,20 +8,6 @@
  */
 #define MESSAGE_MAX 81920
 
-/*
- * OPTION: Maximum space for the message text buffer (see "io.c")
- * Default: assume that each of the 2048 messages is repeated an
- * average of three times, and has an average length of 48
- */
-#define MESSAGE_BUF 655360
-
-extern u32b message__next;
-extern u32b message__last;
-extern u32b message__head;
-extern u32b message__tail;
-extern u32b *message__ptr;
-extern char *message__buf;
-
 extern bool msg_flag;
 extern COMMAND_CODE now_message;