Sirius X

需要無視の自己満足ブログです。

【Visual C++】【ゲーム開発】spdlogアタッチメント

Category:Rockman Reanimated, Visual Studio, ゲーム開発, ソフトウェア Comment:0

eye-catch

ゲーム開発で必要?と思われるであろう、ログ出力をしています。

C++の場合はとにかく早いライブラリが需要高で、案の定spdlog。

作者はイスラエルの方みたいです。


// spdlog_inc.cpp

// includes.
#include <sstream>
#include <string>
#include <spdlog/spdlog.h>
#include <spdlog/sinks/basic_file_sink.h>
#include "src/forms/trace/log_classification.hpp"


namespace forms {

    namespace trace {

        namespace writer {

            void writeGenericLogData(std::string filename, std::string title, std::string body, LogClassification type) {
                try {
                    auto i_logger = spdlog::basic_logger_mt(title, filename);
                    switch (type) {
                    case LogClassification::LOG_LEVEL_INFO:
                        i_logger->info(body);
                        break;
                    case LogClassification::LOG_LEVEL_TRACE:
                        spdlog::set_level(spdlog::level::trace);
                        i_logger->trace(body);
                        break;
                    case LogClassification::LOG_LEVEL_DEBUG:
                        i_logger->debug(body);
                        break;
                    case LogClassification::LOG_LEVEL_WARN:
                        i_logger->warn(body);
                        break;
                    case LogClassification::LOG_LEVEL_ERROR:
                        i_logger->error(body);
                        break;
                    case LogClassification::LOG_LEVEL_CRITICAL:
                        i_logger->critical(body);
                        break;
                    default:
                        i_logger->log(spdlog::level::off, body);
                        break;
                    }
                    spdlog::drop_all();
                }
                catch (const spdlog::spdlog_ex& ex) {
                    std::stringstream ss;
                    ss << "Log init failure: " << ex.what() << std::string("\0");
                    std::string exstr = ss.str();
                    MessageBox(NULL, exstr.c_str(), "spdlog Exception info", MB_OK);
                }
            }  // void writeGenericLogData(std::string filename, std::string title, std::string body, LogClassification type) func end

        }  // namespace writer

    }  // namespace trace

}  // namespace forms

