<2021SC@SDUSC>开源游戏引擎Overload代码分析九:OvEditor——Panels(上)

2021SC@SDUSC

开源游戏引擎Overload代码分析九:OvEditor——Panels

前言

这是Overload引擎相关的第十一篇文章,同时也是OvEditor分析的第六篇。Overload引擎的Github主页在这里。

本篇文章将会介绍OvEditor的Panels文件夹中剩余的一些文件,具体应该会涉及Console,GameView,HardwareInfo和ProjectSettings。

一、Console

1.console.h

	class Console : public OvUI::Panels::PanelWindow
	{
	public:
		/**
		* Constructor
		* @param p_title
		* @param p_opened
		* @param p_windowSettings
		*/
		Console
		(
			const std::string& p_title,
			bool p_opened,
			const OvUI::Settings::PanelWindowSettings& p_windowSettings
		);

		/**
		* Method called when a log event occured
		* @param p_logData
		*/
		void OnLogIntercepted(const OvDebug::LogData& p_logData);

		/**
		* Called when the scene plays. It will clear the console if the "Clear on play" settings is on
		*/
		void ClearOnPlay();

		/**
		* Clear the console
		*/
		void Clear();

		/**
		* Filter logs using defined filters
		*/
		void FilterLogs();

		/**
		* Verify if a given log level is allowed by the current filter
		* @param p_logLevel
		*/
		bool IsAllowedByFilter(OvDebug::ELogLevel p_logLevel);

	private:
		void SetShowDefaultLogs(bool p_value);
		void SetShowInfoLogs(bool p_value);
		void SetShowWarningLogs(bool p_value);
		void SetShowErrorLogs(bool p_value);

	private:
		OvUI::Widgets::Layout::Group* m_logGroup;
		std::unordered_map<OvUI::Widgets::Texts::TextColored*, OvDebug::ELogLevel> m_logTextWidgets;

		bool m_clearOnPlay = true;
		bool m_showDefaultLog = true;
		bool m_showInfoLog = true;
		bool m_showWarningLog = true;
		bool m_showErrorLog = true;
	};

定义了console类,是引擎内部的控制台,具体函数在实现在下面讲述。

2.console.cpp

接下来按代码顺序说明。

std::pair<OvUI::Types::Color, std::string> GetWidgetSettingsFromLogData(const OvDebug::LogData& p_logData)
{
	OvUI::Types::Color logColor;
	std::string logHeader;
	std::string logDateFormated = "[";
	bool isSecondPart = false;
	std::for_each(p_logData.date.begin(), p_logData.date.end(), [&logDateFormated, &isSecondPart](char c)
	{ 
		if (isSecondPart)
			logDateFormated.push_back(c == '-' ? ':' : c);

		if (c == '_')
			isSecondPart = true;
	});

	logDateFormated += "] ";

	switch (p_logData.logLevel)
	{
	default:
	case OvDebug::ELogLevel::LOG_DEFAULT:	return { { 1.f, 1.f, 1.f, 1.f }, logDateFormated };
	case OvDebug::ELogLevel::LOG_INFO:		return { { 0.f, 1.f, 1.f, 1.f }, logDateFormated };
	case OvDebug::ELogLevel::LOG_WARNING:	return { { 1.f, 1.f, 0.f, 1.f }, logDateFormated };
	case OvDebug::ELogLevel::LOG_ERROR:		return { { 1.f, 0.f, 0.f, 1.f }, logDateFormated };
	}
}

此函数用于从日志文件中获取设定数据,因为日志文件名有指定格式,所以首先获得用于标记的第二部分,之后根据日志的级别返回标记向量和标记的信息。

