| # Dart Engine | |
| The `include/dart_engine.h` provides additional functions to embed the Dart VM | |
| and to call Dart functions from kernel and AOT snapshots. It is not intended to | |
| be a full-featured API, and should be used together with `dart_api.h`. | |
| It is intended for reusing of existing Dart code in non-Dart programs, and | |
| allows to use Dart snapshots as shared libraries: the caller can start one or | |
| several isolates from Dart snapshots and call Dart functions from it. | |
| Comparing to `dart_api.h` it brings the following: | |
| - Full initialization of Dart VM, including initializing core libraries. | |
| - Easier handling of isolate messages | |
| - Lock-guarded functions to enter/exit isolates. | |
| See examples in `samples/embedder` for usages of the API. | |
| ## Handling isolate messages | |
| In `dart_api.h` there are two possible ways to handle asynchronous | |
| isolate messages: | |
| - `Dart_MessageNotifyCallback`: Users can pass a callback to get | |
| notifications about messages to handle, but handling messages still | |
| requires entering an isolate, entering a scope, calling | |
| `Dart_HandleMessage`, and then leaving a scope and an isolate. | |
| - `Dart_RunLoop`: Users can invoke it on a separate thread, but then they won't | |
| be able to enter isolates from other threads. | |
| As an alternative, `dart_engine.h` provides a simpler function | |
| `DartEngine_HandleMessage`, which encapsulates isolate and scope management, and | |
| it allows to specify per isolate / default message schedulers, which only need | |
| to schedule an execution `DartEngine_HandleMessage` with the right isolate. | |
| Users can create their own `DartEngine_MessageScheduler` struct and pass it to | |
| `DartEngine_SetMessageScheduler` / `DartEngine_SetDefaultMessageScheduler`. See | |
| `samples/embedder/run_timer_async.cc` and `samples/embedder/run_timer.cc` | |
| examples. | |
| ## Entering / leaving isolates | |
| Because engine API uses its own message handling, it is important to use | |
| `DartEngine_AcquireIsolate` / `DartEngine_ReleaseIsolate` instead of | |
| `Dart_EnterIsolate` / `Dart_ExitIsolate`. `DartEngine_AcquireIsolate` blocks | |
| until an isolate can be entered by trying to obtain an internal lock (which is | |
| released by `DartEngine_ReleaseIsolate`), while `Dart_EnterIsolate` crashes if | |
| some other thread has entered the same isolate. |