Class('JooseX.Role.Parameterized.Initializer', {
meta : Joose.Meta.Class,
isa : Joose.Meta.Role,
has : {
initializer : null
},
builder : {
methods : {
initializer : function (meta, initializer) {
meta.initializer = initializer
}
}
},
stem : {
// this will cause the role to remain open after creation (we need to wait till the application moment)
has : {
firstConsumption : true
},
methods : {
beforeConsumedBy : function (targetStem) {
if (this.firstConsumption) {
var targetMeta = this.targetMeta
var initializer = targetMeta.initializer
var consumingClass = targetStem.targetMeta.c
var res = initializer.meta.roleFunc.call(initializer, initializer, consumingClass)
if (Joose.O.isFunction(res)) res = { does : res }
targetMeta.extend(res)
this.firstConsumption = false
}
}
}
}
});
Class('JooseX.Role.Parameterized', {
meta : Joose.Meta.Class,
isa : Joose.Meta.Class,
does : 'JooseX.Class.SimpleConstructor',
use : 'JooseX.Role.Parameterized.Initializer',
has : {
roleFunc : null,
introspect : false
},
builder : {
methods : {
parameter : function (meta, info) {
this.has(meta, info)
},
role : function (meta, roleFunc) {
meta.roleFunc = roleFunc
},
introspect : function (meta, value) {
meta.introspect = value
}
}
},
after : {
processStem : function () {
var meta = this
// adds a default `initialize` method to any parameterized role
this.addMethod('initialize', function () {
var roleFunc = meta.roleFunc
if (!roleFunc) throw "The producing `role` function is not defined for [" + meta.name + "]"
if (meta.introspect)
return Role({
meta : JooseX.Role.Parameterized.Initializer,
initializer : this
})
else {
var res = roleFunc.call(this, this)
if (!Joose.O.isFunction(res)) res = Role(res)
return res
}
})
}
}
});