Home | History | Annotate | Download | only in modules
      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