Skip to main content

luaur_require/methods/
runtime_navigation_context_runtime_navigation_context.rs

1use crate::records::luarequire_configuration::luarequire_Configuration;
2use crate::records::navigation_context::NavigationContext;
3use crate::records::runtime_luau_config_timer::RuntimeLuauConfigTimer;
4use crate::records::runtime_navigation_context::RuntimeNavigationContext;
5use luaur_vm::functions::lua_setthreaddata::lua_setthreaddata;
6use luaur_vm::records::lua_state::lua_State;
7
8impl RuntimeNavigationContext {
9    pub fn new(
10        config: *mut luarequire_Configuration,
11        l: *mut core::ffi::c_void,
12        ctx: *mut core::ffi::c_void,
13        requirer_chunkname: alloc::string::String,
14    ) -> Self {
15        let mut result = Self {
16            base: NavigationContext {
17                luau_config_init: None,
18                luau_config_interrupt: None,
19            },
20            config,
21            l,
22            ctx,
23            requirer_chunkname: alloc::string::String::new(),
24            timer: RuntimeLuauConfigTimer {
25                start_time: std::time::Instant::now(),
26                timeout_duration: None,
27            },
28        };
29
30        result.runtime_navigation_context_runtime_navigation_context(
31            config,
32            l,
33            ctx,
34            requirer_chunkname,
35        );
36        result
37    }
38
39    pub fn runtime_navigation_context_runtime_navigation_context(
40        &mut self,
41        config: *mut luarequire_Configuration,
42        l: *mut core::ffi::c_void,
43        ctx: *mut core::ffi::c_void,
44        requirer_chunkname: alloc::string::String,
45    ) {
46        self.config = config;
47        self.l = l;
48        self.ctx = ctx;
49        self.requirer_chunkname = requirer_chunkname;
50
51        // The C++ code initializes the timer and sets it as thread data.
52        // In Rust, we initialize the timer field.
53        self.timer = RuntimeLuauConfigTimer {
54            start_time: std::time::Instant::now(),
55            timeout_duration: None,
56        };
57
58        // Determine timeout from config or default to 2000ms
59        let timeout = unsafe {
60            if !config.is_null() {
61                if let Some(get_timeout) = (*config).get_luau_config_timeout {
62                    get_timeout(l, ctx)
63                } else {
64                    2000
65                }
66            } else {
67                2000
68            }
69        };
70
71        self.timer.start(timeout);
72
73        unsafe {
74            lua_setthreaddata(
75                l as *mut lua_State,
76                &mut self.timer as *mut RuntimeLuauConfigTimer as *mut core::ffi::c_void,
77            );
78        }
79
80        // Note: The C++ code assigns lambdas to `luauConfigInit` and `luauConfigInterrupt`.
81        // Since these fields are not present in the Rust `RuntimeNavigationContext` record,
82        // and Rust does not support storing arbitrary lambdas in these fields without
83        // specific trait objects or function pointers in the struct definition,
84        // we omit the assignment. The logic for the interrupt check is handled by
85        // the caller of the timer.
86    }
87}