Unverified Commit 7eb1035a authored by stuartmorgan's avatar stuartmorgan Committed by GitHub

Restructure Windows plugin template (#93511)

parent 8a95d42b
...@@ -12,12 +12,18 @@ project(${PROJECT_NAME} LANGUAGES CXX) ...@@ -12,12 +12,18 @@ project(${PROJECT_NAME} LANGUAGES CXX)
# not be changed # not be changed
set(PLUGIN_NAME "{{projectName}}_plugin") set(PLUGIN_NAME "{{projectName}}_plugin")
# Any new source files that you add to the plugin should be added here.
list(APPEND PLUGIN_SOURCES
"{{pluginClassSnakeCase}}.cpp"
"{{pluginClassSnakeCase}}.h"
)
# Define the plugin library target. Its name must not be changed (see comment # Define the plugin library target. Its name must not be changed (see comment
# on PLUGIN_NAME above). # on PLUGIN_NAME above).
#
# Any new source files that you add to the plugin should be added here.
add_library(${PLUGIN_NAME} SHARED add_library(${PLUGIN_NAME} SHARED
"{{pluginClassSnakeCase}}.cpp" "include/{{projectName}}/{{pluginClassSnakeCase}}_c_api.h"
"{{pluginClassSnakeCase}}_c_api.cpp"
${PLUGIN_SOURCES}
) )
# Apply a standard set of build settings that are configured in the # Apply a standard set of build settings that are configured in the
......
#ifndef FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_ #ifndef FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_C_API_H_
#define FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_ #define FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_C_API_H_
#include <flutter_plugin_registrar.h> #include <flutter_plugin_registrar.h>
...@@ -13,11 +13,11 @@ ...@@ -13,11 +13,11 @@
extern "C" { extern "C" {
#endif #endif
FLUTTER_PLUGIN_EXPORT void {{pluginClass}}RegisterWithRegistrar( FLUTTER_PLUGIN_EXPORT void {{pluginClass}}CApiRegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar); FlutterDesktopPluginRegistrarRef registrar);
#if defined(__cplusplus) #if defined(__cplusplus)
} // extern "C" } // extern "C"
#endif #endif
#endif // FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_ #endif // FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_C_API_H_
#include "include/{{projectName}}/{{pluginClassSnakeCase}}.h" #include "{{pluginClassSnakeCase}}.h"
// This must be included before many other Windows headers. // This must be included before many other Windows headers.
#include <windows.h> #include <windows.h>
...@@ -10,26 +10,10 @@ ...@@ -10,26 +10,10 @@
#include <flutter/plugin_registrar_windows.h> #include <flutter/plugin_registrar_windows.h>
#include <flutter/standard_method_codec.h> #include <flutter/standard_method_codec.h>
#include <map>
#include <memory> #include <memory>
#include <sstream> #include <sstream>
namespace { namespace {{projectName}} {
class {{pluginClass}} : public flutter::Plugin {
public:
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
{{pluginClass}}();
virtual ~{{pluginClass}}();
private:
// Called when a method is called on this plugin's channel from Dart.
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue> &method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
};
// static // static
void {{pluginClass}}::RegisterWithRegistrar( void {{pluginClass}}::RegisterWithRegistrar(
...@@ -72,11 +56,4 @@ void {{pluginClass}}::HandleMethodCall( ...@@ -72,11 +56,4 @@ void {{pluginClass}}::HandleMethodCall(
} }
} }
} // namespace } // namespace {{projectName}}
void {{pluginClass}}RegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar) {
{{pluginClass}}::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}
#ifndef FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
#define FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
#include <flutter/method_channel.h>
#include <flutter/plugin_registrar_windows.h>
#include <memory>
namespace {{projectName}} {
class {{pluginClass}} : public flutter::Plugin {
public:
static void RegisterWithRegistrar(flutter::PluginRegistrarWindows *registrar);
{{pluginClass}}();
virtual ~{{pluginClass}}();
// Disallow copy and assign.
{{pluginClass}}(const {{pluginClass}}&) = delete;
{{pluginClass}}& operator=(const {{pluginClass}}&) = delete;
private:
// Called when a method is called on this plugin's channel from Dart.
void HandleMethodCall(
const flutter::MethodCall<flutter::EncodableValue> &method_call,
std::unique_ptr<flutter::MethodResult<flutter::EncodableValue>> result);
};
} // namespace {{projectName}}
#endif // FLUTTER_PLUGIN_{{pluginClassCapitalSnakeCase}}_H_
#include "include/{{projectName}}/{{pluginClassSnakeCase}}_c_api.h"
#include <flutter/plugin_registrar_windows.h>
#include "{{pluginClassSnakeCase}}.h"
void {{pluginClass}}CApiRegisterWithRegistrar(
FlutterDesktopPluginRegistrarRef registrar) {
{{projectName}}::{{pluginClass}}::RegisterWithRegistrar(
flutter::PluginRegistrarManager::GetInstance()
->GetRegistrar<flutter::PluginRegistrarWindows>(registrar));
}
...@@ -112,7 +112,7 @@ flutter: ...@@ -112,7 +112,7 @@ flutter:
{{/macos}} {{/macos}}
{{#windows}} {{#windows}}
windows: windows:
pluginClass: {{pluginClass}} pluginClass: {{pluginClass}}CApi
{{/windows}} {{/windows}}
{{#web}} {{#web}}
web: web:
......
...@@ -333,8 +333,10 @@ ...@@ -333,8 +333,10 @@
"templates/plugin/README.md.tmpl", "templates/plugin/README.md.tmpl",
"templates/plugin/test/projectName_test.dart.tmpl", "templates/plugin/test/projectName_test.dart.tmpl",
"templates/plugin/windows.tmpl/CMakeLists.txt.tmpl", "templates/plugin/windows.tmpl/CMakeLists.txt.tmpl",
"templates/plugin/windows.tmpl/include/projectName.tmpl/pluginClassSnakeCase.h.tmpl", "templates/plugin/windows.tmpl/include/projectName.tmpl/pluginClassSnakeCase_c_api.h.tmpl",
"templates/plugin/windows.tmpl/pluginClassSnakeCase.cpp.tmpl", "templates/plugin/windows.tmpl/pluginClassSnakeCase.cpp.tmpl",
"templates/plugin/windows.tmpl/pluginClassSnakeCase.h.tmpl",
"templates/plugin/windows.tmpl/pluginClassSnakeCase_c_api.cpp.tmpl",
"templates/plugin/lib/projectName_web.dart.tmpl", "templates/plugin/lib/projectName_web.dart.tmpl",
"templates/plugin_ffi/android.tmpl/build.gradle.tmpl", "templates/plugin_ffi/android.tmpl/build.gradle.tmpl",
......
...@@ -1063,7 +1063,7 @@ void main() { ...@@ -1063,7 +1063,7 @@ void main() {
isNot(exists)); isNot(exists));
validatePubspecForPlugin(projectDir: projectDir.absolute.path, expectedPlatforms: const <String>[ validatePubspecForPlugin(projectDir: projectDir.absolute.path, expectedPlatforms: const <String>[
'windows' 'windows'
], pluginClass: 'FlutterProjectPlugin', ], pluginClass: 'FlutterProjectPluginCApi',
unexpectedPlatforms: <String>['some_platform']); unexpectedPlatforms: <String>['some_platform']);
expect(logger.errorText, isNot(contains(_kNoPlatformsMessage))); expect(logger.errorText, isNot(contains(_kNoPlatformsMessage)));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
...@@ -2539,21 +2539,33 @@ void main() { ...@@ -2539,21 +2539,33 @@ void main() {
final Directory platformDir = projectDir.childDirectory('windows'); final Directory platformDir = projectDir.childDirectory('windows');
const String classFilenameBase = 'foo_bar_baz_plugin'; const String classFilenameBase = 'foo_bar_baz_plugin';
const String headerName = '$classFilenameBase.h'; const String cApiHeaderName = '${classFilenameBase}_c_api.h';
final File headerFile = platformDir const String pluginClassHeaderName = '$classFilenameBase.h';
final File cApiHeaderFile = platformDir
.childDirectory('include') .childDirectory('include')
.childDirectory(projectName) .childDirectory(projectName)
.childFile(headerName); .childFile(cApiHeaderName);
final File implFile = platformDir.childFile('$classFilenameBase.cpp'); final File cApiImplFile = platformDir.childFile('${classFilenameBase}_c_api.cpp');
final File pluginClassHeaderFile = platformDir.childFile(pluginClassHeaderName);
final File pluginClassImplFile = platformDir.childFile('$classFilenameBase.cpp');
// Ensure that the files have the right names. // Ensure that the files have the right names.
expect(headerFile, exists); expect(cApiHeaderFile, exists);
expect(implFile, exists); expect(cApiImplFile, exists);
// Ensure that the include is correct. expect(pluginClassHeaderFile, exists);
expect(implFile.readAsStringSync(), contains(headerName)); expect(pluginClassImplFile, exists);
// Ensure that the includes are correct.
expect(cApiImplFile.readAsLinesSync(), containsAllInOrder(<Matcher>[
contains('#include "include/$projectName/$cApiHeaderName"'),
contains('#include "$pluginClassHeaderName"'),
]));
expect(pluginClassImplFile.readAsLinesSync(), contains('#include "$pluginClassHeaderName"'));
// Ensure that the plugin target name matches the post-processed version. // Ensure that the plugin target name matches the post-processed version.
// Ensure that the CMake file has the right target and source values. // Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync(); final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cpp"')); expect(cmakeContents, contains('"$classFilenameBase.cpp"'));
expect(cmakeContents, contains('"$classFilenameBase.h"'));
expect(cmakeContents, contains('"${classFilenameBase}_c_api.cpp"'));
expect(cmakeContents, contains('"include/$projectName/${classFilenameBase}_c_api.h"'));
expect(cmakeContents, contains('set(PLUGIN_NAME "foo_BarBaz_plugin")')); expect(cmakeContents, contains('set(PLUGIN_NAME "foo_BarBaz_plugin")'));
}, overrides: <Type, Generator>{ }, overrides: <Type, Generator>{
FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true), FeatureFlags: () => TestFeatureFlags(isWindowsEnabled: true),
...@@ -2608,17 +2620,26 @@ void main() { ...@@ -2608,17 +2620,26 @@ void main() {
// If the project already ends in _plugin, it shouldn't be added again. // If the project already ends in _plugin, it shouldn't be added again.
const String classFilenameBase = projectName; const String classFilenameBase = projectName;
const String headerName = '$classFilenameBase.h'; const String cApiHeaderName = '${classFilenameBase}_c_api.h';
final File headerFile = platformDir const String pluginClassHeaderName = '$classFilenameBase.h';
final File cApiHeaderFile = platformDir
.childDirectory('include') .childDirectory('include')
.childDirectory(projectName) .childDirectory(projectName)
.childFile(headerName); .childFile(cApiHeaderName);
final File implFile = platformDir.childFile('$classFilenameBase.cpp'); final File cApiImplFile = platformDir.childFile('${classFilenameBase}_c_api.cpp');
final File pluginClassHeaderFile = platformDir.childFile(pluginClassHeaderName);
final File pluginClassImplFile = platformDir.childFile('$classFilenameBase.cpp');
// Ensure that the files have the right names. // Ensure that the files have the right names.
expect(headerFile, exists); expect(cApiHeaderFile, exists);
expect(implFile, exists); expect(cApiImplFile, exists);
// Ensure that the include is correct. expect(pluginClassHeaderFile, exists);
expect(implFile.readAsStringSync(), contains(headerName)); expect(pluginClassImplFile, exists);
// Ensure that the includes are correct.
expect(cApiImplFile.readAsLinesSync(), containsAllInOrder(<Matcher>[
contains('#include "include/$projectName/$cApiHeaderName"'),
contains('#include "$pluginClassHeaderName"'),
]));
expect(pluginClassImplFile.readAsLinesSync(), contains('#include "$pluginClassHeaderName"'));
// Ensure that the CMake file has the right target and source values. // Ensure that the CMake file has the right target and source values.
final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync(); final String cmakeContents = platformDir.childFile('CMakeLists.txt').readAsStringSync();
expect(cmakeContents, contains('"$classFilenameBase.cpp"')); expect(cmakeContents, contains('"$classFilenameBase.cpp"'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment