• src/syncterm/Wren.adoc src/syncterm/scripts/console.wren src/syncterm/

    From Deuc¨@VERT to Git commit to main/sbbs/master on Mon Apr 27 16:09:28 2026
    https://gitlab.synchro.net/main/sbbs/-/commit/4adbdc8d6d1dbafb8877cd67
    Modified Files:
    src/syncterm/Wren.adoc src/syncterm/scripts/console.wren src/syncterm/scripts/load/wrentest.wren src/syncterm/scripts/syncterm.wren src/syncterm/term.c wren_bind.c wren_host.c wren_host.h wren_host_internal.h
    Log Message:
    SyncTERM: Wren HookHandle + main-loop hook compaction

    Foreign HookHandle returned by Hook.on*/Hook.every Ä no Wren-side
    constructor, so scripts can only remove their own hooks. Carries
    per-entry metrics (callCount, totalRuntime, min/maxRuntime) timed
    through xp_timer().

    Hook + timer entries are now heap-allocated structs reached through
    pointer arrays in state.hooks[]/state.timers[]. HookHandle.remove()
    releases the fn handle and links the entry onto a cleanup queue; wren_host_compact() drains that queue from the doterm() outer loop,
    shifts the entry out of its dispatch array, and frees regex
    resources. The struct itself stays alive until both compaction has
    run and Wren's GC has fired the foreign-class finalizer, so removed
    handles keep returning sensible metric reads until the script drops
    them.

    The unified wren_hook_entry struct discriminates hook vs timer via
    ev (extended with WREN_HOOK_TIMER), letting the dispatch
    infrastructure share one path for the lifetime + cleanup machinery.

    Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
    ---
    þ Synchronet þ Vertrauen þ Home of Synchronet þ [vert/cvs/bbs].synchro.net