Skip to content

Commit 63243ea

Browse files
author
idcpj
committed
fix(windows): refactor static globals to instance members to support multiple windows
- Replaced all `static inline` global variables with instance members in `AudioplayersWindowsPlugin`. - Ensured each Engine instance possesses its own independent `MethodChannel` and `EventStreamHandler`. - Fixed crashes occurring when opening a second window due to global static pointer overwriting. - Isolated plugin state across different windows to prevent interference.
1 parent 0e3bca2 commit 63243ea

1 file changed

Lines changed: 77 additions & 34 deletions

File tree

packages/audioplayers_windows/windows/audioplayers_windows_plugin.cpp

Lines changed: 77 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
#include <flutter/plugin_registrar_windows.h>
1212
#include <flutter/standard_method_codec.h>
1313

14+
#include <iostream>
1415
#include <map>
1516
#include <memory>
1617
#include <sstream>
18+
#include <string>
19+
#include <unordered_map>
1720

1821
#include "audio_player.h"
1922
#include "audioplayers_helpers.h"
@@ -47,10 +50,20 @@ class AudioplayersWindowsPlugin : public Plugin {
4750
private:
4851
std::map<std::string, std::unique_ptr<AudioPlayer>> audioPlayers;
4952

50-
static inline BinaryMessenger* binaryMessenger;
51-
static inline std::unique_ptr<MethodChannel<EncodableValue>> methods{};
52-
static inline std::unique_ptr<MethodChannel<EncodableValue>> globalMethods{};
53-
static inline std::unique_ptr<EventStreamHandler<>> globalEvents{};
53+
BinaryMessenger* binaryMessenger;
54+
std::unique_ptr<MethodChannel<EncodableValue>> methods{};
55+
std::unique_ptr<MethodChannel<EncodableValue>> globalMethods{};
56+
57+
// Event channels and handlers must be kept alive
58+
std::unique_ptr<EventChannel<EncodableValue>> globalEventChannel{};
59+
EventStreamHandler<>* globalEvents = nullptr; // Owned by globalEventChannel
60+
61+
// Map to keep player event channels alive
62+
std::map<std::string, std::unique_ptr<EventChannel<EncodableValue>>>
63+
playerEventChannels;
64+
// Map to keep player event handlers alive
65+
std::map<std::string, std::unique_ptr<EventStreamHandler<EncodableValue>>>
66+
playerEventHandlers;
5467

5568
// Called when a method is called on this plugin's channel from Dart.
5669
void HandleMethodCall(const MethodCall<EncodableValue>& method_call,
@@ -70,33 +83,36 @@ class AudioplayersWindowsPlugin : public Plugin {
7083
// static
7184
void AudioplayersWindowsPlugin::RegisterWithRegistrar(
7285
PluginRegistrarWindows* registrar) {
73-
binaryMessenger = registrar->messenger();
74-
methods = std::make_unique<MethodChannel<EncodableValue>>(
75-
binaryMessenger, "xyz.luan/audioplayers",
76-
&StandardMethodCodec::GetInstance());
77-
globalMethods = std::make_unique<MethodChannel<EncodableValue>>(
78-
binaryMessenger, "xyz.luan/audioplayers.global",
86+
auto plugin = std::make_unique<AudioplayersWindowsPlugin>();
87+
88+
plugin->binaryMessenger = registrar->messenger();
89+
90+
plugin->methods = std::make_unique<MethodChannel<EncodableValue>>(
91+
plugin->binaryMessenger, "xyz.luan/audioplayers",
7992
&StandardMethodCodec::GetInstance());
80-
auto _globalEventChannel = std::make_unique<EventChannel<EncodableValue>>(
81-
binaryMessenger, "xyz.luan/audioplayers.global/events",
93+
94+
plugin->globalMethods = std::make_unique<MethodChannel<EncodableValue>>(
95+
plugin->binaryMessenger, "xyz.luan/audioplayers.global",
8296
&StandardMethodCodec::GetInstance());
8397

84-
auto plugin = std::make_unique<AudioplayersWindowsPlugin>();
98+
plugin->globalEventChannel = std::make_unique<EventChannel<EncodableValue>>(
99+
plugin->binaryMessenger, "xyz.luan/audioplayers.global/events",
100+
&StandardMethodCodec::GetInstance());
85101

86-
methods->SetMethodCallHandler(
102+
plugin->methods->SetMethodCallHandler(
87103
[plugin_pointer = plugin.get()](const auto& call, auto result) {
88104
plugin_pointer->HandleMethodCall(call, std::move(result));
89105
});
90106

91-
globalMethods->SetMethodCallHandler(
107+
plugin->globalMethods->SetMethodCallHandler(
92108
[plugin_pointer = plugin.get()](const auto& call, auto result) {
93109
plugin_pointer->HandleGlobalMethodCall(call, std::move(result));
94110
});
95-
globalEvents = std::make_unique<EventStreamHandler<>>();
96-
auto _obj_stm_handle =
97-
static_cast<StreamHandler<EncodableValue>*>(globalEvents.get());
98-
std::unique_ptr<StreamHandler<EncodableValue>> _ptr{_obj_stm_handle};
99-
_globalEventChannel->SetStreamHandler(std::move(_ptr));
111+
112+
auto handler = std::make_unique<EventStreamHandler<EncodableValue>>();
113+
plugin->globalEvents = handler.get();
114+
115+
plugin->globalEventChannel->SetStreamHandler(std::move(handler));
100116

101117
registrar->AddPlugin(std::move(plugin));
102118
}
@@ -123,7 +139,9 @@ void AudioplayersWindowsPlugin::HandleGlobalMethodCall(
123139
} else if (method_call.method_name().compare("emitError") == 0) {
124140
auto code = GetArgument<std::string>("code", args, std::string());
125141
auto message = GetArgument<std::string>("message", args, std::string());
126-
globalEvents->Error(code, message, nullptr);
142+
if (globalEvents) {
143+
globalEvents->Error(code, message, nullptr);
144+
}
127145
result->Success();
128146
} else {
129147
result->NotImplemented();
@@ -247,6 +265,8 @@ void AudioplayersWindowsPlugin::HandleMethodCall(
247265
} else if (method_call.method_name().compare("dispose") == 0) {
248266
player->Dispose();
249267
audioPlayers.erase(playerId);
268+
playerEventChannels.erase(playerId);
269+
playerEventHandlers.erase(playerId);
250270
} else {
251271
result->NotImplemented();
252272
return;
@@ -259,15 +279,17 @@ void AudioplayersWindowsPlugin::CreatePlayer(std::string playerId) {
259279
binaryMessenger, "xyz.luan/audioplayers/events/" + playerId,
260280
&StandardMethodCodec::GetInstance());
261281

262-
auto eventHandler = new EventStreamHandler<>();
263-
auto _obj_stm_handle =
264-
static_cast<StreamHandler<EncodableValue>*>(eventHandler);
265-
std::unique_ptr<StreamHandler<EncodableValue>> _ptr{_obj_stm_handle};
266-
eventChannel->SetStreamHandler(std::move(_ptr));
282+
auto eventHandler = std::make_unique<EventStreamHandler<EncodableValue>>();
283+
EventStreamHandler<EncodableValue>* eventHandlerPtr = eventHandler.get();
284+
eventChannel->SetStreamHandler(std::move(eventHandler));
267285

268286
auto player =
269-
std::make_unique<AudioPlayer>(playerId, methods.get(), eventHandler);
287+
std::make_unique<AudioPlayer>(playerId, methods.get(), eventHandlerPtr);
270288
audioPlayers.insert(std::make_pair(playerId, std::move(player)));
289+
290+
// Keep the event channel and handler alive as long as the plugin/player
291+
// exists
292+
playerEventChannels[playerId] = std::move(eventChannel);
271293
}
272294

273295
AudioPlayer* AudioplayersWindowsPlugin::GetPlayer(std::string playerId) {
@@ -279,18 +301,39 @@ AudioPlayer* AudioplayersWindowsPlugin::GetPlayer(std::string playerId) {
279301
}
280302

281303
void AudioplayersWindowsPlugin::OnGlobalLog(const std::string& message) {
282-
globalEvents->Success(std::make_unique<flutter::EncodableValue>(
283-
flutter::EncodableMap({{flutter::EncodableValue("event"),
284-
flutter::EncodableValue("audio.onLog")},
285-
{flutter::EncodableValue("value"),
286-
flutter::EncodableValue(message)}})));
304+
if (globalEvents) {
305+
globalEvents->Success(std::make_unique<flutter::EncodableValue>(
306+
flutter::EncodableMap({{flutter::EncodableValue("event"),
307+
flutter::EncodableValue("audio.onLog")},
308+
{flutter::EncodableValue("value"),
309+
flutter::EncodableValue(message)}})));
310+
}
287311
}
288312

289313
} // namespace
290314

291315
void AudioplayersWindowsPluginRegisterWithRegistrar(
292316
FlutterDesktopPluginRegistrarRef registrar) {
293-
AudioplayersWindowsPlugin::RegisterWithRegistrar(
317+
if (!registrar) {
318+
std::cerr << "====== Audioplayers: Error - C-API Registrar is NULL!"
319+
<< std::endl;
320+
std::cerr.flush();
321+
return;
322+
}
323+
324+
auto* plugin_registrar =
294325
PluginRegistrarManager::GetInstance()
295-
->GetRegistrar<PluginRegistrarWindows>(registrar));
326+
->GetRegistrar<PluginRegistrarWindows>(registrar);
327+
328+
if (plugin_registrar) {
329+
std::cout << "====== Audioplayers: PluginRegistrarWindows acquired"
330+
<< std::endl;
331+
std::cout.flush();
332+
AudioplayersWindowsPlugin::RegisterWithRegistrar(plugin_registrar);
333+
} else {
334+
std::cerr
335+
<< "====== Audioplayers: Failed to get plugin registrar from manager"
336+
<< std::endl;
337+
std::cerr.flush();
338+
}
296339
}

0 commit comments

Comments
 (0)