| 1 | module live |
| 2 | |
| 3 | pub type FNLinkLiveSymbols = fn (linkcb voidptr) |
| 4 | |
| 5 | pub type FNLiveReloadCB = fn (info &LiveReloadInfo) |
| 6 | |
| 7 | pub struct LiveReloadInfo { |
| 8 | pub: |
| 9 | vexe string // full path to the v compiler |
| 10 | vopts string // v compiler options for a live shared library |
| 11 | original string // full path to the original source file, compiled with -live |
| 12 | live_fn_mutex voidptr // the address of the C mutex, that locks the @[live] fns during reloads. |
| 13 | live_linkfn FNLinkLiveSymbols = unsafe { nil } // generated C callback; receives a dlopen handle |
| 14 | so_extension string // .so or .dll |
| 15 | so_name_template string // a template for the shared libraries location |
| 16 | pub mut: |
| 17 | monitored_files []string // an array, containing all paths that should be monitored for changes |
| 18 | live_lib voidptr // the result of dl.open |
| 19 | reloads int // how many times a reloading was tried |
| 20 | reloads_ok int // how many times the reloads succeeded |
| 21 | reload_time_ms int // how much time the last reload took (compilation + loading) |
| 22 | last_mod_ts i64 // a timestamp for when the original was last changed |
| 23 | recheck_period_ms int = 100 // how often do you want to check for changes |
| 24 | cb_recheck FNLiveReloadCB = unsafe { nil } // executed periodically |
| 25 | cb_compile_failed FNLiveReloadCB = unsafe { nil } // executed when a reload compilation failed |
| 26 | cb_before FNLiveReloadCB = unsafe { nil } // executed before a reload try happens |
| 27 | cb_after FNLiveReloadCB = unsafe { nil } // executed after a reload try happened, even if failed |
| 28 | cb_locked_before FNLiveReloadCB = unsafe { nil } // executed before lib reload, in the mutex section |
| 29 | cb_locked_after FNLiveReloadCB = unsafe { nil } // executed after lib reload, in the mutex section |
| 30 | user_ptr voidptr = unsafe { nil } // you can set it to anything, then retrieve it in the cb_ fns |
| 31 | } |
| 32 | |
| 33 | // LiveReloadInfo.live_linkfn should be called by the reloader |
| 34 | // to dlsym all live functions. TODO: research a way to implement |
| 35 | // live_linkfn in pure V, without complicating live code generation |
| 36 | // too much. |
| 37 | // |
| 38 | // The callbacks: cb_compile_fail, cb_before, cb_after will be |
| 39 | // executed outside the mutex protected section, so be careful, |
| 40 | // if you modify your data inside them. They can race with your |
| 41 | // @[live] functions. |
| 42 | // |
| 43 | // cb_locked_before and cb_locked_after will be executed *inside* |
| 44 | // the mutex protected section. They can NOT race with your [live] |
| 45 | // functions. They should be very quick in what they do though, |
| 46 | // otherwise your live functions can be delayed. |
| 47 | // |
| 48 | // live.info - give user access to program's LiveReloadInfo struct, |
| 49 | // so that the user can set callbacks, read meta information, etc. |
| 50 | pub fn info() &LiveReloadInfo { |
| 51 | if g_live_reload_info == 0 { |
| 52 | // When the current program is not compiled with -live, simply |
| 53 | // return a new empty struct LiveReloadInfo in order to prevent |
| 54 | // crashes. In this case, the background reloader thread is not |
| 55 | // started, and the structure LiveReloadInfo will not get updated. |
| 56 | // All its fields will be 0, but still safe to access. |
| 57 | g_live_reload_info = &LiveReloadInfo{} |
| 58 | } |
| 59 | return unsafe { &LiveReloadInfo(g_live_reload_info) } |
| 60 | } |
| 61 | |