Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
bb88151
Update ADRs.
JX-Master Aug 25, 2026
191470f
[GameGUI]Add game GUI module.
JX-Master Aug 25, 2026
ecf7b91
Add GameGUI Editor.
JX-Master Aug 27, 2026
d1009c6
Merge remote-tracking branch 'origin/v0.10' into dev-game-gui
JX-Master Aug 27, 2026
f600e77
GameGUI Editor refactor.
JX-Master Aug 27, 2026
a5fa52e
[Runtime]Fix POSIX bug: get_file_attribute did not return E_NOT_FOUND.
JX-Master Aug 27, 2026
557b2b5
[EditorGUI]Add martini icon.
JX-Master Aug 27, 2026
d31a6ea
[EditorGUI]Fix ong bug: combo preview test does not apply input font …
JX-Master Aug 27, 2026
1b00e46
[EditorGUI]Disable navigation when input text is receiving inputs.
JX-Master Aug 27, 2026
01b6cc1
Revert "[EditorGUI]Disable navigation when input text is receiving in…
JX-Master Aug 27, 2026
82a4c93
[EditorGUI]InputText will now consume navigation events instead of ke…
JX-Master Aug 28, 2026
de8b9fd
Fix dockspace bugs
JX-Master Aug 28, 2026
c4fc99e
Refine canvas display and widget tree editing.
JX-Master Aug 28, 2026
7750817
Separate main file to multiple source files.
JX-Master Aug 28, 2026
c85e77d
Merge remote-tracking branch 'origin/v0.10' into dev-game-gui
JX-Master Aug 29, 2026
fcc5549
[GUI]Fix one error that will cause D3D12 crash.
JX-Master Aug 30, 2026
d160ea6
Update GameGUI document model to use multiple asset data units.
JX-Master Aug 30, 2026
169bbd5
Merge remote-tracking branch 'origin/v0.10' into dev-game-gui
JX-Master Aug 30, 2026
8fb3db5
Add MSVC /utf-8 support.
JX-Master Aug 30, 2026
d2b8668
Add support for .NET 10 runtime.
JX-Master Aug 30, 2026
053b885
[LunaBuild] Optimize build speed.
JX-Master Aug 31, 2026
fe4ce68
[LunaBuild] Remove unnecessary `vcvars64.bat` calls on Windows MSVC.
JX-Master Aug 31, 2026
6254f26
[LunaBuild]Fix one bug that causes static linking including dependenc…
JX-Master Aug 31, 2026
5a0547d
[VG]Fix one bug that may cause unexpected batch spliting.
JX-Master Sep 2, 2026
c6a9edc
[GUI] Add paint order ID.
JX-Master Sep 2, 2026
3e691a3
[GUI]Remove old draw path.
JX-Master Sep 3, 2026
12ebea4
[GUI]Chaneg default paint order mode for Flex, Grid, Canvas, Table an…
JX-Master Sep 3, 2026
5491aa0
[GUI]Add element visual effects support.
JX-Master Sep 3, 2026
492841b
[EditorGUITest]Add editing schema.
JX-Master Sep 3, 2026
f64d42e
Add save support for arbitrary directories.
JX-Master Sep 4, 2026
e261fda
Add zip module.
JX-Master Sep 4, 2026
4cfa0b1
Add Pak module.
JX-Master Sep 4, 2026
bc17702
[VFS]Add package file support.
JX-Master Sep 4, 2026
4aa062d
[Asset]Add asset database concept.
JX-Master Sep 4, 2026
4f3922c
Fix Windows compile error
JX-Master Sep 4, 2026
5d6ea75
Add support for palette dragging to add new elements.
JX-Master Sep 10, 2026
8793f82
Add multiple workspace support.
JX-Master Sep 14, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions LunaBuild.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<RollForward>Major</RollForward>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>lunabuild</AssemblyName>
Expand Down
11 changes: 9 additions & 2 deletions LunaSDK-Docs/ADRs/ADR-0003 GUI Visual Editing.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
## Status
Proposed
Retired.

## Last updated
2026/6/9
2026/8/29

