Skip to content

Commit

Permalink
Allow specification of std::functions as native entrypoints from Dart…
Browse files Browse the repository at this point in the history
… code. (#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.
  • Loading branch information
chinmaygarde committed Mar 26, 2019
1 parent 51f23fe commit 400a86a
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 0 deletions.
12 changes: 12 additions & 0 deletions shell/platform/embedder/fixtures/simple_main.dart
Expand Up @@ -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";
12 changes: 12 additions & 0 deletions shell/platform/embedder/tests/embedder_context.h
Expand Up @@ -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();
Expand Down
40 changes: 40 additions & 0 deletions shell/platform/embedder/tests/embedder_unittests.cc
Expand Up @@ -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

0 comments on commit 400a86a

Please sign in to comment.