| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- // Copyright (C) 2009-2023, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Core/DeveloperConsole.h>
- namespace anki {
- DeveloperConsole::~DeveloperConsole()
- {
- Logger::getSingleton().removeMessageHandler(this, loggerCallback);
- while(!m_logItems.isEmpty())
- {
- LogItem* item = &m_logItems.getFront();
- m_logItems.popFront();
- deleteInstance(UiMemoryPool::getSingleton(), item);
- }
- }
- Error DeveloperConsole::init()
- {
- zeroMemory(m_inputText);
- ANKI_CHECK(UiManager::getSingleton().newInstance(m_font, "EngineAssets/UbuntuMonoRegular.ttf", Array<U32, 1>{16}));
- // Add a new callback to the logger
- Logger::getSingleton().addMessageHandler(this, loggerCallback);
- return Error::kNone;
- }
- void DeveloperConsole::build(CanvasPtr ctx)
- {
- const Vec4 oldWindowColor = ImGui::GetStyle().Colors[ImGuiCol_WindowBg];
- ImGui::GetStyle().Colors[ImGuiCol_WindowBg].w = 0.3f;
- ctx->pushFont(m_font, 16);
- ImGui::Begin("Console", nullptr, ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoTitleBar);
- ImGui::SetWindowPos(Vec2(0.0f, 0.0f));
- ImGui::SetWindowSize(Vec2(F32(ctx->getWidth()), F32(ctx->getHeight()) * (2.0f / 3.0f)));
- // Push the items
- const F32 footerHeightToPreserve = ImGui::GetStyle().ItemSpacing.y + ImGui::GetFrameHeightWithSpacing();
- ImGui::BeginChild("ScrollingRegion", Vec2(0, -footerHeightToPreserve), false,
- ImGuiWindowFlags_HorizontalScrollbar); // Leave room for 1 separator + 1 InputText
- ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, Vec2(4.0f, 1.0f)); // Tighten spacing
- for(const LogItem& item : m_logItems)
- {
- switch(item.m_type)
- {
- case LoggerMessageType::kNormal:
- ImGui::PushStyleColor(ImGuiCol_Text, Vec4(0.0f, 1.0f, 0.0f, 1.0f));
- break;
- case LoggerMessageType::kError:
- case LoggerMessageType::kFatal:
- ImGui::PushStyleColor(ImGuiCol_Text, Vec4(1.0f, 0.0f, 0.0f, 1.0f));
- break;
- case LoggerMessageType::kWarning:
- ImGui::PushStyleColor(ImGuiCol_Text, Vec4(0.9f, 0.6f, 0.14f, 1.0f));
- break;
- default:
- ANKI_ASSERT(0);
- }
- constexpr Array<const Char*, U(LoggerMessageType::kCount)> kMsgText = {"I", "E", "W", "F"};
- ImGui::TextWrapped("[%s][%s] %s [%s:%d][%s][%s]", kMsgText[item.m_type], (item.m_subsystem) ? item.m_subsystem : "N/A ", item.m_msg.cstr(),
- item.m_file, item.m_line, item.m_func, item.m_threadName.cstr());
- ImGui::PopStyleColor();
- }
- const U32 timestamp = m_logItemsTimestamp.getNonAtomically();
- const Bool scrollToLast = m_logItemsTimestampConsumed < timestamp;
- if(scrollToLast)
- {
- ImGui::SetScrollHereY(1.0f);
- ++m_logItemsTimestampConsumed;
- }
- ImGui::PopStyleVar();
- ImGui::EndChild();
- // Commands
- ImGui::Separator();
- ImGui::PushItemWidth(-1.0f); // Use the whole size
- if(ImGui::InputText("##noname", &m_inputText[0], m_inputText.getSizeInBytes(), ImGuiInputTextFlags_EnterReturnsTrue, nullptr, nullptr))
- {
- const Error err = m_scriptEnv.evalString(&m_inputText[0]);
- if(!err)
- {
- ANKI_CORE_LOGI("Script ran without errors");
- }
- m_inputText[0] = '\0';
- }
- ImGui::PopItemWidth();
- ImGui::SetKeyboardFocusHere(-1); // Auto focus previous widget
- ImGui::End();
- ImGui::GetStyle().Colors[ImGuiCol_WindowBg] = oldWindowColor;
- ctx->popFont();
- }
- void DeveloperConsole::newLogItem(const LoggerMessageInfo& inf)
- {
- LogItem* newLogItem;
- // Pop first
- if(m_logItemCount + 1 > kMaxLogItems)
- {
- LogItem* first = &m_logItems.getFront();
- m_logItems.popFront();
- first->m_msg.destroy();
- first->m_threadName.destroy();
- // Re-use the log item
- newLogItem = first;
- --m_logItemCount;
- }
- else
- {
- newLogItem = newInstance<LogItem>(UiMemoryPool::getSingleton());
- }
- // Create the new item
- newLogItem->m_file = inf.m_file;
- newLogItem->m_func = inf.m_func;
- newLogItem->m_subsystem = inf.m_subsystem;
- newLogItem->m_threadName = inf.m_threadName;
- newLogItem->m_msg = inf.m_msg;
- newLogItem->m_line = inf.m_line;
- newLogItem->m_type = inf.m_type;
- // Push it back
- m_logItems.pushBack(newLogItem);
- ++m_logItemCount;
- m_logItemsTimestamp.fetchAdd(1);
- }
- } // end namespace anki
|