@@ -32,6 +32,12 @@ pub const OtherCbk = struct {
3232};
3333
3434pub const Window = struct {
35+
36+ // store a map between internal timeouts ids and pointers to uint.
37+ // the maximum number of possible timeouts is fixed.
38+ timeoutid : u32 = 0 ,
39+ timeoutids : [10 ]u64 = undefined ,
40+
3541 pub fn constructor () Window {
3642 return Window {};
3743 }
@@ -45,26 +51,39 @@ pub const Window = struct {
4551 }
4652
4753 pub fn _cbkAsync (
48- _ : Window ,
54+ self : * Window ,
4955 loop : * jsruntime.Loop ,
5056 callback : Callback ,
5157 milliseconds : u32 ,
52- ) void {
58+ ) u32 {
5359 const n : u63 = @intCast (milliseconds );
54- // TODO: check this value can be holded in u63
55- _ = loop .timeout (n * std .time .ns_per_ms , callback );
60+ const id = loop .timeout (n * std .time .ns_per_ms , callback );
61+
62+ defer self .timeoutid += 1 ;
63+ self .timeoutids [self .timeoutid ] = id ;
64+
65+ return self .timeoutid ;
5666 }
5767
5868 pub fn _cbkAsyncWithJSArg (
59- _ : Window ,
69+ self : * Window ,
6070 loop : * jsruntime.Loop ,
6171 callback : Callback ,
6272 milliseconds : u32 ,
6373 _ : CallbackArg ,
64- ) void {
74+ ) u32 {
6575 const n : u63 = @intCast (milliseconds );
66- // TODO: check this value can be holded in u63
67- _ = loop .timeout (n * std .time .ns_per_ms , callback );
76+ const id = loop .timeout (n * std .time .ns_per_ms , callback );
77+
78+ defer self .timeoutid += 1 ;
79+ self .timeoutids [self .timeoutid ] = id ;
80+
81+ return self .timeoutid ;
82+ }
83+
84+ pub fn _cancel (self : Window , loop : * jsruntime.Loop , id : u32 ) void {
85+ if (id >= self .timeoutid ) return ;
86+ loop .cancel (self .timeoutids [id ], null );
6887 }
6988
7089 pub fn _cbkAsyncWithNatArg (_ : Window , callback : Callback ) ! void {
@@ -163,7 +182,7 @@ pub fn exec(
163182 \\};
164183 \\window.cbkAsync(f, 100); // 0.1 second
165184 ,
166- .ex = "undefined " ,
185+ .ex = "0 " ,
167186 },
168187 // arrow functional
169188 .{
@@ -174,7 +193,7 @@ pub fn exec(
174193 \\if (p != 2) {throw Error('cases_cbk_async error: p is not equal to 2');}
175194 \\}, 100); // 0.1 second
176195 ,
177- .ex = "undefined " ,
196+ .ex = "1 " ,
178197 },
179198 };
180199 try tests .checkCases (js_env , & cases_cbk_async );
@@ -191,7 +210,7 @@ pub fn exec(
191210 \\};
192211 \\window.cbkAsyncWithJSArg(f, 100, 2); // 0.1 second
193212 ,
194- .ex = "undefined " ,
213+ .ex = "2 " ,
195214 },
196215 // arrow functional
197216 .{
@@ -202,7 +221,7 @@ pub fn exec(
202221 \\if (j != 3) {throw Error('j is not equal to 3');}
203222 \\}, 100, 2); // 0.1 second
204223 ,
205- .ex = "undefined " ,
224+ .ex = "3 " ,
206225 },
207226 };
208227 try tests .checkCases (js_env , & cases_cbk_async_with_js_arg );
@@ -240,4 +259,18 @@ pub fn exec(
240259 .{ .src = "v" , .ex = "1" },
241260 };
242261 try tests .checkCases (js_env , & cases_cbk_setter_arg );
262+
263+ // cancel cbk
264+ var cases_cbk_cancel = [_ ]tests.Case {
265+ .{
266+ .src =
267+ \\let vv = 0;
268+ \\const id = window.cbkAsync(() => {vv += 1}, 100);
269+ \\window.cancel(id);
270+ ,
271+ .ex = "undefined" ,
272+ },
273+ .{ .src = "vv" , .ex = "0" },
274+ };
275+ try tests .checkCases (js_env , & cases_cbk_cancel );
243276}
0 commit comments