Skip to content

Commit 6c2e1b5

Browse files
authored
Add PlatformDispatcher.registerHotRestartListener. (#3)
1 parent 86c7c49 commit 6c2e1b5

7 files changed

Lines changed: 74 additions & 0 deletions

File tree

engine/src/flutter/lib/ui/fixtures/ui_test.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,24 @@ void hooksTests() async {
283283
expectEquals(name, 'testName');
284284
});
285285

286+
await test('invokeHotRestartListeners preserves callback zone', () {
287+
late Zone innerZone;
288+
late Zone runZone;
289+
late String name;
290+
291+
runZoned(() {
292+
innerZone = Zone.current;
293+
PlatformDispatcher.instance.registerHotRestartListener(() {
294+
runZone = Zone.current;
295+
name = 'testName';
296+
});
297+
});
298+
299+
_callHook('_invokeHotRestartListeners', 0);
300+
expectIdentical(runZone, innerZone);
301+
expectEquals(name, 'testName');
302+
});
303+
286304
await test('_futureize successfully returns a value async', () async {
287305
String? callbacker(void Function(Object? arg) cb) {
288306
Timer.run(() {

engine/src/flutter/lib/ui/hooks.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ void _dispatchPlatformMessage(String name, ByteData? data, int responseId) {
2424
PlatformDispatcher.instance._dispatchPlatformMessage(name, data, responseId);
2525
}
2626

27+
@pragma('vm:entry-point')
28+
void _invokeHotRestartListeners() {
29+
PlatformDispatcher.instance._invokeHotRestartListeners();
30+
}
31+
2732
@pragma('vm:entry-point')
2833
bool _onError(Object error, StackTrace? stackTrace) {
2934
return PlatformDispatcher.instance._dispatchError(error, stackTrace ?? StackTrace.empty);

engine/src/flutter/lib/ui/platform_dispatcher.dart

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,29 @@ class PlatformDispatcher {
267267
}
268268
}
269269

270+
/// Registers a callback to be called when the application receives a hot restart signal.
271+
void registerHotRestartListener(VoidCallback callback) {
272+
_hotRestartListeners.add((callback, Zone.current));
273+
}
274+
275+
/// Unregisters a callback from being called when the application receives a hot restart signal.
276+
void unregisterHotRestartListener(VoidCallback callback) {
277+
_hotRestartListeners.remove((callback, Zone.current));
278+
}
279+
280+
void _invokeHotRestartListeners() {
281+
final callbacks = List<(VoidCallback, Zone)>.from(_hotRestartListeners);
282+
for (final (callback, zone) in callbacks) {
283+
try {
284+
_invoke(callback, zone);
285+
} catch (e, s) {
286+
onError?.call(e, s);
287+
}
288+
}
289+
}
290+
291+
final List<(VoidCallback, Zone)> _hotRestartListeners = <(VoidCallback, Zone)>[];
292+
270293
/// Set the debug name associated with this platform dispatcher's root
271294
/// isolate.
272295
///

engine/src/flutter/lib/ui/window/platform_configuration.cc

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ void PlatformConfiguration::DidCreateIsolate() {
4343
dispatch_platform_message_.Set(
4444
tonic::DartState::Current(),
4545
Dart_GetField(library, tonic::ToDart("_dispatchPlatformMessage")));
46+
invoke_hot_restart_listeners_.Set(
47+
tonic::DartState::Current(),
48+
Dart_GetField(library, tonic::ToDart("_invokeHotRestartListeners")));
4649
}
4750

4851
bool PlatformConfiguration::SetEngineId(int64_t engine_id) {
@@ -59,6 +62,17 @@ bool PlatformConfiguration::SetEngineId(int64_t engine_id) {
5962
return true;
6063
}
6164

65+
void PlatformConfiguration::InvokeHotRestartListeners() {
66+
std::shared_ptr<tonic::DartState> dart_state =
67+
invoke_hot_restart_listeners_.dart_state().lock();
68+
if (!dart_state) {
69+
return;
70+
}
71+
tonic::DartState::Scope scope(dart_state);
72+
tonic::CheckAndHandleError(
73+
tonic::DartInvoke(invoke_hot_restart_listeners_.Get(), {}));
74+
}
75+
6276
void PlatformConfiguration::UpdateLocales(
6377
const std::vector<std::string>& locales) {
6478
std::shared_ptr<tonic::DartState> dart_state =

engine/src/flutter/lib/ui/window/platform_configuration.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,9 @@ class PlatformConfiguration final {
220220
/// @return Whether the identifier was set.
221221
bool SetEngineId(int64_t engine_id);
222222

223+
/// @brief Calls registered hot restart listener callbacks.
224+
void InvokeHotRestartListeners();
225+
223226
//----------------------------------------------------------------------------
224227
/// @brief Update the specified locale data in the framework.
225228
///
@@ -268,6 +271,7 @@ class PlatformConfiguration final {
268271
tonic::DartPersistentValue set_engine_id_;
269272
tonic::DartPersistentValue update_locales_;
270273
tonic::DartPersistentValue dispatch_platform_message_;
274+
tonic::DartPersistentValue invoke_hot_restart_listeners_;
271275

272276
// ID starts at 1 because an ID of 0 indicates that no response is expected.
273277
int next_response_id_ = 1;

engine/src/flutter/shell/common/engine.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ bool Engine::Restart(RunConfiguration configuration) {
117117
FML_LOG(ERROR) << "Engine run configuration was invalid.";
118118
return false;
119119
}
120+
auto isolate = runtime_controller_->GetRootIsolate().lock();
121+
if (isolate) {
122+
isolate->platform_configuration()->InvokeHotRestartListeners();
123+
}
120124
delegate_.OnPreEngineRestart();
121125
runtime_controller_ = runtime_controller_->Clone();
122126
UpdateAssetManager(nullptr);

examples/hello_world/lib/main.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
import 'dart:ui';
2+
13
void main() {
24
print('Hello there...');
5+
6+
PlatformDispatcher.instance.registerHotRestartListener(() {
7+
print('Hot restart listener called!');
8+
});
39
}

0 commit comments

Comments
 (0)