## Background
Currently LunaSDK has its own GUI module, but all GUI interfaces are hard-coded in C++. Since now we need to offer our new GUI module to UX designers, we need to offer a new visual GUI design tool and its runtime representation so that UX designers can design GUI interface visually without knowing the real C++ code behind.

## Decision
This proposal was never approved and is now retired and superseded by [[ADR-0015 Introduce GameGUI and GameGUIEditor]]. The former
`GUIAsset`/`GUIEditor` naming and the assumption that asset generation should call `EditorGUI` APIs no longer match
the finalized `GUI`/`EditorGUI` boundary established by [[ADR-0004 Introduce GUI foundation layer]]. The text below
is retained as the historical proposal.

We introduce two new targets in LunaSDK: `GUIAsset` and `GUIEditor`.

### GUIAsset
Expand Down Expand Up @@ -46,4 +51,6 @@ In CLI mode, the editor behaves like a server process, and MCP is the only way t
2. GUI design data and runtime data will not be 100% match at most cases, the runtime data structure version will change rapidly, but the design data is much slower. Use one schema to describe both design data and runtime data will be troublesome.

## Version history
* **2026/8/29** Updated the superseding ADR reference after GameGUI was renumbered to ADR-0015.
* **2026/8/25** Retired this proposal in favor of [[ADR-0015 Introduce GameGUI and GameGUIEditor]], which introduces `GameGUI` and `GameGUIEditor` on the finalized GUI foundation.
* **2026/6/9** Proposed.
157 changes: 100 additions & 57 deletions LunaSDK-Docs/ADRs/ADR-0004 Introduce GUI foundation layer.md

Large diffs are not rendered by default.

445 changes: 445 additions & 0 deletions LunaSDK-Docs/ADRs/ADR-0015 Introduce GameGUI and GameGUIEditor.md

Large diffs are not rendered by default.

303 changes: 303 additions & 0 deletions LunaSDK-Docs/ADRs/ADR-0016 Introduce GUI Paint Order.md

Large diffs are not rendered by default.

86 changes: 86 additions & 0 deletions LunaSDK-Docs/ADRs/ADR-0017 Introduce GUI Element Visual Effects.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
## Status

Approved.

## Last updated

2026/9/3

## Background

GUI elements currently draw through delayed `DrawCallback` functions. Delayed callbacks are necessary when final drawing depends on routed input, post-layout state, custom SDF construction, or other procedural decisions. They are unnecessarily indirect for static visuals such as a panel background, text, an image, or an ordered stack of shadows and strokes whose complete description is already known while the element tree is built.

Attaching a generic draw callback to every potentially styled layout element is not acceptable. It would make non-visual elements pay callback and style-resolution costs, and generic style names could accidentally enable painting on elements that were intended to remain layout-only. Static painting must therefore be explicit and sparse.

ADR-0016 assigns painter ordering and batching through Paint Order IDs. Element Visual Effects must participate in that same ordering model without introducing a second ordering mechanism.

## Decision

GUI Core provides Element Visual Effects as an optional, context-owned paint configuration on every typeless `Element`.

- `ElementVisualEffect` stores one concrete, drawable `DrawCommand` template.
- `ElementVisualConfig` stores ordered `before_children` and `after_children` effect spans.
- `IContext::set_element_visual_config` copies both spans into frame-local storage. Callers may therefore pass temporary arrays and strings owned by the command value are copied with it.
- The configuration is sparse. Elements without a draw callback or Visual Effects do not allocate a paint record and do not perform style lookup.
- Visual Effects are explicit values. GUI Core does not inspect styles or infer effects from an element type. EditorGUI, GameGUI, or business code resolves its own styles and attaches only the effects it intends to draw.
- During draw-command generation, GUI Core directly copies each effect command into the generated command stream, overwrites its element, layer, and Paint Order metadata, and assigns consecutive Paint Order IDs in list order.
- Generation order for one element is:
1. backdrop capture;
2. `before_children` Visual Effects;
3. the `before_children` draw callback;
4. child subtrees;
5. `after_children` Visual Effects;
6. the `after_children` draw callback.
- Each effect reserves one Paint Order ID. Multiple effects may be attached in any order, so two differently colored strokes are represented by two stroke effects with independently configured rectangles, offsets, radii, colors, and widths.
- `rounded_rect_stroke` is added as a drawable GUI primitive. It represents a centered analytic rounded-rectangle stroke and uses `DrawCommand::line_width` as its total width.
- Element Visual Effects accept drawable commands only. Structural commands such as clip pushes and pops and backdrop-capture markers remain procedural generator responsibilities and are rejected by the setter. Backdrop capture continues to use its dedicated attachment API.
- Draw callbacks remain the escape hatch for visuals that depend on `route_input`, require procedural post-layout work, emit structural commands, or need custom Paint Order range management.

