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.
5 #ifndef GIN_MODULES_MODULE_REGISTRY_H_
6 #define GIN_MODULES_MODULE_REGISTRY_H_
13 #include "base/callback.h"
14 #include "base/compiler_specific.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h"
17 #include "base/observer_list.h"
18 #include "gin/gin_export.h"
19 #include "v8/include/v8.h"
23 class ModuleRegistryObserver
;
26 // This class implements the Asynchronous Module Definition (AMD) API.
27 // https://github.com/amdjs/amdjs-api/wiki/AMD
29 // Our implementation isn't complete yet. Missing features:
30 // 1) Built-in support for require, exports, and module.
31 // 2) Path resoltuion in module names.
33 // For these reasons, we don't have an "amd" property on the "define"
34 // function. The spec says we should only add that property once our
35 // implementation complies with the specification.
37 class GIN_EXPORT ModuleRegistry
{
39 typedef base::Callback
<void (v8::Local
<v8::Value
>)> LoadModuleCallback
;
41 virtual ~ModuleRegistry();
43 static ModuleRegistry
* From(v8::Local
<v8::Context
> context
);
45 static void RegisterGlobals(v8::Isolate
* isolate
,
46 v8::Local
<v8::ObjectTemplate
> templ
);
48 // Installs the necessary functions needed for modules.
49 // WARNING: this may execute script in the page.
50 static void InstallGlobals(v8::Isolate
* isolate
, v8::Local
<v8::Object
> obj
);
52 void AddObserver(ModuleRegistryObserver
* observer
);
53 void RemoveObserver(ModuleRegistryObserver
* observer
);
55 // The caller must have already entered our context.
56 void AddBuiltinModule(v8::Isolate
* isolate
, const std::string
& id
,
57 v8::Local
<v8::Value
> module
);
59 // The caller must have already entered our context.
60 void AddPendingModule(v8::Isolate
* isolate
,
61 scoped_ptr
<PendingModule
> pending
);
63 void LoadModule(v8::Isolate
* isolate
,
64 const std::string
& id
,
65 LoadModuleCallback callback
);
67 // The caller must have already entered our context.
68 void AttemptToLoadMoreModules(v8::Isolate
* isolate
);
70 const std::set
<std::string
>& available_modules() const {
71 return available_modules_
;
74 const std::set
<std::string
>& unsatisfied_dependencies() const {
75 return unsatisfied_dependencies_
;
79 typedef ScopedVector
<PendingModule
> PendingModuleVector
;
80 typedef std::multimap
<std::string
, LoadModuleCallback
> LoadModuleCallbackMap
;
82 explicit ModuleRegistry(v8::Isolate
* isolate
);
84 void Load(v8::Isolate
* isolate
, scoped_ptr
<PendingModule
> pending
);
85 void RegisterModule(v8::Isolate
* isolate
,
86 const std::string
& id
,
87 v8::Local
<v8::Value
> module
);
89 bool CheckDependencies(PendingModule
* pending
);
90 bool AttemptToLoad(v8::Isolate
* isolate
, scoped_ptr
<PendingModule
> pending
);
92 v8::Local
<v8::Value
> GetModule(v8::Isolate
* isolate
, const std::string
& id
);
94 std::set
<std::string
> available_modules_
;
95 std::set
<std::string
> unsatisfied_dependencies_
;
97 LoadModuleCallbackMap waiting_callbacks_
;
99 PendingModuleVector pending_modules_
;
100 v8::Persistent
<v8::Object
> modules_
;
102 ObserverList
<ModuleRegistryObserver
> observer_list_
;
104 DISALLOW_COPY_AND_ASSIGN(ModuleRegistry
);
109 #endif // GIN_MODULES_MODULE_REGISTRY_H_