forked from mosaicdao/mosaic.js
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathinstanceComposer.js
90 lines (77 loc) · 2.55 KB
/
instanceComposer.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
'use strict';
const InstanceComposer = function(configStrategy) {
this.configStrategy = configStrategy || {};
this.instanceMap = {};
this.shadowedClassMap = {};
};
//Some static properties & methods.
const composerMap = {};
const instanceComposerMethodName = 'ic';
const shadowMap = {};
InstanceComposer.register = function(
ClassConstructor,
getterMethodName,
mustRetainInstance
) {
if ( InstanceComposer.prototype[getterMethodName] ) {
console.trace('Duplicate Getter Method name', getterMethodName);
throw 'Duplicate Getter Method Name ';
}
composerMap[getterMethodName] = ClassConstructor;
InstanceComposer.prototype[getterMethodName] = function() {
const oThis = this; //this refers to instance of InstanceComposer.
let _instance;
if (mustRetainInstance) {
_instance = oThis.instanceMap[getterMethodName];
if (!_instance) {
_instance = new ClassConstructor(oThis.configStrategy, oThis);
oThis.instanceMap[getterMethodName] = _instance;
}
_instance[instanceComposerMethodName] = function() {
return oThis;
};
} else {
_instance = new ClassConstructor(oThis.configStrategy, oThis);
_instance[instanceComposerMethodName] = function() {
return oThis;
};
}
return _instance;
};
};
InstanceComposer.registerShadowableClass = function(ClassConstructor, classGetterName) {
if (composerMap.hasOwnProperty(classGetterName) || shadowMap.hasOwnProperty(classGetterName)) {
console.trace('Duplicate Getter Method name', classGetterName);
throw 'Duplicate Getter Method Name.';
}
shadowMap[classGetterName] = ClassConstructor;
InstanceComposer.prototype[classGetterName] = function() {
const oThis = this; //this refers to instance of InstanceComposer.
let _shadowedClass;
_shadowedClass = oThis.shadowedClassMap[classGetterName];
if (!_shadowedClass) {
oThis.shadowedClassMap[classGetterName] = _shadowedClass = oThis.createShadowClass(ClassConstructor);
}
return _shadowedClass;
};
};
InstanceComposer.prototype = {
configStrategy: null,
instanceMap: null,
shadowedClassMap: null,
createShadowClass: function(ClassConstructor) {
const oThis = this; //this refers to instance of InstanceComposer.
class DerivedClass extends ClassConstructor {
constructor(...args) {
super(...args);
}
[instanceComposerMethodName]() {
return oThis;
}
}
//Aesthetics.
DerivedClass.name = ClassConstructor.name;
return DerivedClass;
}
};
module.exports = InstanceComposer;