Chandra

 view release on metacpan or  search on metacpan

xs/hotreload.xs  view on Meta::CPAN

            SV *key_sv = hv_iterkeysv(he);
            STRLEN klen;
            const char *kpv = SvPV(key_sv, klen);
            if (!hv_exists(current, kpv, (I32)klen)) {
                av_push(changed_av, newSVpvn(kpv, klen));
            }
        }

        changed_count = av_len(changed_av) + 1;

        if (changed_count > 0) {
            /* Update stored files */
            (void)hv_stores(entry_hv, "files", newRV_noinc((SV *)current));

            /* Call callback with arrayref of changed files */
            {
                dSP;
                SV *changed_ref = sv_2mortal(newRV_noinc((SV *)changed_av));
                ENTER; SAVETMPS;
                PUSHMARK(SP);
                XPUSHs(changed_ref);
                PUTBACK;
                call_sv(*cb_svp, G_DISCARD | G_EVAL);
                FREETMPS; LEAVE;

                if (SvTRUE(ERRSV)) {
                    warn("Chandra::HotReload: callback error: %" SVf, SVfARG(ERRSV));
                    sv_setpvs(ERRSV, "");
                }
            }

            total_changed += changed_count;
        } else {
            SvREFCNT_dec((SV *)current);
            SvREFCNT_dec((SV *)changed_av);
        }
    }

    RETVAL = total_changed;
    done:
    ;
}
OUTPUT:
    RETVAL

SV *
clear(self)
    SV *self
CODE:
{
    HV *hv = (HV *)SvRV(self);
    (void)hv_stores(hv, "watches", newRV_noinc((SV *)newAV()));
    RETVAL = SvREFCNT_inc(self);
}
OUTPUT:
    RETVAL

void
watched_paths(self)
    SV *self
PPCODE:
{
    HV *hv = (HV *)SvRV(self);
    SV **watches_svp = hv_fetchs(hv, "watches", 0);
    AV *watches_av = (AV *)SvRV(*watches_svp);
    I32 i, len = av_len(watches_av) + 1;

    if (GIMME_V == G_SCALAR) {
        EXTEND(SP, 1);
        PUSHs(sv_2mortal(newSViv(len)));
    } else {
        EXTEND(SP, len);
        for (i = 0; i < len; i++) {
            SV **entry_svp = av_fetch(watches_av, i, 0);
            HV *entry_hv = (HV *)SvRV(*entry_svp);
            SV **path_svp = hv_fetchs(entry_hv, "path", 0);
            PUSHs(sv_2mortal(newSVsv(*path_svp)));
        }
    }
}

SV *
interval(self, ...)
    SV *self
CODE:
{
    HV *hv = (HV *)SvRV(self);
    SV **svp;

    if (items > 1) {
        (void)hv_stores(hv, "interval", newSVnv(SvNV(ST(1))));
    }

    svp = hv_fetchs(hv, "interval", 0);
    RETVAL = newSVnv(SvNV(*svp));
}
OUTPUT:
    RETVAL

SV *
_scan_files(self, path_sv)
    SV *self
    SV *path_sv
CODE:
{
    const char *path = SvPV_nolen(path_sv);
    HV *files_hv = newHV();
    Stat_t st;

    PERL_UNUSED_VAR(self);

    if (PerlLIO_stat(path, &st) == 0) {
        if (S_ISREG(st.st_mode)) {
            /* Single file */
            STRLEN plen = SvCUR(path_sv);
            (void)hv_store(files_hv, path, (I32)plen, newSVnv((NV)st.st_mtime), 0);
        } else if (S_ISDIR(st.st_mode)) {
            /* Recursive C directory walk - no File::Find / eval_pv */
            _hotreload_scan_recursive(aTHX_ path, files_hv);
        }
    }



( run in 0.533 second using v1.01-cache-2.11-cpan-71847e10f99 )