1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef GIN_MODULES_MODULE_REGISTRY_H_ 6 #define GIN_MODULES_MODULE_REGISTRY_H_ 7 8 #include <list> 9 #include <map> 10 #include <set> 11 #include <string> 12 13 #include "base/callback.h" 14 #include "base/compiler_specific.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "gin/gin_export.h" 17 #include "gin/per_context_data.h" 18 19 namespace gin { 20 21 struct PendingModule; 22 23 // This class implements the Asynchronous Module Definition (AMD) API. 24 // https://github.com/amdjs/amdjs-api/wiki/AMD 25 // 26 // Our implementation isn't complete yet. Missing features: 27 // 1) Built-in support for require, exports, and module. 28 // 2) Path resoltuion in module names. 29 // 30 // For these reasons, we don't have an "amd" property on the "define" 31 // function. The spec says we should only add that property once our 32 // implementation complies with the specification. 33 // 34 class GIN_EXPORT ModuleRegistry : public ContextSupplement { 35 public: 36 typedef base::Callback<void (v8::Handle<v8::Value>)> LoadModuleCallback; 37 38 virtual ~ModuleRegistry(); 39 40 static ModuleRegistry* From(v8::Handle<v8::Context> context); 41 42 static void RegisterGlobals(v8::Isolate* isolate, 43 v8::Handle<v8::ObjectTemplate> templ); 44 45 // The caller must have already entered our context. 46 void AddBuiltinModule(v8::Isolate* isolate, 47 const std::string& id, 48 v8::Handle<v8::ObjectTemplate> templ); 49 50 // The caller must have already entered our context. 51 void AddPendingModule(v8::Isolate* isolate, 52 scoped_ptr<PendingModule> pending); 53 54 void LoadModule(v8::Isolate* isolate, 55 const std::string& id, 56 LoadModuleCallback callback); 57 58 // The caller must have already entered our context. 59 void AttemptToLoadMoreModules(v8::Isolate* isolate); 60 61 const std::set<std::string>& available_modules() const { 62 return available_modules_; 63 } 64 65 const std::set<std::string>& unsatisfied_dependencies() const { 66 return unsatisfied_dependencies_; 67 } 68 69 private: 70 typedef ScopedVector<PendingModule> PendingModuleVector; 71 typedef std::map<std::string, LoadModuleCallback> LoadModuleCallbackMap; 72 73 explicit ModuleRegistry(v8::Isolate* isolate); 74 75 // From ContextSupplement: 76 virtual void Detach(v8::Handle<v8::Context> context) OVERRIDE; 77 78 void Load(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); 79 void RegisterModule(v8::Isolate* isolate, 80 const std::string& id, 81 v8::Handle<v8::Value> module); 82 83 bool CheckDependencies(PendingModule* pending); 84 bool AttemptToLoad(v8::Isolate* isolate, scoped_ptr<PendingModule> pending); 85 86 v8::Handle<v8::Value> GetModule(v8::Isolate* isolate, const std::string& id); 87 88 std::set<std::string> available_modules_; 89 std::set<std::string> unsatisfied_dependencies_; 90 91 LoadModuleCallbackMap waiting_callbacks_; 92 93 PendingModuleVector pending_modules_; 94 v8::Persistent<v8::Object> modules_; 95 96 DISALLOW_COPY_AND_ASSIGN(ModuleRegistry); 97 }; 98 99 } // namespace gin 100 101 #endif // GIN_MODULES_MODULE_REGISTRY_H_ 102