spdlogライブラリをGitHubの作者ぺージ (https://github.com/gabime/spdlog) から入手して、該当のプロジェクトフォルダに追加。

Visual Studioの場合(しか分からないが…)は、対象プロジェクトのプロパティで「追加のインクルードディレクトリ」に「$(SolutionDir)」(もしくは $(ProjectDir)?)を設定すれば、使用できるようになる。

評価された値で確認する

これはspdlog.h自体がspdlogのアペンディックスをシステムインクルードしている状態のために必要。

何なのかと言うと、山かっこでinclude している (#include <spdlog/spdlog.h>のように)。

spdlog自体がファイルロガーとして速度を重視しているためである。C言語におけるインクルードの引用符の仕組みについてはGoogle大先生に聞いてみてほしい。

ダブルクォートより、インクルードディレクトリを設定した上で山かっこincludeを行うと速度に影響がある(らしいよ( ^ω^))


実際に使用してみる。

// formal.hpp


#ifndef ERIS_FORMS_TRACE_DUPLICATE_FORMAL_HPP_
#define ERIS_FORMS_TRACE_DUPLICATE_FORMAL_HPP_

// includes.
#include <string>
#include "src/subroutine/kits/timecontroller/systime_script.hpp"
#include "src/forms/config/env.hpp"
#include "src/forms/trace/log_classification.hpp"


namespace {
    const std::string defaultLogFilePath = "storages/dat/log/";
}


namespace forms {

    namespace trace {

        namespace duplicate {

            class FormalDuplicate {

            public:
                FormalDuplicate();
                ~FormalDuplicate() = default;
                bool doWriteLog(std::string text);
                bool doWriteEditingStyleLog(std::string title, std::string body, LogClassification lvl);

            private:
                std::string outputLogFilePath;
                std::string createLogFileName(std::string org_name);

            };

            inline FormalDuplicate::FormalDuplicate() {
                std::string params = "";
                // logfile name is 'system-log-[YYYYMMDD].log'.
                if (!config::getParameter("$STREAM_OUTPUT_LOG_PATH", &params)) params = defaultLogFilePath;
                outputLogFilePath = createLogFileName(params);
            }

            inline std::string FormalDuplicate::createLogFileName(std::string org_name) {
                std::string str;
                if (!subr::kits::timecontroller::getCurrentDateTime(&str, "YYYYMMDD")) return "\0";
                str = org_name + str.substr(0, 6) + "\\system-log-" + str + ".log";  // str.substr(0, 6) + "/" + is Monthly partition(Directory).
                return str;
            }

        }  // namespace duplicate

    }  // namespace trace

}  // namespace forms

#endif // !ERIS_FORMS_TRACE_DUPLICATE_FORMAL_HPP_
// formal.cpp

// includes.
#include "formal.hpp"
#include <string>
#include <Windows.h>
#include "src/forms/trace/writer/spdlogs_inc.hpp"
#include "src/forms/trace/log_classification.hpp"


namespace forms {

    namespace trace {

        namespace duplicate {

            bool FormalDuplicate::doWriteLog(std::string text) {
                writer::writeGenericLogData(outputLogFilePath, "Default log", text, LogClassification::LOG_LEVEL_INFO);
                return true;
            }

            bool FormalDuplicate::doWriteEditingStyleLog(std::string title, std::string body, LogClassification lvl) {
                writer::writeGenericLogData(outputLogFilePath, title, body, lvl);
                return true;
            }

        } // namespace duplicate

    }  // namespace trace

}  // namespace forms
// log_classification.hpp


#ifndef ERIS_FORMS_TRACE_LOG_CLASSIFICATION_HPP_
#define ERIS_FORMS_TRACE_LOG_CLASSIFICATION_HPP_

namespace forms {

    namespace trace {

        enum class LogClassification {
            LOG_LEVEL_OFF
            , LOG_LEVEL_TRACE
            , LOG_LEVEL_DEBUG
            , LOG_LEVEL_INFO
            , LOG_LEVEL_WARN
            , LOG_LEVEL_ERROR
            , LOG_LEVEL_CRITICAL
            , LOG_LEVEL_UNKNOWN = 9
        };

    }  // namespace trace

}  // namespace forms

#endif // !ERIS_FORMS_TRACE_LOG_CLASSIFICATION_HPP_

あの・・・説明省略で、、、全部ソース乗っけちゃう馬鹿者は私だああああああ🤗

// 使ってるcpp

#include <DxLib.h>
#include "src/forms/trace/duplicate/formal.hpp"
#include "src/forms/trace/log_classification.hpp"
#include "src/forms/trace/writer/spdlogs_inc.hpp"


using namespace forms::trace;

namespace sequence {

    Sequence::Sequence() {
        log_handle = new duplicate::FormalDuplicate;
    }

    Sequence::~Sequence() {
        delete log_handle;
    }


    Evaluate Sequence::Master(Evaluate evals) {
        /* sample code */
        if (1 == CheckHitKey(KEY_INPUT_ESCAPE)) {
            log_handle->doWriteEditingStyleLog("処理ログ", "ログ出力を検証しています。", forms::trace::LogClassification::LOG_LEVEL_TRACE);
            return Evaluate::PROC_QUIT;
        }
        return Evaluate::PROC_SUCCEED;
    }

}  // namespace sequence

DxLib.hとかCheckHitKey(KEY_INPUT_ESCAPE)とかは無視して下さい😫🙇

ここではログレベル トレースとかで出力しようとしているが、通常ロガーハンドラから直接traceメソッドで呼び出しても使用できない。

traceログやdebugログを使用する場合は、以下を指定する。

...

    spdlog::set_level(spdlog::level::trace);   // or necessary to specify spdlog::level::debug.

...
出力結果サンプル

次は入力デバイスの実装ですね( ˘ω˘ )

地道に😇

コメントを残す

メールアドレスが公開されることはありません。