|  | // Copyright 2015 The Chromium Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | #ifndef TONIC_DART_LIBRARY_LOADER_H_ | 
|  | #define TONIC_DART_LIBRARY_LOADER_H_ | 
|  |  | 
|  | #include <memory> | 
|  | #include <string> | 
|  | #include <unordered_map> | 
|  | #include <unordered_set> | 
|  | #include <vector> | 
|  |  | 
|  | #include "base/callback_forward.h" | 
|  | #include "base/macros.h" | 
|  | #include "base/memory/weak_ptr.h" | 
|  | #include "dart/runtime/include/dart_api.h" | 
|  |  | 
|  | namespace tonic { | 
|  | class DartDependency; | 
|  | class DartDependencyCatcher; | 
|  | class DartLibraryProvider; | 
|  | class DartState; | 
|  |  | 
|  | // TODO(abarth): This class seems more complicated than it needs to be. Is | 
|  | // there some way of simplifying this system? For example, we have a bunch | 
|  | // of inner classes that could potentially be factored out in some other way. | 
|  | class DartLibraryLoader { | 
|  | public: | 
|  | explicit DartLibraryLoader(DartState* dart_state); | 
|  | ~DartLibraryLoader(); | 
|  |  | 
|  | // TODO(dart): This can be called both on the main thread from application | 
|  | // solates or from the handle watcher isolate thread. | 
|  | static Dart_Handle HandleLibraryTag(Dart_LibraryTag tag, | 
|  | Dart_Handle library, | 
|  | Dart_Handle url); | 
|  |  | 
|  | void LoadLibrary(const std::string& name); | 
|  | void LoadScript(const std::string& name); | 
|  |  | 
|  | void WaitForDependencies( | 
|  | const std::unordered_set<DartDependency*>& dependencies, | 
|  | const base::Closure& callback); | 
|  |  | 
|  | void set_dependency_catcher(DartDependencyCatcher* dependency_catcher) { | 
|  | DCHECK(!dependency_catcher_ || !dependency_catcher); | 
|  | dependency_catcher_ = dependency_catcher; | 
|  | } | 
|  |  | 
|  | DartState* dart_state() const { return dart_state_; } | 
|  |  | 
|  | DartLibraryProvider* library_provider() const { return library_provider_; } | 
|  |  | 
|  | // The |DartLibraryProvider| must outlive the |DartLibraryLoader|. | 
|  | void set_library_provider(DartLibraryProvider* library_provider) { | 
|  | library_provider_ = library_provider; | 
|  | } | 
|  |  | 
|  | bool error_during_loading() const { | 
|  | return error_during_loading_; | 
|  | } | 
|  |  | 
|  | // If one is needed by the embedder, this sets the magic number used to | 
|  | // distinguish snapshots from scripts. If no magic number is set, the | 
|  | // DartLibraryLoader always assumes that the targets of LoadLibrary and | 
|  | // LoadScript are Dart source, and not snapshots. | 
|  | void set_magic_number(const uint8_t* magic_number, intptr_t len) { | 
|  | magic_number_ = magic_number; | 
|  | magic_number_len_ = len; | 
|  | } | 
|  |  | 
|  | private: | 
|  | class Job; | 
|  | class ImportJob; | 
|  | class SourceJob; | 
|  | class DependencyWatcher; | 
|  | class WatcherSignaler; | 
|  |  | 
|  | Dart_Handle Import(Dart_Handle library, Dart_Handle url); | 
|  | Dart_Handle Source(Dart_Handle library, Dart_Handle url); | 
|  | Dart_Handle CanonicalizeURL(Dart_Handle library, Dart_Handle url); | 
|  | void DidCompleteImportJob(ImportJob* job, const std::vector<uint8_t>& buffer); | 
|  | void DidCompleteSourceJob(SourceJob* job, const std::vector<uint8_t>& buffer); | 
|  | void DidFailJob(Job* job); | 
|  |  | 
|  | const uint8_t* SniffForMagicNumber( | 
|  | const uint8_t* text_buffer, intptr_t* buffer_len, bool* is_snapshot); | 
|  |  | 
|  | DartState* dart_state_; | 
|  | DartLibraryProvider* library_provider_; | 
|  | std::unordered_map<std::string, Job*> pending_libraries_; | 
|  | std::unordered_set<std::unique_ptr<Job>> jobs_; | 
|  | std::unordered_set<std::unique_ptr<DependencyWatcher>> dependency_watchers_; | 
|  | DartDependencyCatcher* dependency_catcher_; | 
|  | const uint8_t* magic_number_; | 
|  | intptr_t magic_number_len_; | 
|  | bool error_during_loading_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(DartLibraryLoader); | 
|  | }; | 
|  |  | 
|  | }  // namespace tonic | 
|  |  | 
|  | #endif  // TONIC_DART_LIBRARY_LOADER_H_ |