|  | // Copyright 2013 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 GIN_MODULES_MODULE_REGISTRY_H_ | 
|  | #define GIN_MODULES_MODULE_REGISTRY_H_ | 
|  |  | 
|  | #include <list> | 
|  | #include <map> | 
|  | #include <set> | 
|  | #include <string> | 
|  |  | 
|  | #include "base/callback.h" | 
|  | #include "base/compiler_specific.h" | 
|  | #include "base/memory/scoped_ptr.h" | 
|  | #include "base/memory/scoped_vector.h" | 
|  | #include "base/observer_list.h" | 
|  | #include "gin/gin_export.h" | 
|  | #include "v8/include/v8.h" | 
|  |  | 
|  | namespace gin { | 
|  |  | 
|  | class ModuleRegistryObserver; | 
|  | struct PendingModule; | 
|  |  | 
|  | // This class implements the Asynchronous Module Definition (AMD) API. | 
|  | // https://github.com/amdjs/amdjs-api/wiki/AMD | 
|  | // | 
|  | // Our implementation isn't complete yet. Missing features: | 
|  | //   1) Built-in support for require, exports, and module. | 
|  | //   2) Path resoltuion in module names. | 
|  | // | 
|  | // For these reasons, we don't have an "amd" property on the "define" | 
|  | // function. The spec says we should only add that property once our | 
|  | // implementation complies with the specification. | 
|  | // | 
|  | class GIN_EXPORT ModuleRegistry { | 
|  | public: | 
|  | typedef base::Callback<void (v8::Handle<v8::Value>)> LoadModuleCallback; | 
|  |  | 
|  | virtual ~ModuleRegistry(); | 
|  |  | 
|  | static ModuleRegistry* From(v8::Handle<v8::Context> context); | 
|  |  | 
|  | static void RegisterGlobals(v8::Isolate* isolate, | 
|  | v8::Handle<v8::ObjectTemplate> templ); | 
|  |  | 
|  | // Installs the necessary functions needed for modules. | 
|  | // WARNING: this may execute script in the page. | 
|  | static void InstallGlobals(v8::Isolate* isolate, v8::Handle<v8::Object> obj); | 
|  |  | 
|  | void AddObserver(ModuleRegistryObserver* observer); | 
|  | void RemoveObserver(ModuleRegistryObserver* observer); | 
|  |  | 
|  | // The caller must have already entered our context. | 
|  | void AddBuiltinModule(v8::Isolate* isolate, const std::string& id, | 
|  | v8::Handle<v8::Value> module); | 
|  |  | 
|  | // The caller must have already entered our context. | 
|  | void AddPendingModule(v8::Isolate* isolate, | 
|  | scoped_ptr<PendingModule> pending); | 
|  |  | 
|  | void LoadModule(v8::Isolate* isolate, | 
|  | const std::string& id, | 
|  | LoadModuleCallback callback); | 
|  |  | 
|  | // The caller must have already entered our context. | 
|  | void AttemptToLoadMoreModules(v8::Isolate* isolate); | 
|  |  | 
|  | const std::set<std::string>& available_modules() const { | 
|  | return available_modules_; | 
|  | } | 
|  |  | 
|  | const std::set<std::string>& unsatisfied_dependencies() const { | 
|  | return unsatisfied_dependencies_; | 
|  | } | 
|  |  | 
|  | private: | 
|  | typedef ScopedVector<PendingModule> PendingModuleVector; | 
|  | typedef std::multimap<std::string, LoadModuleCallback> LoadModuleCallbackMap; | 
|  |  | 
|  | explicit ModuleRegistry(v8::Isolate* isolate); | 
|  |  | 
|  | void Load(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); | 
|  | void RegisterModule(v8::Isolate* isolate, | 
|  | const std::string& id, | 
|  | v8::Handle<v8::Value> module); | 
|  |  | 
|  | bool CheckDependencies(PendingModule* pending); | 
|  | bool AttemptToLoad(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); | 
|  |  | 
|  | v8::Handle<v8::Value> GetModule(v8::Isolate* isolate, const std::string& id); | 
|  |  | 
|  | std::set<std::string> available_modules_; | 
|  | std::set<std::string> unsatisfied_dependencies_; | 
|  |  | 
|  | LoadModuleCallbackMap waiting_callbacks_; | 
|  |  | 
|  | PendingModuleVector pending_modules_; | 
|  | v8::Persistent<v8::Object> modules_; | 
|  |  | 
|  | ObserverList<ModuleRegistryObserver> observer_list_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(ModuleRegistry); | 
|  | }; | 
|  |  | 
|  | }  // namespace gin | 
|  |  | 
|  | #endif  // GIN_MODULES_MODULE_REGISTRY_H_ |