π₯οΈ Embedded UI β Dear ImGui
Fase: 6 β O Olimpo
Namespace: Caffeine::Editor
Status: π
Planejado
RFs: RF6.1, RF6.2, RF6.6
VisΓ£o Geral
IntegraΓ§Γ£o de Dear ImGui para a interface do Caffeine Studio IDE. ImGui Γ© uma biblioteca de UI em modo imediato (immediate mode) β cada frame redesenha todos os widgets. Ideal para ferramentas de desenvolvimento.
DistinΓ§Γ£o da Fase 4:
- UI System β UI retida para jogos (HUD, menus, HealthBar)
- Embedded ImGui β UI imediata para ferramentas de desenvolvimento (editor, profiler, console)
API Planejada
namespace Caffeine::Editor {
// ============================================================================
// @brief IntegraΓ§Γ£o ImGui com SDL3 + RHI da Caffeine.
//
// Inicializa ImGui com:
// - Backend SDL3 (eventos de mouse/teclado)
// - Backend SDL_GPU (renderizaΓ§Γ£o)
//
// Lifecycle:
// 1. init(window, device)
// 2. Per frame: beginFrame() β ImGui widgets β endFrame(cmd)
// 3. shutdown()
// ============================================================================
class ImGuiIntegration {
public:
bool init(SDL_Window* window, RHI::RenderDevice* device);
void shutdown();
void beginFrame(); // chama ImGui::NewFrame()
void endFrame(RHI::CommandBuffer* cmd); // chama ImGui::Render() + draw data
// Passa evento SDL para ImGui (chame antes de processar input do jogo)
bool processEvent(const SDL_Event& event);
// Verifica se ImGui estΓ‘ capturando input (nΓ£o repassar ao jogo)
bool wantsKeyboard() const;
bool wantsMouse() const;
};
// ============================================================================
// @brief Janela de profiler β visualiza dados do Profiler da Fase 2.
// ============================================================================
class ProfilerWindow {
public:
void render(const Debug::Profiler& profiler);
private:
bool m_open = true;
bool m_paused = false;
// histograma de 120 frames
std::array<f32, 120> m_frameTimes;
u32 m_frameIdx = 0;
};
// ============================================================================
// @brief Console window β exibe logs e aceita comandos.
// ============================================================================
class ConsoleWindow {
public:
void render();
void addLog(Debug::LogLevel level, const char* category,
const char* message);
private:
struct LogEntry {
Debug::LogLevel level;
FixedString<32> category;
FixedString<256> message;
};
std::vector<LogEntry> m_entries;
char m_inputBuf[256] = {};
bool m_autoScroll = true;
bool m_open = true;
Debug::LogLevel m_filterLevel = Debug::LogLevel::Trace;
};
// ============================================================================
// @brief Stats overlay β frame time, FPS, memory.
// ============================================================================
class StatsOverlay {
public:
void render(const GameLoop::FrameStats& stats,
const AssetManager::CacheStats& cache);
};
} // namespace Caffeine::Editor
Janelas do Editor
ProfilerWindow
ββββββββββββββββββββββββββββββββββββββββββββ
β π¬ Profiler [Pause] [X] β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Frame: 16.7ms | FPS: 60 β
β ββββββββββββββββββββββββ (frame graph) β
β β
β Scope avg max β
β ECS::PhysicsSystem 2.1ms 4.3ms β
β BatchRenderer::flush 0.8ms 1.2ms β
β AnimationSystem 0.3ms 0.6ms β
β AudioSystem::update 0.1ms 0.2ms β
ββββββββββββββββββββββββββββββββββββββββββββ
ConsoleWindow
ββββββββββββββββββββββββββββββββββββββββββββ
β π¬ Console [X] β
ββββββββββββββββββββββββββββββββββββββββββββ€
β Filter: [All βΎ] [β Auto-scroll] β
ββββββββββββββββββββββββββββββββββββββββββββ€
β [INFO] AssetManager Loaded hero.caf β
β [WARN] Physics Overlap detected β
β [INFO] Audio Playing bgm.caf β
β [INFO] ECS Created 50 entit. β
ββββββββββββββββββββββββββββββββββββββββββββ€
β > _ β
ββββββββββββββββββββββββββββββββββββββββββββ
IntegraΓ§Γ£o no Game Loop
// ββ Init ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
#if CF_EDITOR_MODE
Caffeine::Editor::ImGuiIntegration imgui;
imgui.init(window, &device);
Caffeine::Editor::ProfilerWindow profilerWindow;
Caffeine::Editor::ConsoleWindow consoleWindow;
// Hook no LogSystem para exibir no console:
Debug::LogSystem::instance().addSink([&](LogLevel lvl, const char* cat,
const char* msg) {
consoleWindow.addLog(lvl, cat, msg);
});
#endif
// ββ Por frame βββββββββββββββββββββββββββββββββββββββββββββββββ
#if CF_EDITOR_MODE
imgui.beginFrame();
profilerWindow.render(Debug::Profiler::instance());
consoleWindow.render();
sceneEditor.render(world, camera); // Fase 6.3
imgui.endFrame(cmd);
#endif
Hot-Reload Runtime (RF6.6)
FileWatcher (jΓ‘ no AssetManager::pollFileChanges())
β
βΌ
Arquivo modificado em disco
β
βββ textura (.png) β re-encode β upload GPU β todos os handles atualizados
βββ shader (.hlsl/.glsl) β recompile β novo Pipeline β substituΓdo
βββ script (.lua) β reload VM β funΓ§Γ΅es atualizadas
CritΓ©rio de AceitaΓ§Γ£o
DependΓͺncias
ReferΓͺncias
π₯οΈ Embedded UI β Dear ImGui
VisΓ£o Geral
IntegraΓ§Γ£o de Dear ImGui para a interface do Caffeine Studio IDE. ImGui Γ© uma biblioteca de UI em modo imediato (immediate mode) β cada frame redesenha todos os widgets. Ideal para ferramentas de desenvolvimento.
DistinΓ§Γ£o da Fase 4:
API Planejada
Janelas do Editor
ProfilerWindow
ConsoleWindow
IntegraΓ§Γ£o no Game Loop
Hot-Reload Runtime (RF6.6)
CritΓ©rio de AceitaΓ§Γ£o
DependΓͺncias
ReferΓͺncias
docs/fase2/debug.mdβ Profiler + LogSystem