OvEditor::Panels::Console::Console
(
	const std::string& p_title,
	bool p_opened,
	const OvUI::Settings::PanelWindowSettings& p_windowSettings
) :
	PanelWindow(p_title, p_opened, p_windowSettings)
{
	allowHorizontalScrollbar = true;

	auto& clearButton = CreateWidget<Buttons::Button>("Clear");
	clearButton.size = { 50.f, 0.f };
	clearButton.idleBackgroundColor = { 0.5f, 0.f, 0.f };
	clearButton.ClickedEvent += std::bind(&Console::Clear, this);
	clearButton.lineBreak = false;

	auto& clearOnPlay = CreateWidget<Selection::CheckBox>(m_clearOnPlay, "Auto clear on play");

	CreateWidget<Layout::Spacing>(5).lineBreak = false;

	auto& enableDefault = CreateWidget<Selection::CheckBox>(true, "Default");
	auto& enableInfo = CreateWidget<Selection::CheckBox>(true, "Info");
	auto& enableWarning = CreateWidget<Selection::CheckBox>(true, "Warning");
	auto& enableError = CreateWidget<Selection::CheckBox>(true, "Error");

	clearOnPlay.lineBreak = false;
	enableDefault.lineBreak = false;
	enableInfo.lineBreak = false;
	enableWarning.lineBreak = false;
	enableError.lineBreak = true;

	clearOnPlay.ValueChangedEvent += [this](bool p_value) { m_clearOnPlay = p_value; };
	enableDefault.ValueChangedEvent += std::bind(&Console::SetShowDefaultLogs, this, std::placeholders::_1);
	enableInfo.ValueChangedEvent += std::bind(&Console::SetShowInfoLogs, this, std::placeholders::_1);
	enableWarning.ValueChangedEvent += std::bind(&Console::SetShowWarningLogs, this, std::placeholders::_1);
	enableError.ValueChangedEvent += std::bind(&Console::SetShowErrorLogs, this, std::placeholders::_1);

	CreateWidget<Visual::Separator>();

	m_logGroup = &CreateWidget<Layout::Group>();
    m_logGroup->ReverseDrawOrder();

	EDITOR_EVENT(PlayEvent) += std::bind(&Console::ClearOnPlay, this);

	OvDebug::Logger::LogEvent += std::bind(&Console::OnLogIntercepted, this, std::placeholders::_1);
}

这是构造函数。首先会初始化一个面板窗口,之后初始化一些特有的内容,允许有竖直的滑条,设置了一个用于清空内容的按钮,之后初始化了许多checkbox的小部件,绑定了各自对应的功能,同时有一些日志的群组设计。

接下来是一些用在构造函数中的函数,主要是一些部件的功能:

void OvEditor::Panels::Console::OnLogIntercepted(const OvDebug::LogData & p_logData)
{
	auto[logColor, logDate] = GetWidgetSettingsFromLogData(p_logData);

	auto& consoleItem1 = m_logGroup->CreateWidget<Texts::TextColored>(logDate + "\t" + p_logData.message, logColor);

	consoleItem1.enabled = IsAllowedByFilter(p_logData.logLevel);

	m_logTextWidgets[&consoleItem1] = p_logData.logLevel;
}

void OvEditor::Panels::Console::ClearOnPlay()
{
	if (m_clearOnPlay)
		Clear();
}

void OvEditor::Panels::Console::Clear()
{
	m_logTextWidgets.clear();
	m_logGroup->RemoveAllWidgets();
}

void OvEditor::Panels::Console::FilterLogs()
{
	for (const auto&[widget, logLevel] : m_logTextWidgets)
		widget->enabled = IsAllowedByFilter(logLevel);
}

bool OvEditor::Panels::Console::IsAllowedByFilter(OvDebug::ELogLevel p_logLevel)
{
	switch (p_logLevel)
	{
	case OvDebug::ELogLevel::LOG_DEFAULT:	return m_showDefaultLog;
	case OvDebug::ELogLevel::LOG_INFO:		return m_showInfoLog;
	case OvDebug::ELogLevel::LOG_WARNING:	return m_showWarningLog;
	case OvDebug::ELogLevel::LOG_ERROR:		return m_showErrorLog;
	}

	return false;
}

void OvEditor::Panels::Console::SetShowDefaultLogs(bool p_value)
{
	m_showDefaultLog = p_value;
	FilterLogs();
}

void OvEditor::Panels::Console::SetShowInfoLogs(bool p_value)
{
	m_showInfoLog = p_value;
	FilterLogs();
}

void OvEditor::Panels::Console::SetShowWarningLogs(bool p_value)
{
	m_showWarningLog = p_value;
	FilterLogs();
}

void OvEditor::Panels::Console::SetShowErrorLogs(bool p_value)
{
	m_showErrorLog = p_value;
	FilterLogs();
}

OnLogIntercepted首先通过GetWidgetSettingsFromLogData获得日志的信息,初始化一个以存储信息为初值的部件,用IsAllowedByFilter确定是否要启用此部件。

IsAllowedByFilter根据传入的值返回是否使用日志,如果传入的值不符合期望值,就返回false。

ClearOnPlay会在m_clearOnPlay为真时调用clear()函数,也即清屏设定被开启时就清屏。

Clear会调用次级的清空函数,把m_logTextWidgets和m_logGroup都清空。

FilterLogs会用IsAllowedByFilter过滤得到是否启用部件。

SetShowDefaultLogs,SetShowInfoLogs,SetShowWarningLogs和SetShowErrorLogs都是用于给属性赋值,而在赋值后都会调用FilterLogs来更新是否启用的属性。

二、待续

GameView,HardwareInfo和ProjectSettings这三个部分之后再继续讲。

总结

Console相关的都是与控制台有关的函数,没有特殊的地方。
Diana

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值