Reflections on Dear ImGui

Languages: [EN] English | [KO] 한국어

Reflections on Dear ImGui
Dear ImGui 에 대한 고찰

Overview

소개

Dear ImGui is a personal reflection on ImGui, written based on my experience.

ImGui를 사용하면서 얻은 경험을 바탕으로 쓴 개인적 고찰.

Background for Choosing a GUI Library

  • Architectural Separation: Smeltrix doesn't fit well with Retained Mode, which mixes data flow and UI rendering.
  • Platform Independence: Wary of Smeltrix's core logic being dependent on specific GUI frameworks (WinUI 3, QT, etc.).
  • Selection: Found an intuitive code style in Dear ImGui's Immediate Mode that I felt while working with NWG (Native Windows GUI) in Rust in the past.

GUI 라이브러리 선정 배경

  • 아키텍처 분리: 데이터의 흐름과 UI 렌더링이 섞이는 Retained Mode 와 Smeltrix 가 맞지 않음.
  • 플랫폼 독립성: Smeltrix 의 핵심 로직이 특정 GUI 프레임워크(WinUI 3,QT 등)에 종속되는 것을 경계.
  • 선택: 과거 Rust 에서 NWG(Native Windows GUI)를 다루며 느꼈던 직관적인 코드 방식을 Dear ImGui의 Immediate Mode 에서 발견.

Understanding the Concept of Immediate Mode

  • Simple analogy explanation: "DB + PHP + HTML" relationship
  • ImGui uses Immediate Mode, where the UI is constructed and rendered every frame
  • DB (C++ variables): The source of truth where actual data is stored, existing independently of the UI
  • PHP (ImGui logic): Reads data from the DB every request (frame) and determines how it should be presented
  • HTML (rendered output): The final UI result displayed to the user
  • Traditional GUI frameworks tend to store state within the UI itself
  • ImGui renders the UI by reading the current memory state every frame, similar to how a web server generates pages
  • Data ownership remains in the business logic rather than the UI, resulting in a clearer code flow

즉시 모드의 개념 이해

  • 간단 비유 설명: "DB + PHP + HTML"의 관계
  • ImGui는 매 프레임마다 UI를 즉시 구성하고 렌더링하는 즉시 모드(Immediate Mode)
  • DB (C++ 변수): 실제 데이터가 저장된 원천이며, UI와 별개로 존재.
  • PHP (ImGui 로직): 매 요청(프레임)마다 DB에서 데이터를 읽어와 어떻게 보여줄지 결정
  • HTML (렌더링 결과): 사용자 화면에 최종적으로 뿌려지는 UI 결과
  • 기존 GUI가 UI 자체에 값을 저장하려 했다면
  • ImGui는 웹 서버가 페이지를 생성하듯 매 순간 메모리의 상태를 읽어 화면 출력
  • 데이터의 소유권이 UI가 아닌 비즈니스 로직에 머물게 하여 코드의 흐름이 명확

Data-Centric Design for Immediate Mode

  • State Management: ImGui generates a UI for each frame, so if business logic and UI code are mixed, there is a high probability of problems with state management and event flow.
  • Clear separation of responsibilities: UI code, core business logic, and existing system code must be physically separated
  • Maintainability: A separated structure provides strong advantages when replacing the GUI layer or testing business logic independently

즉시 모드를 위한 데이터 중심 설계

  • 상태 관리: ImGui 는 매 프레임 UI를 생성, 비즈니스 로직과 UI 코드가 뒤섞이면 상태 관리, 이벤트 흐름에 문제 발생 확률이 높아짐.
  • 명확한 책임 분리: UI 코드와 핵심 비즈니스 로직, 기존 시스템 코드를 물리적 분리가 필수.
  • 유지보수 편의성: 분리된 구조는 추후 GUI 레이어를 교체하거나 비즈니스 로직만 별도로 테스트할 때 강력한 이점을 제공.

The Risk of Technical Debt

  • The moment ImGui code and logic code become coupled, the difficulty of debugging and unit testing increases sharply
  • When logic and UI code are mixed, technical debt quickly accumulates and becomes difficult to manage during maintenance and feature expansion
  • In the long term, this increases project complexity and compounds technical debt
  • Maintaining clear code separation principles from the initial design stage helps extend the lifespan of the project

기술 부채의 위험성

  • ImGui, 로직 코드가 결합되는 순간, 디버깅과 단위 테스트의 난이도가 급격히 상승
  • 로직과 UI 코드가 뒤섞이게 되면 유지보수와 기능 확장 시 감당하기 어려운 기술부채가 쌓임
  • 장기적인 관점에서 이는 프로젝트의 복잡도를 높이고 기술 부채를 누적시키는 결과를 초래
  • 따라서 초기 설계 단계부터 명확한 코드 분리 원칙을 고수하는 것이 프로젝트의 생명력을 연장

