mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Allow specification of std::functions as native entrypoints from Dart code. (flutter/engine#8309)
This allows for the specification of std::functions (using EmbedderContext::NativeEntry) with their captures as native entrypoints. Earlier, only C functions we allowed which meant that there were no captures and assertions had to use globals which could introduce bugs when used with gtest_repeat.
This commit is contained in:
parent
1ca8afa1bc
commit
07f506f752
@ -6,3 +6,15 @@ void customEntrypoint() {
|
||||
}
|
||||
|
||||
void sayHiFromCustomEntrypoint() native "SayHiFromCustomEntrypoint";
|
||||
|
||||
|
||||
@pragma('vm:entry-point')
|
||||
void customEntrypoint1() {
|
||||
sayHiFromCustomEntrypoint1();
|
||||
sayHiFromCustomEntrypoint2();
|
||||
sayHiFromCustomEntrypoint3();
|
||||
}
|
||||
|
||||
void sayHiFromCustomEntrypoint1() native "SayHiFromCustomEntrypoint1";
|
||||
void sayHiFromCustomEntrypoint2() native "SayHiFromCustomEntrypoint2";
|
||||
void sayHiFromCustomEntrypoint3() native "SayHiFromCustomEntrypoint3";
|
||||
|
||||
@ -16,11 +16,23 @@
|
||||
#include "flutter/shell/platform/embedder/embedder.h"
|
||||
#include "flutter/shell/platform/embedder/tests/embedder_test_resolver.h"
|
||||
|
||||
#define CREATE_NATIVE_ENTRY(native_entry) \
|
||||
({ \
|
||||
static ::shell::testing::EmbedderContext::NativeEntry closure; \
|
||||
static Dart_NativeFunction entrypoint = [](Dart_NativeArguments args) { \
|
||||
closure(args); \
|
||||
}; \
|
||||
closure = (native_entry); \
|
||||
entrypoint; \
|
||||
})
|
||||
|
||||
namespace shell {
|
||||
namespace testing {
|
||||
|
||||
class EmbedderContext {
|
||||
public:
|
||||
using NativeEntry = std::function<void(Dart_NativeArguments)>;
|
||||
|
||||
EmbedderContext(std::string assets_path = "");
|
||||
|
||||
~EmbedderContext();
|
||||
|
||||
@ -59,5 +59,45 @@ TEST_F(EmbedderTest, CanInvokeCustomEntrypoint) {
|
||||
ASSERT_TRUE(engine.is_valid());
|
||||
}
|
||||
|
||||
TEST_F(EmbedderTest, CanInvokeCustomEntrypointMacro) {
|
||||
auto& context = GetEmbedderContext();
|
||||
|
||||
fml::AutoResetWaitableEvent latch1;
|
||||
fml::AutoResetWaitableEvent latch2;
|
||||
fml::AutoResetWaitableEvent latch3;
|
||||
|
||||
// Can be defined separately.
|
||||
auto entry1 = [&latch1](Dart_NativeArguments args) {
|
||||
FML_LOG(ERROR) << "In Callback 1";
|
||||
latch1.Signal();
|
||||
};
|
||||
auto native_entry1 = CREATE_NATIVE_ENTRY(entry1);
|
||||
context.AddNativeCallback("SayHiFromCustomEntrypoint1", native_entry1);
|
||||
|
||||
// Can be wrapped in in the args.
|
||||
auto entry2 = [&latch2](Dart_NativeArguments args) {
|
||||
FML_LOG(ERROR) << "In Callback 2";
|
||||
latch2.Signal();
|
||||
};
|
||||
context.AddNativeCallback("SayHiFromCustomEntrypoint2",
|
||||
CREATE_NATIVE_ENTRY(entry2));
|
||||
|
||||
// Everything can be inline.
|
||||
context.AddNativeCallback(
|
||||
"SayHiFromCustomEntrypoint3",
|
||||
CREATE_NATIVE_ENTRY([&latch3](Dart_NativeArguments args) {
|
||||
FML_LOG(ERROR) << "In Callback 3";
|
||||
latch3.Signal();
|
||||
}));
|
||||
|
||||
EmbedderConfigBuilder builder(context);
|
||||
builder.SetDartEntrypoint("customEntrypoint1");
|
||||
auto engine = builder.LaunchEngine();
|
||||
latch1.Wait();
|
||||
latch2.Wait();
|
||||
latch3.Wait();
|
||||
ASSERT_TRUE(engine.is_valid());
|
||||
}
|
||||
|
||||
} // namespace testing
|
||||
} // namespace shell
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user