The existing sparse element draw-configuration index is generalized internally into a sparse paint record that stores both callback and Visual Effect configuration. This avoids adding a per-element allocation or a separate hot-path lookup.

## Migration policy

This decision does not require every existing callback to migrate.

Implementations are migrated when their final visual description does not depend on `route_input` and can be expressed by the available drawable commands. Interaction-dependent components keep callbacks. Static components that currently require procedural post-layout SDF construction may remain callbacks until an equivalent native effect exists.

When a container uses shared child Paint Order ranges, its complete painted extent includes all of its Visual Effects, including shadow and stroke outsets. The caller remains responsible for choosing shared mode only when sibling painted extents do not overlap.

## Impact

### Positive

- Static elements avoid callback invocation and callback userdata lifetime management.
- Layout-only elements remain paint-free unless a higher-level package explicitly attaches effects.
- Ordered fill, stroke, shadow, text, image, shape, backdrop-blur, and SDF commands use the same Paint Order and batching path as callback output.
- Multiple visual layers are data rather than bespoke callback code.
- GUI Core remains widget-free and does not interpret EditorGUI or GameGUI styles.

### Negative

- `IContext` changes ABI and receives a new interface ID.
- Effect command lists are copied into frame-local storage.
- One effect consumes one Paint Order ID even when the command later produces no visible pixels.
- Complex procedural visuals still need callbacks, so both mechanisms remain part of the GUI API.

## Alternatives considered

### Give every layout element a style-aware callback

Rejected because it adds work to non-visual elements and allows broad style definitions to cause accidental rendering.

### Reintroduce unrestricted `record_draw`

Rejected because a general recording API obscures the distinction between static element visuals and procedural drawing, and structural commands make ownership and ordering across children ambiguous. The Visual Effects API deliberately records only explicit drawable commands in two well-defined element phases.

### Translate effects in an element callback

Rejected because it retains callback overhead and callback lifetime concerns. GUI Core already owns command generation and can translate static effects directly.

### Reorder callback output by geometric overlap analysis

Rejected as the primary solution because it is more expensive and less predictable than explicit Paint Order allocation. Geometry-based optimization may still be explored independently.

## Version history

* **2026/9/3** Proposed and approved the sparse GUI Core Element Visual Effects model, static-only migration policy, and analytic rounded-rectangle stroke primitive.
56 changes: 56 additions & 0 deletions LunaSDK-Docs/ADRs/ADR-0018 Introduce a standalone Zip module.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
## Status
Proposed.

## Last updated
2026/9/4

## Background
LunaSDK needs ZIP archive support both for ordinary application code and as the foundation of a future Pak module. ZIP storage must remain independent of VFS mounting and Asset metadata. Reimplementing ZIP64, Deflate, archive editing, and format validation would duplicate existing library functionality.

## Decision
Introduce a `Zip` module, depending on `Runtime` and a pinned libzip dependency. Download libzip 1.11.4 and zlib 1.3.2 through `setup.sh` / `setup.bat` into the ignored `SDKs` directory, then compile them locally through LunaBuild. Third-party library sources must not be checked into the LunaSDK repository. The repository contains only download recipes, configuration templates, and build integration code. Keep third-party declarations out of the module's public API.

Setup verifies the pinned source archives with SHA-256 and prepares the libzip configuration headers and generated error table inside `SDKs`. It checks these source SDKs even when the platform SDK bundle is already installed. Normal builds do not download dependencies or require a system libzip, zlib, or CMake installation.

