Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.
 
 
 
 
 
 

107 wiersze
3.1 KiB

  1. //
  2. // Created by yangbin on 2021/11/15.
  3. //
  4. #include <flutter/plugin_registrar.h>
  5. #include <flutter/plugin_registrar_windows.h>
  6. #include <flutter/method_channel.h>
  7. #include <flutter/standard_method_codec.h>
  8. #include "message_channel_plugin.h"
  9. const auto kClientChannelName = "webview_message/client_channel";
  10. namespace {
  11. using FlutterMethodChannel = std::shared_ptr<flutter::MethodChannel<flutter::EncodableValue>>;
  12. class ClientMessageChannelPlugin {
  13. public:
  14. explicit ClientMessageChannelPlugin(FlutterMethodChannel channel);
  15. void InvokeMethod(
  16. const std::string &method,
  17. std::unique_ptr<flutter::EncodableValue> arguments) {
  18. channel_->InvokeMethod(method, std::move(arguments), nullptr);
  19. }
  20. private:
  21. FlutterMethodChannel channel_;
  22. };
  23. class ServerMessageChannelPlugin {
  24. public:
  25. void AddClient(std::shared_ptr<ClientMessageChannelPlugin> client) {
  26. client_set_.insert(std::move(client));
  27. }
  28. void RemoveClient(const std::shared_ptr<ClientMessageChannelPlugin> &client) {
  29. client_set_.erase(client);
  30. }
  31. void DispatchMethodCall(
  32. const flutter::MethodCall<flutter::EncodableValue> &call,
  33. ClientMessageChannelPlugin *client_from);
  34. private:
  35. std::set<std::shared_ptr<ClientMessageChannelPlugin>> client_set_;
  36. };
  37. std::shared_ptr<ServerMessageChannelPlugin> g_server_channel_plugin;
  38. class ClientPluginProxy : public flutter::Plugin {
  39. public:
  40. explicit ClientPluginProxy(std::shared_ptr<ClientMessageChannelPlugin> client)
  41. : client_(std::move(client)) {
  42. assert(g_server_channel_plugin);
  43. g_server_channel_plugin->AddClient(client_);
  44. }
  45. ~ClientPluginProxy() override {
  46. g_server_channel_plugin->RemoveClient(client_);
  47. }
  48. private:
  49. std::shared_ptr<ClientMessageChannelPlugin> client_;
  50. };
  51. }
  52. void RegisterClientMessageChannelPlugin(FlutterDesktopPluginRegistrarRef registrar) {
  53. auto registrar_windows = flutter::PluginRegistrarManager::GetInstance()
  54. ->GetRegistrar<flutter::PluginRegistrarWindows>(registrar);
  55. auto channel = std::make_shared<flutter::MethodChannel<flutter::EncodableValue>>(
  56. registrar_windows->messenger(), kClientChannelName,
  57. &flutter::StandardMethodCodec::GetInstance());
  58. if (!g_server_channel_plugin) {
  59. g_server_channel_plugin = std::make_shared<ServerMessageChannelPlugin>();
  60. }
  61. assert(g_server_channel_plugin);
  62. auto client_plugin = std::make_shared<ClientMessageChannelPlugin>(channel);
  63. registrar_windows->AddPlugin(std::make_unique<ClientPluginProxy>(client_plugin));
  64. }
  65. ClientMessageChannelPlugin::ClientMessageChannelPlugin(
  66. FlutterMethodChannel channel
  67. ) : channel_(std::move(channel)) {
  68. channel_->SetMethodCallHandler([this](const auto &call, auto result) {
  69. if (g_server_channel_plugin) {
  70. g_server_channel_plugin->DispatchMethodCall(call, this);
  71. result->Success();
  72. }
  73. });
  74. }
  75. void ServerMessageChannelPlugin::DispatchMethodCall(
  76. const flutter::MethodCall<> &call,
  77. ClientMessageChannelPlugin *client_from) {
  78. for (const auto &item: client_set_) {
  79. if (item.get() != client_from) {
  80. item->InvokeMethod(
  81. call.method_name(),
  82. std::make_unique<flutter::EncodableValue>(*call.arguments()));
  83. }
  84. }
  85. }