jungle-organic
Version:
The organic programming framework
140 lines (109 loc) • 4.79 kB
text/typescript
namespace Jungle {
export class ResolutionCell extends BaseCell {
io:IO.ResolveIO;
form:GForm;
resolveCache:{
args:any,
carried:any,
selection:any,
crowned:any,
reduced:any
}
protected constructForm(){
return new GForm(this)
}
protected constructIO(iospec){
return new IO.ResolveIO(this, iospec)
}
protected constructCore(crown, form){
return new ResolutionCell(crown, form)
}
private resolveDenizen(handle, args, denizen, reference){
let mergekey = reference === undefined ? false : reference;
if(denizen instanceof BaseCell && denizen !== undefined){
let denizenArg = args === undefined ? undefined : args[reference];
let resolved = denizen.resolve(denizenArg);
handle.merge(resolved, mergekey);
}else{
handle.merge(denizen, mergekey);
}
}
//main recursion
private resolveCell(handle:Util.Junction, node, carriedArgs, selection):any{
//log("node to resolve: ", node)
//cutting dictates that we select nothing and therefore will
var cut = false;
if(!selection){
cut = true;
}else if(selection === true && node instanceof Object){
//select all
selection = Object.keys(node);
}
//at this stage cut determines primitives are nullified and objects empty
const projectedCrown = this.crown; //TODO: projection onto selected keys;
const core = this;
//in here we have time to scan all Denizens and they will merge into the handle.
let splitf = core.resolveDenizen.bind(core, handle, carriedArgs)
Util.typeCaseSplitF(splitf)(projectedCrown);
}
resolve(resolveArgs){
Object.freeze(resolveArgs)
//
if(!this.prepared){
var pr = this.prepare();
}
if (this.io.isShellBase && !this.io.specialGate){
//resolve external
var sInpHook = this.io.specialInput
var sInpResult = sInpHook.tractor.call(this.ctx.exposed, resolveArgs);
var sResult;
if(sInpResult != IO.HALT && (sInpHook.eager || sInpResult !== undefined)){
this.io.specialGate = true;
sResult = this.resolve(sInpResult);
this.io.specialGate = false;
return sResult;
}else{
//the input has failed to trigger resolution our output hook
//will provide the return value on potentially undefined input
return this.io.specialOutput.tractor.call(this.ctx.exposed, sInpResult);
}
}else{
this.resolveCache = {
args:resolveArgs,
carried:null,
crowned:null,
selection:null,
reduced:null
}
//let [begin, raise] = this.junction.hold();
this.junction
.then(this.resolveCarryThen.bind(this),false)
.then(this.resolveCrownThen.bind(this),false)
.then(this.resolveReduceThen.bind(this),false)
.then(this.resolveCompleteThen.bind(this),false)
//begin();
return this.junction.realize();
//var selection = this.form.selector.call(this.ctx.exposed, Object.keys(this.crown), this.resolveCache.resolveArgs);
}
}
resolveCarryThen(results, handle){
//console.log("carry results:", results)
this.ctx.exposed.handle = handle;
return this.form.carrier.call(this.ctx.exposed, this.resolveCache.args);
}
resolveCrownThen(results, handle){
this.resolveCache.carried = results;
return this.resolveCell(handle, this.crown, this.resolveCache.carried, true);
}
resolveReduceThen(results, handle){
this.resolveCache.crowned = results;
this.ctx.exposed.handle = handle;
return this.form.resolver.call(this.ctx.exposed, this.resolveCache.crowned, this.resolveCache.args, this.resolveCache.carried);
}
resolveCompleteThen(results, handle){
this.resolveCache.reduced = results;
var dispached = this.io.dispatchResult(this.resolveCache.reduced);
return dispached;
}
}
}