Posted at
Siv3DDay 21

Siv3Dでデバッグ用のテキスト表示をうまいことやる方法

Siv3DではPlintln()でテキストの簡易表示ができます。

テキストの簡易表示 1

この簡易表示はClearPrint()で削除するまで画面に残り続けますが、

ClearPrint()実行時には全ての簡易テキストが削除されます。

毎フレーム更新される情報を表示したい場合、

# include <Siv3D.hpp>

void Main()
{
while (System::Update())
{
ClearPrint();
Plintln(hoge0);
Plintln(hoge1);
Plintln(hoge2);
}
}

と書くことで、スッキリと表示させることができます。

デバッグに必要な情報を表示する手段として、このPlintln()は便利な関数ですが、

毎フレーム更新したい情報とそうではない情報が混在するとき、困ったことになります。

ClearPrint()を使うと全ての簡易テキストが削除されてしまうため、

毎フレームClearPrint()を呼ぶと、1フレームしか簡易テキストが表示されなくなったりします。

# include <Siv3D.hpp>

void Main()
{
int a = 0;

while (System::Update())
{
ClearPrint();
Plintln(L"aaa");
Plintln(L"111");

if(a % 10 == 0){
Plintln(L"bbb");
}
a++;
}
}

そこで、このようなクラスを作ります。

#pragma once

# include <Siv3D.hpp>

class DebugPrint
{
private:
std::unordered_map<String, String> m_VariableMap;
std::unordered_map<String, int> m_UpdateFrameMap;

public:
DebugPrint(){
m_VariableSetMap.clear();
m_UpdateFrameMap.clear();
}
~DebugPrint();

void SetVariable(String id, String variable) {
m_VariableMap[id] = variable;
m_UpdateFrameMap[id] = System::FrameCount();
}
void Draw() {
ClearPrint();
for (auto& v : m_VariableMap) {
Println( m_UpdateFrameMap[v.first], L":", v.first, L":", variable.second);
}
}
};

以下のように使います。

#include "DebugPrint.h"

void Main()
{
DebugPrint dp;
int a = 0;

while (System::Update())
{
ClearPrint();
dp.SetVariable(L"hoge0",L"aaa");
dp.SetVariable(L"hoge1",Format(111));

if(a % 10 == 0){
dp.SetVariable(L"hoge2",L"bbb");
}
a++;

dp.Draw();
}
}

以下のように表示されるはず。

123:hoge0:aaa

123:hoge1:111
120:hoge2:bbb

Singletonを使えばソースコード上の好きなところで呼び出せます。

シングルトンのベターな実装方法

void Foo::Update(){

DebugPrint& dp = singleton<DebugPrint>::get_instance();
dp.SetVariable(L"Foo",L"Bar");
}

うまく使って開発の役に立てましょう。