You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/ErrorReport.cpp

240 lines
6.0 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "ErrorReport.h"
// Editor
#include "ErrorReportDialog.h"
//////////////////////////////////////////////////////////////////////////
QString CErrorRecord::GetErrorText() const
{
QString str = error.trimmed();
const char* sModuleName = "";
// Module name
switch (module)
{
case VALIDATOR_MODULE_UNKNOWN:
sModuleName = "";
break;
case VALIDATOR_MODULE_RENDERER:
sModuleName = "Renderer";
break;
case VALIDATOR_MODULE_3DENGINE:
sModuleName = "Engine";
break;
case VALIDATOR_MODULE_SYSTEM:
sModuleName = "System";
break;
case VALIDATOR_MODULE_AUDIO:
sModuleName = "Audio";
break;
case VALIDATOR_MODULE_MOVIE:
sModuleName = "Movie";
break;
case VALIDATOR_MODULE_EDITOR:
sModuleName = "Editor";
break;
case VALIDATOR_MODULE_NETWORK:
sModuleName = "Network";
break;
case VALIDATOR_MODULE_PHYSICS:
sModuleName = "Physics";
break;
case VALIDATOR_MODULE_FEATURETESTS:
sModuleName = "FeatureTests";
break;
case VALIDATOR_MODULE_SHINE:
sModuleName = "UI";
break;
}
str = QStringLiteral("[%1]\t[%2]\t%3").arg(count, 2).arg(QString(sModuleName).leftJustified(6), error).trimmed();
if (!file.isEmpty())
{
str += QString("\t") + file;
}
else
{
str += QString("\t ");
}
if (pObject)
{
str += QString("\t Object=\"") + pObject->GetName() + "\"";
}
return str;
}
//////////////////////////////////////////////////////////////////////////
// CError Report.
//////////////////////////////////////////////////////////////////////////
CErrorReport::CErrorReport()
{
m_errors.reserve(100);
m_bImmediateMode = true;
m_bShowErrors = true;
m_pObject = nullptr;
m_pParticle = nullptr;
}
//////////////////////////////////////////////////////////////////////////
void CErrorReport::ReportError(CErrorRecord& err)
{
static bool bNoRecurse = false;
if (bNoRecurse)
{
return;
}
bNoRecurse = true;
if (m_bImmediateMode)
{
if (err.module == VALIDATOR_MODULE_EDITOR && err.severity == static_cast<int>(VALIDATOR_ERROR))
{
Warning(err.error.toUtf8().data());
}
else
{
// Show dialog if first character of warning is !.
if (!err.error.isEmpty() && err.error[0] == '!')
{
Warning(err.error.toUtf8().data());
}
else
{
m_errors.push_back(err);
}
}
}
else
{
if (err.pObject == nullptr && m_pObject != nullptr)
{
err.pObject = m_pObject;
}
m_errors.push_back(err);
}
bNoRecurse = false;
}
//////////////////////////////////////////////////////////////////////////
void CErrorReport::Clear()
{
m_errors.clear();
}
//////////////////////////////////////////////////////////////////////////
inline bool SortErrorsByModule(const CErrorRecord& e1, const CErrorRecord& e2)
{
if (e1.module == e2.module)
{
if (e1.error == e2.error)
{
return e1.file < e2.file;
}
else
{
return e1.error < e2.error;
}
}
return e1.module < e2.module;
}
//////////////////////////////////////////////////////////////////////////
void CErrorReport::Display()
{
if (m_errors.empty() || !m_bShowErrors)
{
SetImmediateMode(true);
return;
}
// Sort by module.
std::sort(m_errors.begin(), m_errors.end(), SortErrorsByModule);
std::vector<CErrorRecord> errorList;
errorList.swap(m_errors);
m_errors.reserve(errorList.size());
QString prevName = "";
QString prevFile = "";
for (int i = 0; i < errorList.size(); i++)
{
CErrorRecord& err = errorList[i];
if (err.error != prevName || err.file != prevFile)
{
err.count = 1;
m_errors.push_back(err);
}
else if (!m_errors.empty())
{
m_errors.back().count++;
}
prevName = err.error;
prevFile = err.file;
}
// Log all errors.
CryLogAlways("========================= Errors =========================");
for (int i = 0; i < m_errors.size(); i++)
{
CErrorRecord& err = m_errors[i];
QString str = err.GetErrorText();
CryLogAlways("%3d) %s", i, str.toUtf8().data());
}
CryLogAlways("========================= End Errors =========================");
ICVar* const noErrorReportWindowCVar = gEnv && gEnv->pConsole ? gEnv->pConsole->GetCVar("sys_no_error_report_window") : nullptr;
if (noErrorReportWindowCVar && noErrorReportWindowCVar->GetIVal() == 0)
{
CErrorReportDialog::Open(this);
}
SetImmediateMode(true);
}
//////////////////////////////////////////////////////////////////////////
bool CErrorReport::IsEmpty() const
{
return m_errors.empty();
}
//////////////////////////////////////////////////////////////////////////
CErrorRecord& CErrorReport::GetError(int i)
{
assert(i >= 0 && i < m_errors.size());
return m_errors[i];
};
//////////////////////////////////////////////////////////////////////////
void CErrorReport::SetImmediateMode(bool bEnable)
{
if (bEnable != m_bImmediateMode)
{
Clear();
m_bImmediateMode = bEnable;
}
}
//////////////////////////////////////////////////////////////////////////
void CErrorReport::SetCurrentValidatorObject(CBaseObject* pObject)
{
m_pObject = pObject;
}
//////////////////////////////////////////////////////////////////////////
void CErrorReport::SetCurrentFile(const QString& file)
{
m_currentFilename = file;
}