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, with its data-centric architecture, and Immediate Mode are more suitable than Retained Mode, where UI objects maintain state.
  • 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와 Immediate Mode가 더 적합.
  • 플랫폼 독립성: 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: At Smeltrix, the physical separation of UI code, core business logic, and existing system code is essential.
  • Maintainability: A separated structure provides strong advantages when replacing the GUI layer or testing business logic independently

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

  • 상태 관리: ImGui 는 매 프레임 UI를 생성, 비즈니스 로직과 UI 코드가 뒤섞이면 상태 관리, 이벤트 흐름에 문제 발생 확률이 높아짐.
  • 명확한 책임 분리: Smeltrix에서는 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: If state values frequently appear alongside the UI code in the form of &value, it may be a sign that data ownership is being formed within the UI layer.
  • Clarity through system separation: In a properly separated structure, already-managed data addresses (pointers) are passed directly
  • 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 의 핵심 위젯들은 데이터를 포인터()로 받도록 설계
  • 기술 부채의 징후:&value 형태로 상태값이 UI코드와 같은 위치에 자주 등장한다면, 데이터 소유권이 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
  • If a multilingual system or UI widget label-matching approach designed for traditional UI frameworks is applied as-is, it may not work as intended because ImGui requires the data to be rendered to be provided by developer code on 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 nature, custom ImGui widgets are organized as UI Asset units and bound to the application Context. A separate UI DSL defines both the Context structure and Asset bindings, enabling a DOM-like UI structure that can be composed at runtime.
  • This allows the runtime UI to be composed dynamically by controlling Context configuration and ImGui Asset bindings through external and internal definition languages, without having to write the entire UI structure directly in code.
  • Plays a key role in building a dynamic and flexible system in which data changes are immediately reflected in the UI composition.

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

  • ImGui의 즉시 모드 특성을 활용하여, 커스텀 ImGui 위젯을 UI Asset 단위로 구성하고 앱 Context에 바인딩. 별도의 UI DSL을 통해 Context 구조와 Asset 바인딩을 함께 정의함으로써, 런타임에서 조합 가능한 일종의 DOM-like UI 구조를 구축
  • 이를 통해 UI 구조를 직접 코드로 모두 작성하지 않고, 외부·내부 정의 언어를 통해 Context 구성과 ImGui Asset 바인딩을 제어하여 런타임 UI를 동적으로 조합
  • 데이터의 변화가 즉각적으로 레이아웃에 반영되는 동적이고 유연한 시스템을 구축하는 데 핵심적인 역할

Comments