Use a signal for the pre-engine restart event (flutter/engine#55063)

With multiple FlViews a callback doesn't scale.
This commit is contained in:
Robert Ancell 2024-09-12 09:25:52 +12:00 committed by GitHub
parent 7a06558bd9
commit a89c2ae2a4
4 changed files with 25 additions and 79 deletions

View File

@ -62,11 +62,6 @@ struct _FlEngine {
FlEngineUpdateSemanticsHandler update_semantics_handler; FlEngineUpdateSemanticsHandler update_semantics_handler;
gpointer update_semantics_handler_data; gpointer update_semantics_handler_data;
GDestroyNotify update_semantics_handler_destroy_notify; GDestroyNotify update_semantics_handler_destroy_notify;
// Function to call right before the engine is restarted.
FlEngineOnPreEngineRestartHandler on_pre_engine_restart_handler;
gpointer on_pre_engine_restart_handler_data;
GDestroyNotify on_pre_engine_restart_handler_destroy_notify;
}; };
G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error) G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error)
@ -74,6 +69,10 @@ G_DEFINE_QUARK(fl_engine_error_quark, fl_engine_error)
static void fl_engine_plugin_registry_iface_init( static void fl_engine_plugin_registry_iface_init(
FlPluginRegistryInterface* iface); FlPluginRegistryInterface* iface);
enum { kSignalOnPreEngineRestart, kSignalLastSignal };
static guint fl_engine_signals[kSignalLastSignal];
G_DEFINE_TYPE_WITH_CODE( G_DEFINE_TYPE_WITH_CODE(
FlEngine, FlEngine,
fl_engine, fl_engine,
@ -343,10 +342,7 @@ static void fl_engine_update_semantics_cb(const FlutterSemanticsUpdate2* update,
static void fl_engine_on_pre_engine_restart_cb(void* user_data) { static void fl_engine_on_pre_engine_restart_cb(void* user_data) {
FlEngine* self = FL_ENGINE(user_data); FlEngine* self = FL_ENGINE(user_data);
if (self->on_pre_engine_restart_handler != nullptr) { g_signal_emit(self, fl_engine_signals[kSignalOnPreEngineRestart], 0);
self->on_pre_engine_restart_handler(
self, self->on_pre_engine_restart_handler_data);
}
} }
// Called when a response to a sent platform message is received from the // Called when a response to a sent platform message is received from the
@ -427,13 +423,6 @@ static void fl_engine_dispose(GObject* object) {
self->update_semantics_handler_data = nullptr; self->update_semantics_handler_data = nullptr;
self->update_semantics_handler_destroy_notify = nullptr; self->update_semantics_handler_destroy_notify = nullptr;
if (self->on_pre_engine_restart_handler_destroy_notify) {
self->on_pre_engine_restart_handler_destroy_notify(
self->on_pre_engine_restart_handler_data);
}
self->on_pre_engine_restart_handler_data = nullptr;
self->on_pre_engine_restart_handler_destroy_notify = nullptr;
G_OBJECT_CLASS(fl_engine_parent_class)->dispose(object); G_OBJECT_CLASS(fl_engine_parent_class)->dispose(object);
} }
@ -448,6 +437,10 @@ static void fl_engine_class_init(FlEngineClass* klass) {
fl_binary_messenger_get_type(), fl_binary_messenger_get_type(),
static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | static_cast<GParamFlags>(G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS))); G_PARAM_STATIC_STRINGS)));
fl_engine_signals[kSignalOnPreEngineRestart] = g_signal_new(
"on-pre-engine-restart", fl_engine_get_type(), G_SIGNAL_RUN_LAST, 0,
nullptr, nullptr, nullptr, G_TYPE_NONE, 0);
} }
static void fl_engine_init(FlEngine* self) { static void fl_engine_init(FlEngine* self) {
@ -735,23 +728,6 @@ void fl_engine_set_update_semantics_handler(
self->update_semantics_handler_destroy_notify = destroy_notify; self->update_semantics_handler_destroy_notify = destroy_notify;
} }
void fl_engine_set_on_pre_engine_restart_handler(
FlEngine* self,
FlEngineOnPreEngineRestartHandler handler,
gpointer user_data,
GDestroyNotify destroy_notify) {
g_return_if_fail(FL_IS_ENGINE(self));
if (self->on_pre_engine_restart_handler_destroy_notify) {
self->on_pre_engine_restart_handler_destroy_notify(
self->on_pre_engine_restart_handler_data);
}
self->on_pre_engine_restart_handler = handler;
self->on_pre_engine_restart_handler_data = user_data;
self->on_pre_engine_restart_handler_destroy_notify = destroy_notify;
}
// Note: This function can be called from any thread. // Note: This function can be called from any thread.
gboolean fl_engine_send_platform_message_response( gboolean fl_engine_send_platform_message_response(
FlEngine* self, FlEngine* self,

View File

@ -60,16 +60,6 @@ typedef void (*FlEngineUpdateSemanticsHandler)(
const FlutterSemanticsUpdate2* update, const FlutterSemanticsUpdate2* update,
gpointer user_data); gpointer user_data);
/**
* FlEngineOnPreEngineRestartHandler:
* @engine: an #FlEngine.
* @user_data: (closure): data provided when registering this handler.
*
* Function called right before the engine is restarted.
*/
typedef void (*FlEngineOnPreEngineRestartHandler)(FlEngine* engine,
gpointer user_data);
/** /**
* fl_engine_new_with_renderer: * fl_engine_new_with_renderer:
* @project: an #FlDartProject. * @project: an #FlDartProject.
@ -218,22 +208,6 @@ void fl_engine_set_update_semantics_handler(
gpointer user_data, gpointer user_data,
GDestroyNotify destroy_notify); GDestroyNotify destroy_notify);
/**
* fl_engine_set_on_pre_engine_restart_handler:
* @engine: an #FlEngine.
* @handler: function to call when the engine is restarted.
* @user_data: (closure): user data to pass to @handler.
* @destroy_notify: (allow-none): a function which gets called to free
* @user_data, or %NULL.
*
* Registers the function called right before the engine is restarted.
*/
void fl_engine_set_on_pre_engine_restart_handler(
FlEngine* engine,
FlEngineOnPreEngineRestartHandler handler,
gpointer user_data,
GDestroyNotify destroy_notify);
/** /**
* fl_engine_send_window_metrics_event: * fl_engine_send_window_metrics_event:
* @engine: an #FlEngine. * @engine: an #FlEngine.

View File

@ -275,14 +275,9 @@ void on_pre_engine_restart_cb(FlEngine* engine, gpointer user_data) {
*count += 1; *count += 1;
} }
void on_pre_engine_restart_destroy_notify(gpointer user_data) {
int* count = reinterpret_cast<int*>(user_data);
*count += 10;
}
// Checks restarting the engine invokes the correct callback. // Checks restarting the engine invokes the correct callback.
TEST(FlEngineTest, OnPreEngineRestart) { TEST(FlEngineTest, OnPreEngineRestart) {
FlEngine* engine = make_mock_engine(); g_autoptr(FlEngine) engine = make_mock_engine();
FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine); FlutterEngineProcTable* embedder_api = fl_engine_get_embedder_api(engine);
OnPreEngineRestartCallback callback; OnPreEngineRestartCallback callback;
@ -317,16 +312,11 @@ TEST(FlEngineTest, OnPreEngineRestart) {
// //
// * When the engine restarts, count += 1; // * When the engine restarts, count += 1;
// * When the engine is freed, count += 10. // * When the engine is freed, count += 10.
fl_engine_set_on_pre_engine_restart_handler( g_signal_connect(engine, "on-pre-engine-restart",
engine, on_pre_engine_restart_cb, &count, G_CALLBACK(on_pre_engine_restart_cb), &count);
on_pre_engine_restart_destroy_notify);
callback(callback_user_data); callback(callback_user_data);
EXPECT_EQ(count, 1); EXPECT_EQ(count, 1);
// Disposal should call the destroy notify.
g_object_unref(engine);
EXPECT_EQ(count, 11);
} }
TEST(FlEngineTest, DartEntrypointArgs) { TEST(FlEngineTest, DartEntrypointArgs) {

View File

@ -40,6 +40,9 @@ struct _FlView {
// Engine this view is showing. // Engine this view is showing.
FlEngine* engine; FlEngine* engine;
// Handler for engine restart signal.
guint on_pre_engine_restart_handler;
// ID for this view. // ID for this view.
FlutterViewId view_id; FlutterViewId view_id;
@ -274,9 +277,7 @@ static void update_semantics_cb(FlEngine* engine,
// This method should reset states to be as if the engine had just been started, // This method should reset states to be as if the engine had just been started,
// which usually indicates the user has requested a hot restart (Shift-R in the // which usually indicates the user has requested a hot restart (Shift-R in the
// Flutter CLI.) // Flutter CLI.)
static void on_pre_engine_restart_cb(FlEngine* engine, gpointer user_data) { static void on_pre_engine_restart_cb(FlView* self) {
FlView* self = FL_VIEW(user_data);
init_keyboard(self); init_keyboard(self);
init_scrolling(self); init_scrolling(self);
} }
@ -652,8 +653,12 @@ static void fl_view_dispose(GObject* object) {
if (self->engine != nullptr) { if (self->engine != nullptr) {
fl_engine_set_update_semantics_handler(self->engine, nullptr, nullptr, fl_engine_set_update_semantics_handler(self->engine, nullptr, nullptr,
nullptr); nullptr);
fl_engine_set_on_pre_engine_restart_handler(self->engine, nullptr, nullptr, }
nullptr);
if (self->on_pre_engine_restart_handler != 0) {
g_signal_handler_disconnect(self->engine,
self->on_pre_engine_restart_handler);
self->on_pre_engine_restart_handler = 0;
} }
g_clear_object(&self->engine); g_clear_object(&self->engine);
@ -784,8 +789,9 @@ G_MODULE_EXPORT FlView* fl_view_new_for_engine(FlEngine* engine) {
fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb, fl_engine_set_update_semantics_handler(self->engine, update_semantics_cb,
self, nullptr); self, nullptr);
fl_engine_set_on_pre_engine_restart_handler( self->on_pre_engine_restart_handler =
self->engine, on_pre_engine_restart_cb, self, nullptr); g_signal_connect_swapped(engine, "on-pre-engine-restart",
G_CALLBACK(on_pre_engine_restart_cb), self);
return self; return self;
} }