Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 498dbc6

Browse files
[windows] Mostly eliminate the state structs (#20662)
The Windows embedding was based on the GLFW embedding, which grew organically from a singe-file implementation that used structs to manage all of the important state. It is in the process of being converted to a cleaner object-based architecture, but currently it is a hybrid of objects and structs that have redundant data, making it very prone to errors of forgetting to update pointers in multiple locations. This reduces the remaining structs to only a single pointer to the larger object that manages the responsibilities that handle is associated with, so that there is no need to wire things together in multiple places. For now they continue to exist as projections of the larger objects, but that will be eliminated over time by having an object structure that better reflects the API structure. Fixes flutter/flutter#64250
1 parent 9336f5d commit 498dbc6

File tree

5 files changed

+61
-52
lines changed

5 files changed

+61
-52
lines changed

shell/platform/windows/flutter_windows.cc

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
#include "flutter/shell/platform/windows/flutter_windows_view.h"
2525
#include "flutter/shell/platform/windows/win32_dpi_utils.h"
2626
#include "flutter/shell/platform/windows/win32_flutter_window.h"
27-
#include "flutter/shell/platform/windows/win32_platform_handler.h"
2827
#include "flutter/shell/platform/windows/win32_task_runner.h"
2928
#include "flutter/shell/platform/windows/window_binding_handler.h"
3029
#include "flutter/shell/platform/windows/window_state.h"
@@ -37,12 +36,22 @@ static flutter::FlutterWindowsEngine* EngineFromHandle(
3736
return reinterpret_cast<flutter::FlutterWindowsEngine*>(ref);
3837
}
3938

40-
// Returns opaque API handle for the given engine instance.
39+
// Returns the opaque API handle for the given engine instance.
4140
static FlutterDesktopEngineRef HandleForEngine(
4241
flutter::FlutterWindowsEngine* engine) {
4342
return reinterpret_cast<FlutterDesktopEngineRef>(engine);
4443
}
4544

45+
// Returns the view corresponding to the given opaque API handle.
46+
static flutter::FlutterWindowsView* ViewFromHandle(FlutterDesktopViewRef ref) {
47+
return reinterpret_cast<flutter::FlutterWindowsView*>(ref);
48+
}
49+
50+
// Returns the opaque API handle for the given view instance.
51+
static FlutterDesktopViewRef HandleForView(flutter::FlutterWindowsView* view) {
52+
return reinterpret_cast<FlutterDesktopViewRef>(view);
53+
}
54+
4655
FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
4756
int width,
4857
int height,
@@ -54,8 +63,6 @@ FlutterDesktopViewControllerRef FlutterDesktopViewControllerCreate(
5463
state->view =
5564
std::make_unique<flutter::FlutterWindowsView>(std::move(window_wrapper));
5665
state->view->CreateRenderSurface();
57-
state->view_wrapper = std::make_unique<FlutterDesktopView>();
58-
state->view_wrapper->view = state->view.get();
5966

6067
// Take ownership of the engine, starting it if necessary.
6168
state->view->SetEngine(
@@ -83,7 +90,7 @@ FlutterDesktopEngineRef FlutterDesktopViewControllerGetEngine(
8390

8491
FlutterDesktopViewRef FlutterDesktopViewControllerGetView(
8592
FlutterDesktopViewControllerRef controller) {
86-
return controller->view_wrapper.get();
93+
return HandleForView(controller->view.get());
8794
}
8895

8996
bool FlutterDesktopViewControllerHandleTopLevelWindowProc(
@@ -144,13 +151,13 @@ FlutterDesktopMessengerRef FlutterDesktopEngineGetMessenger(
144151
return EngineFromHandle(engine)->messenger();
145152
}
146153

147-
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view_ref) {
148-
return std::get<HWND>(*view_ref->view->GetRenderTarget());
154+
HWND FlutterDesktopViewGetHWND(FlutterDesktopViewRef view) {
155+
return std::get<HWND>(*ViewFromHandle(view)->GetRenderTarget());
149156
}
150157

151158
FlutterDesktopViewRef FlutterDesktopPluginRegistrarGetView(
152159
FlutterDesktopPluginRegistrarRef registrar) {
153-
return registrar->view.get();
160+
return HandleForView(registrar->engine->view());
154161
}
155162

156163
void FlutterDesktopPluginRegistrarRegisterTopLevelWindowProcDelegate(
@@ -197,7 +204,7 @@ FlutterDesktopMessengerRef FlutterDesktopRegistrarGetMessenger(
197204
void FlutterDesktopRegistrarSetDestructionHandler(
198205
FlutterDesktopPluginRegistrarRef registrar,
199206
FlutterDesktopOnRegistrarDestroyed callback) {
200-
registrar->destruction_handler = callback;
207+
registrar->engine->SetPluginRegistrarDestructionCallback(callback);
201208
}
202209

203210
bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
@@ -209,7 +216,7 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
209216
FlutterPlatformMessageResponseHandle* response_handle = nullptr;
210217
if (reply != nullptr && user_data != nullptr) {
211218
FlutterEngineResult result = FlutterPlatformMessageCreateResponseHandle(
212-
messenger->engine, reply, user_data, &response_handle);
219+
messenger->engine->engine(), reply, user_data, &response_handle);
213220
if (result != kSuccess) {
214221
std::cout << "Failed to create response handle\n";
215222
return false;
@@ -224,11 +231,11 @@ bool FlutterDesktopMessengerSendWithReply(FlutterDesktopMessengerRef messenger,
224231
response_handle,
225232
};
226233

227-
FlutterEngineResult message_result =
228-
FlutterEngineSendPlatformMessage(messenger->engine, &platform_message);
234+
FlutterEngineResult message_result = FlutterEngineSendPlatformMessage(
235+
messenger->engine->engine(), &platform_message);
229236

230237
if (response_handle != nullptr) {
231-
FlutterPlatformMessageReleaseResponseHandle(messenger->engine,
238+
FlutterPlatformMessageReleaseResponseHandle(messenger->engine->engine(),
232239
response_handle);
233240
}
234241

@@ -248,13 +255,14 @@ void FlutterDesktopMessengerSendResponse(
248255
const FlutterDesktopMessageResponseHandle* handle,
249256
const uint8_t* data,
250257
size_t data_length) {
251-
FlutterEngineSendPlatformMessageResponse(messenger->engine, handle, data,
252-
data_length);
258+
FlutterEngineSendPlatformMessageResponse(messenger->engine->engine(), handle,
259+
data, data_length);
253260
}
254261

255262
void FlutterDesktopMessengerSetCallback(FlutterDesktopMessengerRef messenger,
256263
const char* channel,
257264
FlutterDesktopMessageCallback callback,
258265
void* user_data) {
259-
messenger->dispatcher->SetMessageCallback(channel, callback, user_data);
266+
messenger->engine->message_dispatcher()->SetMessageCallback(channel, callback,
267+
user_data);
260268
}

shell/platform/windows/flutter_windows_engine.cc

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -103,17 +103,14 @@ FlutterWindowsEngine::FlutterWindowsEngine(const FlutterProjectBundle& project)
103103
}
104104
});
105105

106-
// Set up the structure of the state/handle objects; engine and view
107-
// paramaters will be filled in later.
106+
// Set up the legacy structs backing the API handles.
108107
messenger_ = std::make_unique<FlutterDesktopMessenger>();
109-
message_dispatcher_ =
110-
std::make_unique<IncomingMessageDispatcher>(messenger_.get());
111-
messenger_->dispatcher = message_dispatcher_.get();
112-
108+
messenger_->engine = this;
113109
plugin_registrar_ = std::make_unique<FlutterDesktopPluginRegistrar>();
114110
plugin_registrar_->engine = this;
115-
plugin_registrar_->view = std::make_unique<FlutterDesktopView>();
116111

112+
message_dispatcher_ =
113+
std::make_unique<IncomingMessageDispatcher>(messenger_.get());
117114
window_proc_delegate_manager_ =
118115
std::make_unique<Win32WindowProcDelegateManager>();
119116
}
@@ -200,8 +197,8 @@ bool FlutterWindowsEngine::RunWithEntrypoint(const char* entrypoint) {
200197

201198
bool FlutterWindowsEngine::Stop() {
202199
if (engine_) {
203-
if (plugin_registrar_ && plugin_registrar_->destruction_handler) {
204-
plugin_registrar_->destruction_handler(plugin_registrar_.get());
200+
if (plugin_registrar_destruction_callback_) {
201+
plugin_registrar_destruction_callback_(plugin_registrar_.get());
205202
}
206203
FlutterEngineResult result = FlutterEngineShutdown(engine_);
207204
engine_ = nullptr;
@@ -212,14 +209,18 @@ bool FlutterWindowsEngine::Stop() {
212209

213210
void FlutterWindowsEngine::SetView(FlutterWindowsView* view) {
214211
view_ = view;
215-
plugin_registrar_->view->view = view;
216212
}
217213

218214
// Returns the currently configured Plugin Registrar.
219215
FlutterDesktopPluginRegistrarRef FlutterWindowsEngine::GetRegistrar() {
220216
return plugin_registrar_.get();
221217
}
222218

219+
void FlutterWindowsEngine::SetPluginRegistrarDestructionCallback(
220+
FlutterDesktopOnRegistrarDestroyed callback) {
221+
plugin_registrar_destruction_callback_ = callback;
222+
}
223+
223224
void FlutterWindowsEngine::HandlePlatformMessage(
224225
const FlutterPlatformMessage* engine_message) {
225226
if (engine_message->struct_size != sizeof(FlutterPlatformMessage)) {

shell/platform/windows/flutter_windows_engine.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,10 +61,18 @@ class FlutterWindowsEngine {
6161
// Returns the currently configured Plugin Registrar.
6262
FlutterDesktopPluginRegistrarRef GetRegistrar();
6363

64+
// Sets |callback| to be called when the plugin registrar is destroyed.
65+
void SetPluginRegistrarDestructionCallback(
66+
FlutterDesktopOnRegistrarDestroyed callback);
67+
6468
FLUTTER_API_SYMBOL(FlutterEngine) engine() { return engine_; }
6569

6670
FlutterDesktopMessengerRef messenger() { return messenger_.get(); }
6771

72+
IncomingMessageDispatcher* message_dispatcher() {
73+
return message_dispatcher_.get();
74+
}
75+
6876
Win32TaskRunner* task_runner() { return task_runner_.get(); }
6977

7078
Win32WindowProcDelegateManager* window_proc_delegate_manager() {
@@ -105,6 +113,10 @@ class FlutterWindowsEngine {
105113
// The plugin registrar handle given to API clients.
106114
std::unique_ptr<FlutterDesktopPluginRegistrar> plugin_registrar_;
107115

116+
// A callback to be called when the engine (and thus the plugin registrar)
117+
// is being destroyed.
118+
FlutterDesktopOnRegistrarDestroyed plugin_registrar_destruction_callback_;
119+
108120
// The manager for WindowProc delegate registration and callbacks.
109121
std::unique_ptr<Win32WindowProcDelegateManager> window_proc_delegate_manager_;
110122
};

shell/platform/windows/public/flutter_windows.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ typedef struct FlutterDesktopViewControllerState*
2222
FlutterDesktopViewControllerRef;
2323

2424
// Opaque reference to a Flutter window.
25+
struct FlutterDesktopView;
2526
typedef struct FlutterDesktopView* FlutterDesktopViewRef;
2627

2728
// Opaque reference to a Flutter engine instance.

shell/platform/windows/window_state.h

Lines changed: 13 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -9,48 +9,35 @@
99
#include "flutter/shell/platform/common/cpp/incoming_message_dispatcher.h"
1010
#include "flutter/shell/platform/embedder/embedder.h"
1111

12+
// Structs backing the opaque references used in the C API.
13+
//
14+
// DO NOT ADD ANY NEW CODE HERE. These are legacy, and are being phased out
15+
// in favor of objects that own and manage the relevant functionality.
16+
1217
namespace flutter {
1318
struct FlutterWindowsEngine;
1419
struct FlutterWindowsView;
1520
} // namespace flutter
1621

17-
// Struct for storing state within an instance of the windows native (HWND or
18-
// CoreWindow) Window.
22+
// Wrapper to distinguish the view controller ref from the view ref given out
23+
// in the C API.
1924
struct FlutterDesktopViewControllerState {
2025
// The view that backs this state object.
2126
std::unique_ptr<flutter::FlutterWindowsView> view;
22-
23-
// The window handle given to API clients.
24-
std::unique_ptr<FlutterDesktopView> view_wrapper;
2527
};
2628

27-
// Opaque reference for the native windows itself. This is separate from the
28-
// controller so that it can be provided to plugins without giving them access
29-
// to all of the controller-based functionality.
30-
struct FlutterDesktopView {
31-
// The view that (indirectly) owns this state object.
32-
flutter::FlutterWindowsView* view = nullptr;
33-
};
34-
35-
// State associated with the plugin registrar.
29+
// Wrapper to distinguish the plugin registrar ref from the engine ref given out
30+
// in the C API.
3631
struct FlutterDesktopPluginRegistrar {
3732
// The engine that owns this state object.
3833
flutter::FlutterWindowsEngine* engine = nullptr;
39-
40-
// The handle for the view associated with this registrar.
41-
std::unique_ptr<FlutterDesktopView> view;
42-
43-
// Callback to be called on registrar destruction.
44-
FlutterDesktopOnRegistrarDestroyed destruction_handler;
4534
};
4635

47-
// State associated with the messenger used to communicate with the engine.
36+
// Wrapper to distinguish the messenger ref from the engine ref given out
37+
// in the C API.
4838
struct FlutterDesktopMessenger {
49-
// The Flutter engine this messenger sends outgoing messages to.
50-
FLUTTER_API_SYMBOL(FlutterEngine) engine;
51-
52-
// The message dispatcher for handling incoming messages.
53-
flutter::IncomingMessageDispatcher* dispatcher;
39+
// The engine that owns this state object.
40+
flutter::FlutterWindowsEngine* engine = nullptr;
5441
};
5542

5643
#endif // FLUTTER_SHELL_PLATFORM_WINDOWS_FLUTTER_WINDOW_STATE_H_

0 commit comments

Comments
 (0)