Skip to content

Commit 737a086

Browse files
[linux/windows] Add FlutterWindowController
Creates an initial C++ object as the primary intaction point for the embedder calls. This provides a simpler API surface than embedder.h, and folds in some common code (e.g., error logging). This also serves to insulate clients from the embedder.h API layer, so that future incremental changes done for google#230 will cause less churn for embedders.
1 parent 0adf81e commit 737a086

File tree

5 files changed

+193
-34
lines changed

5 files changed

+193
-34
lines changed

example/linux_fde/flutter_embedder_example.cc

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
#include <menubar/menubar_plugin.h>
2525

2626
#ifdef USE_FLATTENED_INCLUDES
27-
#include <flutter_desktop_embedding/embedder.h>
27+
#include <flutter_desktop_embedding/flutter_window_controller.h>
2828
#else
29-
#include <flutter_desktop_embedding/glfw/embedder.h>
29+
#include <flutter_desktop_embedding/glfw/flutter_window_controller.h>
3030
#endif
3131

3232
namespace {
@@ -53,11 +53,6 @@ std::string GetExecutableDirectory() {
5353
} // namespace
5454

5555
int main(int argc, char **argv) {
56-
if (!flutter_desktop_embedding::FlutterInit()) {
57-
std::cerr << "Unable to init GLFW; exiting." << std::endl;
58-
return EXIT_FAILURE;
59-
}
60-
6156
// Resources are located relative to the executable.
6257
std::string base_directory = GetExecutableDirectory();
6358
if (base_directory.empty()) {
@@ -72,27 +67,27 @@ int main(int argc, char **argv) {
7267
#ifdef NDEBUG
7368
arguments.push_back("--disable-dart-asserts");
7469
#endif
70+
71+
flutter_desktop_embedding::FlutterWindowController flutter_controller(
72+
icu_data_path);
73+
7574
// Start the engine.
76-
auto window = flutter_desktop_embedding::CreateFlutterWindow(
77-
640, 480, assets_path, icu_data_path, arguments);
78-
if (window == nullptr) {
79-
flutter_desktop_embedding::FlutterTerminate();
80-
std::cerr << "Unable to create Flutter window; exiting." << std::endl;
75+
if (!flutter_controller.CreateWindow(640, 480, assets_path, arguments)) {
8176
return EXIT_FAILURE;
8277
}
8378

8479
// Register any native plugins.
8580
plugins_menubar::MenubarPlugin::RegisterWithRegistrar(
86-
flutter_desktop_embedding::GetRegistrarForPlugin(
87-
window, "plugins_menubar::MenubarPlugin"));
81+
flutter_controller.GetRegistrarForPlugin(
82+
"plugins_menubar::MenubarPlugin"));
8883
plugins_color_panel::ColorPanelPlugin::RegisterWithRegistrar(
89-
flutter_desktop_embedding::GetRegistrarForPlugin(
90-
window, "plugins_color_panel::ColorPanelPlugin"));
84+
flutter_controller.GetRegistrarForPlugin(
85+
"plugins_color_panel::ColorPanelPlugin"));
9186
plugins_file_chooser::FileChooserPlugin::RegisterWithRegistrar(
92-
flutter_desktop_embedding::GetRegistrarForPlugin(
93-
window, "plugins_file_chooser::FileChooserPlugin"));
87+
flutter_controller.GetRegistrarForPlugin(
88+
"plugins_file_chooser::FileChooserPlugin"));
9489

95-
flutter_desktop_embedding::FlutterWindowLoop(window);
96-
glfwTerminate();
90+
// Run until the window is closed.
91+
flutter_controller.RunEventLoop();
9792
return EXIT_SUCCESS;
9893
}

example/windows_fde/flutter_embedder_example.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,32 +13,32 @@
1313
// limitations under the License.
1414

1515
#include <iostream>
16+
#include <string>
1617
#include <vector>
1718

18-
#include "flutter_desktop_embedding/glfw/embedder.h"
19+
#include "flutter_desktop_embedding/glfw/flutter_window_controller.h"
1920

2021
int main(int argc, char **argv) {
21-
if (!flutter_desktop_embedding::FlutterInit()) {
22-
std::cerr << "Unable to init GLFW; exiting." << std::endl;
23-
return EXIT_FAILURE;
24-
}
22+
// TODO: Make paths relative to the executable so it can be run from anywhere.
23+
std::string assets_path =
24+
"..\\..\\example\\flutter_app\\build\\flutter_assets";
25+
std::string icu_data_path =
26+
"..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat";
27+
2528
// Arguments for the Flutter Engine.
2629
std::vector<std::string> arguments;
2730
#ifndef _DEBUG
2831
arguments.push_back("--disable-dart-asserts");
2932
#endif
33+
flutter_desktop_embedding::FlutterWindowController flutter_controller(
34+
icu_data_path);
35+
3036
// Start the engine.
31-
// TODO: Make paths relative to the executable so it can be run from anywhere.
32-
auto window = flutter_desktop_embedding::CreateFlutterWindow(
33-
640, 480, "..\\build\\flutter_assets",
34-
"..\\..\\library\\windows\\dependencies\\engine\\icudtl.dat", arguments);
35-
if (window == nullptr) {
36-
flutter_desktop_embedding::FlutterTerminate();
37-
std::cerr << "Unable to create Flutter window; exiting." << std::endl;
37+
if (!flutter_controller.CreateWindow(640, 480, assets_path, arguments)) {
3838
return EXIT_FAILURE;
3939
}
4040

41-
flutter_desktop_embedding::FlutterWindowLoop(window);
42-
flutter_desktop_embedding::FlutterTerminate();
41+
// Run until the window is closed.
42+
flutter_controller.RunEventLoop();
4343
return EXIT_SUCCESS;
4444
}

library/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,11 @@ published_shared_library("flutter_embedder") {
2121
if (is_linux || is_win) {
2222
public = [
2323
"include/flutter_desktop_embedding/glfw/embedder.h",
24+
"include/flutter_desktop_embedding/glfw/flutter_window_controller.h",
2425
]
2526
sources = [
2627
"common/glfw/embedder.cc",
28+
"common/glfw/flutter_window_controller.cc",
2729
"common/glfw/key_event_handler.cc",
2830
"common/glfw/key_event_handler.h",
2931
"common/glfw/keyboard_hook_handler.h",
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "library/include/flutter_desktop_embedding/glfw/flutter_window_controller.h"
16+
17+
#include <iostream>
18+
19+
namespace flutter_desktop_embedding {
20+
21+
FlutterWindowController::FlutterWindowController(std::string &icu_data_path)
22+
: icu_data_path_(icu_data_path) {
23+
init_succeeded_ = FlutterInit();
24+
}
25+
26+
FlutterWindowController::~FlutterWindowController() {
27+
if (init_succeeded_) {
28+
FlutterTerminate();
29+
}
30+
}
31+
32+
bool FlutterWindowController::CreateWindow(
33+
size_t width, size_t height, const std::string &assets_path,
34+
const std::vector<std::string> &arguments) {
35+
if (!init_succeeded_) {
36+
std::cerr << "Could not create window; FlutterInit failed." << std::endl;
37+
return false;
38+
}
39+
40+
if (window_) {
41+
std::cerr << "Only one Flutter window can exist at a time." << std::endl;
42+
return false;
43+
}
44+
45+
window_ = CreateFlutterWindow(width, height, assets_path, icu_data_path_,
46+
arguments);
47+
if (!window_) {
48+
std::cerr << "Failed to create window." << std::endl;
49+
return false;
50+
}
51+
return true;
52+
}
53+
54+
PluginRegistrar *FlutterWindowController::GetRegistrarForPlugin(
55+
const std::string &plugin_name) {
56+
if (!window_) {
57+
return nullptr;
58+
}
59+
return flutter_desktop_embedding::GetRegistrarForPlugin(window_, plugin_name);
60+
}
61+
62+
void FlutterWindowController::RunEventLoop() {
63+
if (window_) {
64+
FlutterWindowLoop(window_);
65+
}
66+
}
67+
68+
} // namespace flutter_desktop_embedding
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// Copyright 2019 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#ifndef LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_
16+
#define LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_
17+
18+
#include <string>
19+
#include <vector>
20+
21+
#include "embedder.h"
22+
23+
#ifdef USE_FLATTENED_INCLUDES
24+
#include "fde_export.h"
25+
#include "plugin_registrar.h"
26+
#else
27+
#include "../fde_export.h"
28+
#include "../plugin_registrar.h"
29+
#endif
30+
31+
namespace flutter_desktop_embedding {
32+
33+
// A controller for a window displaying Flutter content.
34+
//
35+
// This is the primary wrapper class for the desktop embedding C API.
36+
// If you use this class, you should not call any of the setup or teardown
37+
// methods in embedder.h directly, as this class will do that internally.
38+
//
39+
// This class is a singleton, as Flutter does not support multiple engines in
40+
// one process, or multiple views in one engine.
41+
//
42+
// Note: This is an early implementation (using GLFW internally) which
43+
// requires control of the application's event loop, and is thus useful
44+
// primarily for building a simple one-window shell hosting a Flutter
45+
// application. The final implementation and API will be very different.
46+
class FDE_EXPORT FlutterWindowController {
47+
public:
48+
// There must be only one instance of this class in an application at any
49+
// given time, as Flutter does not support multiple engines in one process,
50+
// or multiple views in one engine.
51+
explicit FlutterWindowController(std::string &icu_data_path);
52+
53+
~FlutterWindowController();
54+
55+
// Creates and displays a window for displaying Flutter content.
56+
//
57+
// The |assets_path| is the path to the flutter_assets folder for the Flutter
58+
// application to be run. |icu_data_path| is the path to the icudtl.dat file
59+
// for the version of Flutter you are using.
60+
//
61+
// The |arguments| are passed to the Flutter engine. See:
62+
// https://github.com/flutter/engine/blob/master/shell/common/switches.h for
63+
// for details. Not all arguments will apply to embedding mode.
64+
//
65+
// There must be only one instance of this class in an application at any
66+
// given time, as Flutter does not support multiple engines in one process,
67+
// or multiple views in one engine.
68+
bool CreateWindow(size_t width, size_t height, const std::string &assets_path,
69+
const std::vector<std::string> &arguments);
70+
71+
// Returns the PluginRegistrar to register a plugin with the given name.
72+
//
73+
// The name must be unique across the application, so the recommended approach
74+
// is to use the fully namespace-qualified name of the plugin class.
75+
PluginRegistrar *GetRegistrarForPlugin(const std::string &plugin_name);
76+
77+
// Loops on Flutter window events until termination.
78+
void RunEventLoop();
79+
80+
private:
81+
// The path to the ICU data file. Set at creation time since it is the same
82+
// for any window created.
83+
std::string icu_data_path_;
84+
85+
// Whether or not FlutterInit succeeded at creation time.
86+
bool init_succeeded_ = false;
87+
88+
// The curent Flutter window, if any.
89+
GLFWwindow *window_ = nullptr;
90+
};
91+
92+
} // namespace flutter_desktop_embedding
93+
94+
#endif // LIBRARY_INCLUDE_FLUTTER_DESKTOP_EMBEDDING_GLFW_FLUTTER_WINDOW_CONTROLLER_H_

0 commit comments

Comments
 (0)