Fix marker destruction: use CleanupEntity_ProcessAttachments (0x670d50)
The native high-level destructor counterpart to CreateEntityInstance_WithAttachment. Properly detaches from render lists and scene graph before freeing memory, fixing the delayed crash from dangling pointers in the per-frame render path.
This commit is contained in:
@@ -73,12 +73,14 @@ fn createEntityInstance(path: [*:0]const u8, pos: *[3]f32, facing: f32, flags: u
|
||||
return if (result != 0) @ptrFromInt(result) else null;
|
||||
}
|
||||
|
||||
/// DestroyWorldObjectAndRelease — __fastcall(ECX=obj), tail JMP.
|
||||
fn destroyWorldObject(obj: *anyopaque) void {
|
||||
/// CleanupEntity_ProcessAttachments — __fastcall(ECX=entity), no stack params.
|
||||
/// High-level destructor: frees attachments, decrements refcount, dispatches
|
||||
/// to type-specific cleanup (render detach + scene graph removal + heap free).
|
||||
fn cleanupEntity(obj: *anyopaque) void {
|
||||
asm volatile ("call *%[func]"
|
||||
:
|
||||
: [_] "{ecx}" (@intFromPtr(obj)),
|
||||
[func] "r" (o.FN_DESTROY_WORLD_OBJECT),
|
||||
[func] "r" (o.FN_CLEANUP_ENTITY),
|
||||
: .{ .eax = true, .edx = true, .memory = true, .cc = true }
|
||||
);
|
||||
}
|
||||
@@ -139,7 +141,7 @@ pub fn destroyTestMarker() void {
|
||||
test_marker = null;
|
||||
|
||||
con.print("[markers] destroying marker...\n");
|
||||
destroyWorldObject(marker);
|
||||
cleanupEntity(marker);
|
||||
con.print("[markers] marker destroyed\n");
|
||||
}
|
||||
|
||||
|
||||
+10
-1
@@ -43,9 +43,18 @@ pub const FN_ALLOCATE_WORLD_OBJECT: usize = 0x006a0930;
|
||||
|
||||
/// DestroyWorldObjectAndRelease(object) — __fastcall, ECX=obj, no stack params.
|
||||
/// Unlinks from world object list (+0x10/+0x14), calls virtual destructor, frees heap.
|
||||
/// Ends with tail JMP to ReleaseToHeap — from caller's perspective, a normal return.
|
||||
/// ONLY for objects on WENTITY heap (from AllocateAndInitializeWorldObject).
|
||||
pub const FN_DESTROY_WORLD_OBJECT: usize = 0x006a0a70;
|
||||
|
||||
/// CleanupEntity_ProcessAttachments(entity) — __fastcall, ECX=entity, no stack params.
|
||||
/// High-level destructor counterpart to CreateEntityInstance_WithAttachment.
|
||||
/// Walks and frees attachment children, decrements refcount at +0x0E, then
|
||||
/// dispatches to type-specific destructor based on flags at +0x8:
|
||||
/// flag 0x8 (M2): destroyWorldEnvironment (0x6a6870) — scene graph removal + free
|
||||
/// flag 0x40 (WMO): cleanupGameObject (0x6a67a0) — render detach + spatial unlink + free
|
||||
/// Only actually frees when refcount reaches 0.
|
||||
pub const FN_CLEANUP_ENTITY: usize = 0x00670d50;
|
||||
|
||||
/// DecrementReferenceCount(obj) — __fastcall, ECX=obj, no stack params.
|
||||
/// Decrements ref count; when it reaches 0, calls virtual destructor to free.
|
||||
pub const FN_DECREMENT_REFCOUNT: usize = 0x007103a0;
|
||||
|
||||
Reference in New Issue
Block a user