The module operates on ZIP archives and entries. It provides archive creation, opening, entry enumeration and lookup, sequential entry streams, adding and replacing entries from caller-provided streams, explicit directories, renaming, deleting, compression selection, saving, and discarding changes. Store and Deflate are supported initially; encrypted entry decoding and encoding are not enabled in this phase. Unsupported methods produce explicit errors.

### Streams and ownership
Archive input uses `ISeekableStream`. Opening reads archive metadata on demand rather than loading the entire archive into memory. Added entry sources are seekable streams and are retained until the archive releases them. Their data must remain unchanged until save or discard. This permits large inputs without unconditional whole-file buffering.

Entry readers provide `IStream` semantics. They do not promise seeking in compressed entries. An archive owns its libzip handle and readers retain their archive. An archive cannot be edited, saved, or discarded while a reader is open. Calls involving the same archive, its readers, or shared source streams must be externally serialized.

ZIP entry indices are session-local and must not be treated as persistent identifiers. Entries can be deleted without renumbering the remaining session entries; enumeration skips deleted entries.

### Editing and saving
Mutations are staged in the archive session. Neither mutation nor object destruction implicitly saves. Releasing an unsaved archive discards its changes.

Stream-based saving writes a complete archive to a distinct caller-owned output stream. It must not alias the archive input or any retained entry source, including aliases through separate handles. The output must support writing, seeking and resizing, and its previous contents are replaced. The original inputs are never overwritten by the module.

A failed save leaves the archive session available for retry or discard; the destination may contain incomplete data. A successful save consumes the session, as libzip closes its archive when committing. The caller can reopen the destination to continue editing. Empty archives are preserved as valid ZIP files.

This output-stream contract deliberately does not claim atomic replacement of a filesystem path or physical-storage durability. A caller that needs those guarantees supplies a temporary destination and publishes it using its storage-specific replacement and synchronization protocol. `ISeekableStream` does not expose a durable synchronization operation, and Runtime's current `IFile::flush` cannot report synchronization errors.

### Layering
`Zip` exposes archive-level edits such as replacing an entry with a data source. A future `Pak` module supplies directory-tree policy, file-style random writes, caching, stable logical file identities, and repeated flush sessions using these operations. VFS supplies its Pak driver. Asset stores its database as an ordinary VFS file. None of those higher-level features is part of this change.

The ZIP format is kept standard, including ZIP64 when required. File naming, directory-tree validation, and extraction policy must not be confused with archive parsing: this module does not extract entry paths onto a filesystem.

## Impact
Applications can read and write ordinary ZIP files without depending on Pak, VFS, or Asset. Store and Deflate archives remain interoperable with standard ZIP tools. Download recipes record third-party source versions and archive hashes; downloaded SDKs retain the upstream licenses. Optional codecs and AES backends are disabled to keep the initial dependency set bounded. The wrapper rejects encrypted data operations, including legacy ZIP encryption compiled into libzip's core.

Both third-party libraries are static targets even in a shared-module build. LunaBuild must honor an explicit `StaticLibrary` target kind when choosing output names, archive commands, Windows import-library outputs, and runtime staging. Normal Luna `SharedLibrary` targets continue to follow the global linkage option.

Users of stream-based save must provide a separate output and explicitly handle publication. Compressed entry readers are sequential. These boundaries avoid promising filesystem transactions and random-access decoding that neither a generic stream nor the selected library provides automatically.

## Alternatives considered
### Implement a private container immediately
A private container could optimize block-level random access and incremental commits, but those requirements are not part of the first Zip module. It would also lose direct interoperability with ordinary ZIP tools.

### Expose libzip directly
Exposing libzip types would couple application code and future Pak code to its allocation, error, and handle-lifetime conventions. A Luna interface keeps those details private while retaining archive-level capabilities.

### Hide ZIP support inside Pak or VFS
This would prevent business code from using ordinary ZIP archives independently and mix archive algorithms with filesystem policy.

## Version history
* **2026/9/4** Proposed and implemented for review. Introduce Zip first; future Pak depends on Zip, and VFS integrates Pak through a driver.
Loading
Loading