123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- /**
- * Represents the smallest part of a content. Is a wrapper for what is being compared.
- * Holds an array of things. Only returns positive comparisons when all of them match, unless both sides only left optional nouns.
- */
- class ContentAtom {
- protected nouns : Array<any> = [];
- public constructor (...nouns : Array<any>) {
- this.addNoun(...nouns);
- }
- public addNoun (...nouns : Array<any>) {
- this.nouns.push(...nouns);
- return this;
- }
- public setNouns (...nouns : Array<any>) {
- this.nouns = [];
- this.addNoun(...nouns);
- return this;
- }
- public getNouns () {
- return [...this.nouns];
- }
- public getAtomPriority () {
- let weight = 0;
- this.nouns.forEach(value => {
- weight += ContentAtom.weightNoun(value);
- });
- return weight;
- }
- /**
- * Comparisons are always made assuming we're comparing the SPECIFIC side to the VAGUE side.
- * @param other
- */
- public compareAgainst (other : ContentAtom) {
- let specificNouns = [...this.nouns];
- let vagueNouns = [...other.nouns];
- for (let i = specificNouns.length - 1; i >= 0; i--) {
- let specificNoun = specificNouns[i];
- for (let k = vagueNouns.length - 1; k >= 0; k--) {
- let vagueNoun = vagueNouns[k];
- if (ContentAtom.compareNoun(specificNoun, vagueNoun)) {
- specificNouns.splice(i, 1);
- vagueNouns.splice(k, 1);
- break;
- }
- }
- }
- if (specificNouns.length == 0 && vagueNouns.length == 0) {
- return true;
- } else {
- // If any mandatory nouns were left unfilled, return false
- for (let i = 0; i < specificNouns.length; i++) {
- if (!(specificNouns[i] instanceof ContentNoun) || (<ContentNoun> specificNouns[i]).getType() == ContentNounType.MANDATORY) {
- return false;
- }
- }
- // If any non-adaptive nouns were left on the vague side, return false
- // Adaptive nouns means the content will handle it not existing for us
- for (let i = 0; i < vagueNouns.length; i++) {
- if (!(vagueNouns[i] instanceof ContentNoun) || (<ContentNoun> vagueNouns[i]).getType() != ContentNounType.FULLY_ADAPTIVE) {
- return false;
- }
- }
- // All tests passed, must be okay
- return true;
- }
- }
- public static compareNoun (specificNoun : any, vagueNoun : any) {
- if (specificNoun instanceof ContentNoun) {
- return specificNoun.compareAgainst(vagueNoun);
- } else if (typeof vagueNoun == "function") {
- // specific must inherit vague or be vague
- return specificNoun == vagueNoun || specificNoun instanceof vagueNoun ||
- (typeof specificNoun == "function" && (<any> specificNoun).prototype instanceof vagueNoun)
- } else if (vagueNoun instanceof Thing) {
- // specific must be vague
- return specificNoun == vagueNoun;
- }
- // Last strict check, probably returns false every time, unless we're dealing with numbers?
- return vagueNoun === specificNoun;
- }
- public static weightNoun (noun : any) : number {
- if (noun instanceof ContentNoun) {
- // This is a collection of multiple nouns! Add the weights?
- let weight = 0;
- noun.getNouns().forEach(value => {
- weight += ContentAtom.weightNoun(value);
- });
- return weight;
- } else if (noun instanceof ContentNounSimple) {
- // It's just a marker
- return 1;
- } else {
- // Normal noun.
- if (typeof noun == "function") {
- if (<any>noun.prototype instanceof Thing) {
- let specificity = 2; // Vague Thing
- let parentClass = Object.getPrototypeOf(noun);
- while (parentClass != Thing) {
- specificity += 0.1;
- parentClass = Object.getPrototypeOf(parentClass);
- }
- return specificity;
- } else {
- return 2.5; // It's not a "Thing", so it's probably a weird class, which is kind of specific
- }
- } else if (noun instanceof Thing) {
- return 4; // Specific thing
- } else {
- return 0.5; // The fuck is this shit, probably a number or something.
- }
- }
- }
- }
|