Intent Embedded in ImGui’s API: Enforced Use of Pointers

  • ImGui::Combo(const char *label, int *current_item, const char *const *items...)
  • Core ImGui widgets are designed to receive data via pointers
  • A sign of technical debt: When UI and logic are mixed, patterns like converting ordinary variables to addresses at the call site (&value) frequently appear, indicating a UI-driven architecture
  • Clarity through system separation: In a properly separated structure, already-managed data addresses (pointers) are passed directly
  • The designer’s intent: This design is not meant to save developers from repeatedly typing & across tens of thousands of lines of code
  • It embeds the architectural principle that "data must be managed outside the UI" directly into the interface itself

ImGui 의 코드 속 의도: 포인터 강제

  • ImGui::Combo(const char *label, int *current_item, const char *const *items...)
  • ImGui 의 핵심 위젯들은 데이터를 포인터()로 받도록 설계
  • 기술 부채의 징후: 만약 UI와 로직이 뒤섞여 있다면, 일반 변수를 호출 시점에 주소로 변환하는 &value 형태가 자주 등장, 이는 설계가 UI에 종속되어 있음을 뜻함
  • 시스템 분리의 명확성: 반면, UI와 비즈니스 로직이 물리적으로 분리된 구조에서는 이미 관리되고 있는 데이터 주소(Pointer)를 그대로 넘김
  • 설계자의 의도: 수만 줄의 시스템 코드를 작성할 때 일일이 &를 붙이는 수고를 덜어주려는 것이 아님.
  • "데이터는 UI 밖에서 관리되어야 한다"는 (포인터로 지정만 하라는) 아키텍처 원칙을 인터페이스 자체에 박아넣은 것.

Practical Perspective

  • Most projects using ImGui apply a UI layer on top of an already established system
  • Without clear architectural separation at the start of development, the likelihood of encountering major difficulties is very high
  • ImGui code examples may appear simple, but approaching them with traditional GUI assumptions leads to increased technical debt for short-term UI solutions
  • Well-designed projects consistently maintain a clear boundary between logic and UI
  • Implementing traditional GUI-style localization systems or widget-label matching within the ImGui layer may not work as intended, since the UI is reinitialized every frame
  • ImGui is a bloat-free toolkit rather than a framework; therefore, one must avoid imposing legacy framework paradigms onto its architecture

실무 관점

  • ImGui 를 사용하는 대부분의 프로젝트는 "이미" 구축된 시스템 위에 UI 레이어를 덧입히는 형태
  • 개발 시작시 명확한 설계 분리가 없다면 난관에 봉착할 확률이 매우 높음
  • ImGui 코드 예제를 보면 매우 간단해 보이지만, 기존 관념을 가지고 시작하게 된다면, 당장의 UI 문제 해결을 위한 기술 부채가 증가
  • 실제로 잘 설계된 프로젝트 일수록 로직과 UI의 경계가 명확
  • 기존 UI프레임워크 스타일의 다국어 시스템, 각종 UI위젯 레이블 매치 등 ImGui 에서 수행할 경우 구조상 매 프레임 초기화 되기 때문에 의도대로 작동하지 않을 수 있음
  • ImGui 는 프레임워크가 아닌 Bloat-free 툴킷이기에 다른 관념을 가져와서는 안됨

Maximizing the Benefits: Realizing a Runtime DOM Structure

  • By leveraging ImGui’s Immediate Mode characteristics and combining them with function pointers + App Context, the runtime system can be structured similarly to a DOM (Document Object Model)
  • This enables real-time composition of ImGui code at runtime using internal and external configuration or markup-like definitions
  • The Project, SMELTRIX, UI is designed and implemented with this structure in mind
  • This approach plays a key role in building dynamic and flexible systems where data changes are immediately reflected in the layout

장점 극대화 팁: 런타임 DOM 구조의 실현

  • ImGui 의 즉시 모드 특성을 활용하면, 함수 포인터+앱컨텍스트 와 결합하여 시스템 런타임을 일종의 DOM(Document Object Model) 구조로 구축 가능
  • 이를 통해 외부+내부를 통한 설정+마크업 언어를 통한 ImGui 코드를 런타임 위에서 실시간 조합이 가능
  • 프로젝트 SMELTRIX의 UI가 이러한 구조로 설계 및 제작
  • 데이터의 변화가 즉각적으로 레이아웃에 반영되는 동적이고 유연한 시스템을 구축하는 데 핵심적인 역할

Comments