[pull] master from GaijinEntertainment:master#985
Merged
Conversation
…ommands C++ encoder in modules/dasStbImage/src/apng_write_impl.h reuses stb's internal CRC32 + zlib_compress, runs encode + file I/O on a worker thread with a bounded queue (drop-oldest on overflow). Backpatches acTL.num_frames on close as a single 12-byte write (body + recomputed CRC). Exposes stbi_apng_begin/frame/end/dropped to daslang. Live commands live next to screenshot in opengl_live.das: record_start (file/fps/max_seconds), record_stop, record_status. Capture runs from [before_update] at the fps throttle with auto-stop on max_seconds. dastest covers chunk parse + acTL backpatch, frame 0 decode via stbi_load (default-image fallback), RGB+RGBA, error paths, overflow drops, parallel writers — 12 cases green. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
dasGLFW.main.cpp gains a multi-listener callback chain for cursor pos, mouse button, and scroll. The dispatcher captures whatever prior C callback was installed (ImGui_ImplGlfw, app-level callbacks) and replays it as the chain's "prev", so synth events posted via DasGlfw_Post* / Dispatch* reach every real listener too. New publics: glfw_chain_add_cursor_pos / mouse_button / scroll, glfw_chain_clear, glfw_post_cursor_pos / mouse_button / scroll, glfw_dispatch_cursor_pos. glfw_live grows a synthetic mouse driver with live commands: mouse_pos, mouse_click, mouse_scroll, mouse_move_to, mouse_play, mouse_stop, mouse_status. Per-frame [before_update] tick lerps between move waypoints and posts one cursor event per frame, so ImGui and overlays see smooth motion. get_synth_cursor() exposes (active,x,y) for overlays to draw against the synth position instead of GetMousePos() -- ImGui_ImplGlfw's per-frame poll would otherwise overwrite io.MousePos with the real OS cursor on focused windows. The OS cursor is never warped: it lives outside the GL back buffer (the window manager paints it at display time), so warping has no effect on glReadPixels-driven APNG recordings. daslib/json_boost.das: PERF018 fix -- from_JV array form now iterates the array directly instead of via range(length). docs: register stbi_apng_* in das2rst stbimage groups + fill the four handmade stubs the apng commit left behind; register the synthesized finalize() in strudel_scheduler's lifecycle group; document the new glfw_live mouse commands in daslang_live.rst + skills/daslang_live.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#1 DasGlfw_ChainClear restores prev callbacks before erasing the map entry. Without this, the dispatcher stays installed but early-returns on every real event, silently disconnecting ImGui_ImplGlfw and any other prior listener. #2 ApngWriter::enqueue validates stride_bytes >= row_bytes and rejects null pixels. Negative or too-small stride was being cast to size_t and underflowing into OOB reads. #3 stbi_apng_frame docstring now matches the implementation: positive stride only, always returns 1 on success, drops oldest on overflow (visible via stbi_apng_dropped). The prior copy claimed negative stride and a 0-return-on-full contract, neither of which exists. #4 mouse_click validates `action` and returns a structured error on anything other than "press" / "release". Typos like "pressed" no longer silently flip to release. #5 mouse_play sorts the wire timeline by t_ms before building the internal queue, so out-of-order input no longer drops earlier events. Extracted MouseEventWire + sort_play_events into a small standalone module (live/mouse_events) so the regression test under tests/dasglfw/test_mouse_play_sort.das can require only the algorithm, not glfw_live's full GLFW/OpenGL chain. The module is marked options no_aot to keep the test interpreter-friendly under test_aot. tests/aot/CMakeLists.txt registers tests/dasglfw/ alongside the other test directories. #6 record_start clamps `fps` to >= 1.0 and stores/reports the effective value, instead of accepting a sub-1 fps in status output while running the scheduler at the clamped rate. #7 record_tick resyncs next_capture_t to `now + frame_interval_s` after a stall instead of catch-up bursting. delay_ms now reflects the actual elapsed time between captures so playback timing matches the real spacing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
CI: revert the mouse_events module extraction from round 1. daspkg's
exe build treats live/glfw_live as a shared module
(dasModuleGlfw.shared_module) and rejected the require of a
native-path-only mouse_events ("error[20115]: Shared module glfw_live
has incorrect dependency type. Can't require mouse_events because its
not shared"). Put MouseEventWire + sort_play_events back inline in
glfw_live.das; drop the mouse_events.das file, the .das_module
register_native_path, and the tests/dasglfw entries in
tests/aot/CMakeLists.txt. The regression test under tests/dasglfw/
is now self-contained -- it mirrors the wire-event shape with a local
struct and verifies the same sort + less-than comparator lands
t_ms-ascending, so no glfw_live require chain is needed.
#8 mouse_play button branch validates action in {"press", "release"}
the same way mouse_click does. Invalid strings return a structured
error instead of silently flipping to release.
#9 dropped the "Stable-sort" claim from sort_play_events' docstring
and from the test -- daslang's sort is qsort, not stable. The test
now uses distinct t_ms values (no ties), asserting only the
non-decreasing-t_ms invariant mouse_play depends on.
#10 record_tick now deletes the per-frame pixels buffer at end of
function. Local var array doesn't finalize on scope exit, so the
heap was growing by width*height*4 bytes per captured frame.
#11 stbi_apng_frame docstring now states the writer expects bottom-up
row order (glReadPixels output) and flips internally, so callers
don't double-flip.
#12 write_chunk + the acTL backpatch fold the chunk type + body into
an incremental byte-table CRC32 instead of memcpy'ing the whole body
into a temporary vector. Removes the per-chunk peak-memory doubling.
12/12 APNG tests pass (CRC sanity verified through chunk-parse round
trip).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#13 ApngWriter::end now rejects zero-frame closes. Previously it would emit IHDR/acTL/IEND with no IDAT/fdAT -- not a valid PNG/APNG. Stores filepath in begin(), and on end() with frames_written == 0 closes the file, calls remove() on the partial artifact, and returns failure so the caller doesn't ship a corrupt file. #14/#16/#17 test_apng.das: every stbi_load result is now followed by a success(loaded != null, ...) assertion, and the dimension checks (equal x/y) only fire when the load succeeded. Locals x/y/comp are initialized to 0 so a load failure doesn't read uninitialized memory in subsequent (skipped) checks. Applied to test_apng_basic and test_apng_double_writers' l1/l2 paths. #15 test_apng_drop_accounting (renamed from test_apng_drop_on_overflow) replaces the tautological dropped_before_end >= 0 assertion with the real submitted = emitted + dropped invariant: dropped_before_end + chunks.n_fctl == 40. drop_count is only mutated by enqueue (finalized once all 40 submits complete), and end() drains the worker queue, so the invariant is race-free. Works whether the worker was fast (few drops, lots of fcTL) or slow (lots of drops, few fcTL). #18 stbi_apng_frame docstring now notes that 0 can also indicate the writer entered an internal error state from a prior async I/O or encode failure, and that callers should stop and call stbi_apng_end in that case. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#19 ApngWriter::enqueue guards size_t overflow on row_bytes * h. Realistic 32-bit hit (windows-32 CI lane); on 64-bit only kicks in for gigapixel frames. One-line `if (h && row_bytes > SIZE_MAX/h) return false;` before the resize. #20 ApngWriter::emit_frame guards the deflate-input multiply ((row_bytes + 1) * h) and the implicit narrowing to int when calling stbi_zlib_compress (which takes int len). Same 32-bit motivation; the INT_MAX cap also matters when zlib API only sees a 31-bit length. Pulled in <climits> for INT_MAX. #21 daslang_live.rst regression -- the apng commit had updated the live/opengl_live row to "OpenGL screenshot + APNG video recording commands.", but the round-1 synth-mouse commit silently clobbered it back to "OpenGL screenshot command." during the stash juggling for the Sphinx-baseline test. Restored. Copilot caught it. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…events dasGLFW chain dispatcher + synth input; glfw_live mouse driver; APNG recorder
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
See Commits and Changes for more details.
Created by
pull[bot] (v2.0.0-alpha.4)
Can you help keep this open source service alive? 💖 Please sponsor : )