mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 10:20:08 +00:00
cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
617c2d3dec
commit
635298aeac
@ -248,330 +248,6 @@ var FeatureSetProto = {
|
|||||||
&& that[e] instanceof Feature })
|
&& that[e] instanceof Feature })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
// Build feature list...
|
|
||||||
//
|
|
||||||
// Build a list of all registered features
|
|
||||||
// .buildFeatureList()
|
|
||||||
// .buildFeatureList(actions)
|
|
||||||
// -> list
|
|
||||||
//
|
|
||||||
// Build a list of given features
|
|
||||||
// .buildFeatureList(null, list)
|
|
||||||
// .buildFeatureList(actions, list)
|
|
||||||
// -> list
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// NOTE: some feature .isApplicable(..) may expect the action set thus
|
|
||||||
// making it required for building a feature list.
|
|
||||||
// NOTE: this will try and keep the order as close as possible to the
|
|
||||||
// original as possible, this if the list is correctly ordered
|
|
||||||
// it will not be affected...
|
|
||||||
// NOTE: this will fix most dependency ordering errors except for two:
|
|
||||||
// - cyclic dependencies
|
|
||||||
// e.g. a -> b and b -> a, here there is no way to reorder
|
|
||||||
// a and b to resolve this.
|
|
||||||
// - dependency / priority conflict
|
|
||||||
// e.g. a -> b but a has a higher priority that b thus
|
|
||||||
// making it impossible to order the two without
|
|
||||||
// breaking either the dependency or priority ordering.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Forcing a feature disabled:
|
|
||||||
//
|
|
||||||
// If a feature is indicated with a leading '-' then it is forced
|
|
||||||
// disabled and will not load.
|
|
||||||
// Disabled features are treated in the same way as inaplicable
|
|
||||||
// features.
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Dependency sorting:
|
|
||||||
//
|
|
||||||
// These are order dependencies, i.e. for a dependency to be
|
|
||||||
// resolved it must satisfy ALL of the folowing:
|
|
||||||
// - all dependencies must exist in the list.
|
|
||||||
// - all dependencies must be positiond/setup before the dependant.
|
|
||||||
//
|
|
||||||
// The general algorithm is as folows:
|
|
||||||
// 1) place the dependencies befeore the dependant for each element
|
|
||||||
// 2) remove the duplicate features except fot the first occurance
|
|
||||||
// 3) repeat 1 and 2 for 2 to depth times or until the feature list
|
|
||||||
// stabelizes, i.e. no new features are added on the last run.
|
|
||||||
//
|
|
||||||
// NOTE: if auto_include is true (default) this will add dependencies
|
|
||||||
// as they are needed...
|
|
||||||
// This is useful for "meta-features" that do nothing other than
|
|
||||||
// depend/include sets of other features, for exmale: 'ui',
|
|
||||||
// 'core', 'browser', ...etc.
|
|
||||||
// NOTE: dependency chains larger than depth will be dropped, this
|
|
||||||
// can be fixed by setting a greater depth (default: 8)...
|
|
||||||
// NOTE: conflicts that can occur and can not be recovered from:
|
|
||||||
// - cyclic dependency
|
|
||||||
// X will be before one of its dependencies...
|
|
||||||
// - dependency / priority conflict
|
|
||||||
// X will have higher priority than one of its dependencies...
|
|
||||||
// NOTE: feature that depend in unapplicable features are considered
|
|
||||||
// unapplicable.
|
|
||||||
// XXX not sure if this is 100% correct...
|
|
||||||
// NOTE: child high priority features will push their dependencies up
|
|
||||||
// to precede them.
|
|
||||||
// ...this will not resolve all the possible conflicts so be
|
|
||||||
// careful.
|
|
||||||
//
|
|
||||||
// XXX make suggested feature expansion recursive...
|
|
||||||
// XXX this appears to be very slow if lst not passed...
|
|
||||||
// XXX add ability to remove features by prefixing a '-' to its name
|
|
||||||
// ...if one -<feature> is present, remove all instances of
|
|
||||||
// <feature>
|
|
||||||
// XXX .buildFeatureList() is slow and can be a bottleneck for large
|
|
||||||
// numbers of features... might be a good idea to take a look at
|
|
||||||
// this sometime...
|
|
||||||
_buildFeatureList: function(obj, lst, auto_include, depth){
|
|
||||||
var that = this
|
|
||||||
obj = obj || {}
|
|
||||||
|
|
||||||
lst = lst == null ? this.features : lst
|
|
||||||
lst = lst.constructor !== Array ? [lst] : lst
|
|
||||||
|
|
||||||
auto_include = auto_include == null ? true : false
|
|
||||||
depth = depth || 8
|
|
||||||
|
|
||||||
|
|
||||||
var missing = {}
|
|
||||||
|
|
||||||
// helpers...
|
|
||||||
// NOTE: _skipMissing(..) will add missing dependencies to missing...
|
|
||||||
var _skipMissing = function(feature, deps, missing){
|
|
||||||
return deps.filter(function(d){
|
|
||||||
if(lst.indexOf(d) < 0){
|
|
||||||
missing[d] = missing[d] != null ? missing[d] : []
|
|
||||||
if(missing[d].indexOf(feature) < 0){
|
|
||||||
missing[d].push(feature)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return missing[d] == null
|
|
||||||
})
|
|
||||||
}
|
|
||||||
var _sortDep = function(lst, missing, depth){
|
|
||||||
|
|
||||||
do {
|
|
||||||
var res = []
|
|
||||||
var l = lst.length
|
|
||||||
|
|
||||||
lst.forEach(function(n){
|
|
||||||
var e = that[n]
|
|
||||||
|
|
||||||
if(!e){
|
|
||||||
//console.warn('%s: feature is not loaded.', n)
|
|
||||||
// XXX should we break here???
|
|
||||||
throw (n + ': feature is not loaded.')
|
|
||||||
|
|
||||||
// no dependencies...
|
|
||||||
} else if(e.depends == null || e.depends.length == 0){
|
|
||||||
res.push(n)
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// auto-include dependencies...
|
|
||||||
if(auto_include){
|
|
||||||
var deps = e.depends
|
|
||||||
|
|
||||||
// skip dependencies that are not in list...
|
|
||||||
} else {
|
|
||||||
var deps = _skipMissing(n, e.depends, missing)
|
|
||||||
}
|
|
||||||
|
|
||||||
// place dependencies before the depended...
|
|
||||||
res = res.concat(deps)
|
|
||||||
res.push(n)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
lst = res
|
|
||||||
depth -= 1
|
|
||||||
} while(lst.length != l && depth > 0)
|
|
||||||
|
|
||||||
return lst
|
|
||||||
}
|
|
||||||
var _getSuggested = function(featureset, feature, suggested, missing){
|
|
||||||
suggested = suggested || []
|
|
||||||
|
|
||||||
var s = (feature.suggested || [])
|
|
||||||
|
|
||||||
s
|
|
||||||
// remove the already visited suggenstions...
|
|
||||||
.filter(function(e){ return suggested.indexOf(e) < 0 })
|
|
||||||
// add unloaded features to missing...
|
|
||||||
.filter(function(e){
|
|
||||||
if(featureset[e] == null){
|
|
||||||
missing[e] = missing[e] != null ? missing[e] : []
|
|
||||||
if(missing[e].indexOf(feature.tag) < 0){
|
|
||||||
missing[e].push(feature.tag)
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
// load new suggenstions...
|
|
||||||
.forEach(function(n){
|
|
||||||
var e = featureset[n]
|
|
||||||
if(e != null && e.suggested != null){
|
|
||||||
suggested = suggested
|
|
||||||
.concat(_getSuggested(featureset, e, suggested, missing))
|
|
||||||
.unique()
|
|
||||||
}
|
|
||||||
suggested.push(n)
|
|
||||||
})
|
|
||||||
|
|
||||||
return suggested
|
|
||||||
}
|
|
||||||
|
|
||||||
// expand optional "suggested" features...
|
|
||||||
// XXX make this recursive...
|
|
||||||
var res = []
|
|
||||||
lst.forEach(function(n){
|
|
||||||
var e = that[n]
|
|
||||||
if(e != null && e.suggested != null){
|
|
||||||
//res = res.concat(e.suggested)
|
|
||||||
res = res.concat(_getSuggested(that, e, res, missing))
|
|
||||||
}
|
|
||||||
res.push(n)
|
|
||||||
})
|
|
||||||
lst = res
|
|
||||||
|
|
||||||
// expand and sort dependencies...
|
|
||||||
// 2+ times untill depth is 0 or length stabelizes...
|
|
||||||
lst = _sortDep(lst, missing, depth).unique()
|
|
||||||
|
|
||||||
// sort features via priority keeping the order as close to
|
|
||||||
// manual as possible...
|
|
||||||
var l = lst.length
|
|
||||||
lst = lst
|
|
||||||
// remove undefined and non-features...
|
|
||||||
.filter(function(e){
|
|
||||||
return that[e] != null && that[e] instanceof Feature })
|
|
||||||
// build the sort table: [ <priority>, <rev-index>, <elem> ]
|
|
||||||
// NOTE: <rev-index> is element number from the tail...
|
|
||||||
.map(function(e, i){ return [ -that[e].getPriority(), i, e ] })
|
|
||||||
// do the sort...
|
|
||||||
// NOTE: for some reason JS compares lists as strings so we
|
|
||||||
// have to comare the list manually...
|
|
||||||
.sort(function(a, b){ return a[0] - b[0] || a[1] - b[1] })
|
|
||||||
// cleanup -- drop the table...
|
|
||||||
.map(function(e){ return e[2] })
|
|
||||||
|
|
||||||
// sort dependencies again...
|
|
||||||
// NOTE: this bubles the "priority" up the dependency tree...
|
|
||||||
// NOTE: this will not resolve all the conflicts...
|
|
||||||
lst = _sortDep(lst, missing, depth).unique()
|
|
||||||
|
|
||||||
// get disabled features...
|
|
||||||
var disabled = []
|
|
||||||
Object.keys(missing).forEach(function(n){
|
|
||||||
if(n[0] == '-'){
|
|
||||||
delete missing[n]
|
|
||||||
disabled.push(n.slice(1))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
// clasify features...
|
|
||||||
var unapplicable = []
|
|
||||||
var conflicts = {}
|
|
||||||
var that = this
|
|
||||||
lst = lst.filter(function(n, i){
|
|
||||||
var e = that[n]
|
|
||||||
if(e == null){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// disabled...
|
|
||||||
if(disabled.indexOf(n) >= 0){
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// check applicability...
|
|
||||||
if(e.isApplicable && !e.isApplicable.call(that, obj)){
|
|
||||||
unapplicable.push(n)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// no dependencies...
|
|
||||||
if(e.depends == null || e.depends.length == 0){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// mark feature unapplicable if it depends on an unapplicable
|
|
||||||
// or a disabled...
|
|
||||||
// NOTE: we need to do this once as features at this point
|
|
||||||
// are sorted by dependencies...
|
|
||||||
if(e.depends.filter(function(dep){
|
|
||||||
return unapplicable.indexOf(dep) > -1
|
|
||||||
|| disabled.indexOf(dep) > -1
|
|
||||||
}).length > 0){
|
|
||||||
unapplicable.push(n)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
// keep only conflicting...
|
|
||||||
var deps = e.depends.filter(function(dep){
|
|
||||||
dep = lst.indexOf(dep)
|
|
||||||
return dep == -1 || dep > i
|
|
||||||
})
|
|
||||||
|
|
||||||
// skip missing dependencies...
|
|
||||||
// NOTE: we need to check for missing again as a feature
|
|
||||||
// could have been removed due to inapplicability or
|
|
||||||
// being undefined...
|
|
||||||
deps = _skipMissing(n, deps, missing)
|
|
||||||
|
|
||||||
// no conflicts...
|
|
||||||
if(deps.length == 0){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// dependency exists but in wrong order -- can't fix...
|
|
||||||
conflicts[n] = deps
|
|
||||||
|
|
||||||
return false
|
|
||||||
})
|
|
||||||
|
|
||||||
// skip duplicate exclusive features...
|
|
||||||
var exclusive = []
|
|
||||||
var excluded = []
|
|
||||||
lst = lst.filter(function(n){
|
|
||||||
var e = that[n]
|
|
||||||
if(e == null || e.exclusive == null ){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
// count the number of exclusive features already present...
|
|
||||||
var res = e.exclusive
|
|
||||||
.filter(function(n){
|
|
||||||
if(exclusive.indexOf(n) < 0){
|
|
||||||
exclusive.push(n)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
})
|
|
||||||
.length == 0
|
|
||||||
|
|
||||||
if(!res){
|
|
||||||
excluded.push(n)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
|
|
||||||
return {
|
|
||||||
features: lst,
|
|
||||||
disabled: disabled,
|
|
||||||
excluded: excluded,
|
|
||||||
missing: missing,
|
|
||||||
conflicts: conflicts,
|
|
||||||
unapplicable: unapplicable,
|
|
||||||
}
|
|
||||||
},
|
|
||||||
//*/
|
|
||||||
|
|
||||||
|
|
||||||
// Build list of features...
|
// Build list of features...
|
||||||
//
|
//
|
||||||
// Build list of all features for an empty object...
|
// Build list of all features for an empty object...
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user