Skip to content

Commit 57414c3

Browse files
committed
Add Effect.delay factory and refactor Effect.run
The Effect.delay factory creates an effect that runs its callback after a specified duration, with optional eager initialization. The Effect.run method is extracted from the constructor to support manual execution.
1 parent 4082705 commit 57414c3

1 file changed

Lines changed: 69 additions & 11 deletions

File tree

packages/solidart/lib/src/v3.dart

Lines changed: 69 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
// ignore_for_file: public_member_api_docs
22
// TODO(medz): Add code comments
33

4+
import 'dart:async';
5+
46
import 'package:meta/meta.dart';
57
import 'package:solidart/deps/preset.dart' as preset;
68
import 'package:solidart/deps/system.dart' as system;
79

810
typedef ValueComparator<T> = bool Function(T? a, T? b);
911
typedef ValueGetter<T> = T Function();
1012
typedef VoidCallback = ValueGetter<void>;
13+
typedef DelayEffectCallback =
14+
ValueGetter<FutureOr<void>> Function(
15+
T Function<T>(T Function() callback) on,
16+
);
1117

1218
sealed class Option<T> {
1319
const Option();
@@ -294,7 +300,19 @@ class Computed<T> extends preset.ComputedNode<T>
294300
class Effect extends preset.EffectNode
295301
with DisposableMixin
296302
implements Disposable, Configuration {
297-
Effect(
303+
factory Effect(
304+
VoidCallback callback, {
305+
bool? autoDispose,
306+
String? name,
307+
bool? detach,
308+
}) => Effect.manual(
309+
callback,
310+
autoDispose: autoDispose,
311+
name: name,
312+
detach: detach,
313+
)..run();
314+
315+
Effect.manual(
298316
VoidCallback callback, {
299317
bool? autoDispose,
300318
String? name,
@@ -306,18 +324,44 @@ class Effect extends preset.EffectNode
306324
fn: callback,
307325
flags:
308326
system.ReactiveFlags.watching | system.ReactiveFlags.recursedCheck,
309-
) {
310-
final prevSub = preset.setActiveSub(this);
311-
if (prevSub != null && !this.detach) {
312-
preset.link(this, prevSub, 0);
313-
}
327+
);
314328

315-
try {
316-
callback();
317-
} finally {
318-
preset.activeSub = prevSub;
319-
flags &= ~system.ReactiveFlags.recursedCheck;
329+
// TODO(nank1ro): How about this plan?
330+
factory Effect.delay(
331+
DelayEffectCallback factory, {
332+
required Duration duration,
333+
bool? autoDispose,
334+
String? name,
335+
bool? detach,
336+
bool eager = true,
337+
}) {
338+
late final Effect effect;
339+
T on<T>(T Function() callback) {
340+
final prevSub = preset.setActiveSub(effect);
341+
try {
342+
return callback();
343+
} finally {
344+
preset.activeSub = prevSub;
345+
effect.flags &= ~system.ReactiveFlags.recursedCheck;
346+
}
320347
}
348+
349+
final callback = factory(on);
350+
Timer? timer;
351+
effect = Effect.manual(
352+
autoDispose: autoDispose,
353+
name: name,
354+
detach: detach,
355+
() {
356+
timer?.cancel();
357+
timer = .new(duration, () {
358+
unawaited(Future.microtask(callback))
359+
});
360+
},
361+
);
362+
363+
if (eager) effect.run();
364+
return effect;
321365
}
322366

323367
@override
@@ -328,6 +372,20 @@ class Effect extends preset.EffectNode
328372

329373
final bool detach;
330374

375+
void run() {
376+
final prevSub = preset.setActiveSub(this);
377+
if (!detach && prevSub != null) {
378+
preset.link(this, prevSub, 0);
379+
}
380+
381+
try {
382+
fn();
383+
} finally {
384+
preset.activeSub = prevSub;
385+
flags &= ~system.ReactiveFlags.recursedCheck;
386+
}
387+
}
388+
331389
@override
332390
void dispose() {
333391
if (isDisposed) return;

0 commit comments

Comments
 (0)