2 Commits
Author SHA1 Message Date
西风逍遥游 bed4ce5cd2 fix(graphics): rebuild Vulkan surface/swapchain and ImGui context when native window is recreated
Repeatedly closing/reopening a window and re-initializing the render system
(single-process unit_test run) crashed because:

- The Vulkan surface/swapchain stayed bound to the destroyed native window.
  SDL can hand back the same pointer for a recreated window, so pointer
  identity could not detect the stale surface; present() then hit
  getSurfaceCapabilitiesKHR: ErrorUnknown.
- The ImGui context and Vulkan present-overlay survived the window, so a
  later present() drew into an unrelated window via the stale overlay.
- headlessImGuiWalk destroyed the ImGui context while the UI backend's real
  context was still current (CreateContext only auto-switches current when
  GImGui is NULL), leaving a dangling context for later present() calls.

Fix:
- Window::close() calls Graphics::onNativeWindowDestroyed(); the Vulkan
  backend drops the surface/swapchain and fires registered window-destroyed
  callbacks (UI backend tears down its ImGui context here).
- initWithWindow() rebuilds the swapchain synchronously and no longer relies
  on pointer identity to detect a stale surface.
- ImGuiBackend owns its ImGui context explicitly and shuts it down via the
  window-destroyed hook; shutdown() switches to its own context first.
- headlessImGuiWalk switches to and from its private ImGui context.

Test-only fixes exposed once the suite can run to completion:
- animation_skinned: Animation::create() returns the process-wide singleton;
  do not wrap it in unique_ptr (delete left a dangling ModuleManager pointer).
- particles attach tests: emitters live in a process-wide ECS; detach (and
  clear skin sources) before local skeletons are destroyed.
2026-08-15 00:26:06 +08:00
西风逍遥游andCursor Agent 6be72c4c8f feat(particles): 2D/3D dynamic bone emission + expanded tests (#48)
* feat(particles): emit from Spine and IK 2D/3D dynamic bones

Extend ParticleEmitter attach beyond AnimPose to SpineSkeleton and
IK Skeleton2D/Skeleton3D, with getAttachKind and broader unit tests.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(particles): expand dynamic bone attach coverage

Add edge cases (null/OOB, invalid plane), multi-emitter, rate-tracking,
pause/detach sync, Spine scale via module update, IK offset/yz/Solver3D,
AnimPose clip sampling, and empty skin-filter fallback.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(particles): add attach lifetime, forces, and skin plane cases

New particles_attach_more.cpp covers emitter life/buffer on bones,
rebind, scale extremes, emission area, radial origin, Solver2D step
tracking, Spine rotated offsets, preset/stop/start, and skin xz/yz.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

* test(particles): add reset/config/force/skin-filter attach cases

particles_attach_extra.cpp covers reset/moveTo/applyConfig with attach,
ellipse+tangential forces, dt edge cases, kind cycling, Spine rate bob,
Solver3D step, skin filter/buffer, and CesiumMan attach-by-name.

Co-authored-by: 西风逍遥游 <sunxfancy@gmail.com>

---------

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
2026-08-13 11:28:29 +08:00