@gmetrixr/rjson
Version:
(R)ecursive Json
303 lines (302 loc) • 15 kB
JavaScript
import chalk from "chalk";
import { rActionDisplayName, rEventDisplayName } from ".";
import { rn } from "..";
import { emptyROM, RecordFactory, RT, rtp } from "../../R";
import { ProjectFactory, SceneFactory } from "../../recordFactories";
import { ElementUtils } from "../../recordFactories/ElementFactory";
import { isElementType } from "../elements";
import { isSpecialType, specialElementDisplayNames, SpecialType } from "../special";
import { isVariableType } from "../variables";
/**
* Separating out this class as this doesn't need to be included in production and also,
* because this imports potentially heavy "chalk" dependency
*/
export class rulePrintUtils {
}
/** Get an instance of Console Rule Printer */
rulePrintUtils.crp = () => ConsoleRulePrinter.getInstance();
/** Get an instance of Friendly Rule Printer */
rulePrintUtils.frp = () => FriendlyRulePrinter.getInstance();
rulePrintUtils.generateRuleTextsAndPrint = (scene, varDefMap = emptyROM()) => {
let ruleText;
const sceneF = new SceneFactory(scene);
for (const rule of sceneF.getRecords(RT.rule)) {
ruleText = rulePrintUtils.crp().generateRuleText(rule, scene, varDefMap);
rulePrintUtils.crp().consoleRuleTextPrinter(ruleText);
}
};
rulePrintUtils.generateFriendlyRuleTextsAndPrint = (project, sceneIds) => {
const projectF = new ProjectFactory(project);
const varDefROM = projectF.getROM(RT.variable);
for (const sceneId of sceneIds) {
const scene = projectF.getRecord(RT.scene, sceneId);
if (scene !== undefined) {
rulePrintUtils.frp().generateRuleTextsAndPrint(project, scene, varDefROM);
}
}
};
rulePrintUtils.generateFriendlyRuleTexts = (project, sceneIds) => {
const projectF = new ProjectFactory(project);
const varDefROM = projectF.getROM(RT.variable);
let rulesText = "";
const frp = rulePrintUtils.frp();
for (const sceneId of sceneIds) {
const scene = projectF.getRecord(RT.scene, sceneId);
if (scene !== undefined) {
const sceneF = new SceneFactory(scene);
for (const rule of sceneF.getRecords(RT.rule)) {
const ruleText = frp.generateRuleText(rule, project, scene, varDefROM);
rulesText += frp.friendlyRuleLine(ruleText);
rulesText += "\n"; // new line
}
}
}
return rulesText;
};
/**
* Use this class via the singleton getter
* Eg: ConsoleRulePrinter.getInstance().doSomething....
*/
class ConsoleRulePrinter {
constructor() {
this.generateRuleTextsAndPrint = (scene, varDefMap = emptyROM()) => {
let ruleText;
const sceneF = new SceneFactory(scene);
for (const rule of sceneF.getRecords(RT.rule)) {
ruleText = this.generateRuleText(rule, scene, varDefMap);
this.consoleRuleTextPrinter(ruleText);
}
};
this.generateRuleText = (rule, scene, varDefMap = emptyROM()) => {
const rf = new RecordFactory(rule);
const whenEventsArray = [];
const thenActionsArray = [];
rf.getRecords(RT.when_event).forEach(whenEvent => {
//whenEventsArray.push(`${whenEvent.ce_type}(${whenEvent.ce_id}) ${cEventsDisplayNames[<ConnectionEvent>whenEvent.event]} ${whenEvent.properties}`.trim());
whenEventsArray.push(this.weText(whenEvent, scene, varDefMap));
});
rf.getRecords(RT.then_action).forEach(thenAction => {
//thenActionsArray.push(`${thenAction.ce_type}(${thenAction.ce_id}) should ${cActionsDisplayNames[<ConnectionAction>thenAction.action]} ${thenAction.properties}`.trim());
thenActionsArray.push(this.taText(thenAction, scene, varDefMap));
});
return {
ruleIdText: this.ruleIdText(rule),
weTexts: whenEventsArray,
weAndOr: rf.get(rtp.rule.events_and) ? "AND" : "OR",
taTexts: thenActionsArray,
};
};
this.consoleRuleTextPrinter = (ruleText) => {
console.log(`${chalk.yellow.bold("RULE".padStart(5).padEnd(6))}${chalk.yellow(ruleText.ruleIdText)}`);
let startText;
for (let i = 0; i < ruleText.weTexts.length; i++) {
startText = i === 0 ? "WHEN" : ruleText.weAndOr;
console.log(`${chalk.green.bold(startText.padStart(5).padEnd(6))}${chalk.green(ruleText.weTexts[i])}`);
}
for (let i = 0; i < ruleText.taTexts.length; i++) {
startText = i === 0 ? "THEN" : "AND";
console.log(`${chalk.blue.bold(startText.padStart(5).padEnd(6))}${chalk.blue(ruleText.taTexts[i])}`);
}
};
this.ruleIdText = (rule) => {
var _a;
return `${rule.name}(${rule.id}) ${(_a = rule.props.comment) !== null && _a !== void 0 ? _a : ""}`;
};
this.weText = (we, scene, varDefMap = emptyROM(), values) => {
var _a;
const displayName = this.coIdToName(we.props.co_id, we.props.co_type, scene, varDefMap);
const event = rEventDisplayName[we.props.event];
let propertiesText = "";
if (we.props.properties !== undefined && we.props.properties.length !== 0) {
propertiesText = `[${(_a = we.props.properties) === null || _a === void 0 ? void 0 : _a.join(",")}]`;
}
let valuesText = "";
if (values !== undefined && values.length !== 0) {
valuesText = ` values[${values.join(",")}]`;
}
return `${displayName} ${event}${propertiesText}${valuesText}`;
};
this.taText = (ta, scene, varDefMap = emptyROM(), values) => {
var _a;
const displayName = this.coIdToName(ta.props.co_id, ta.props.co_type, scene, varDefMap);
const action = rActionDisplayName[ta.props.action];
let propertiesText = "";
if (ta.props.properties !== undefined && ta.props.properties.length !== 0) {
propertiesText = `[${(_a = ta.props.properties) === null || _a === void 0 ? void 0 : _a.join(",")}]`;
}
let valuesText = "";
if (values !== undefined && values.length !== 0) {
valuesText = ` values[${values.join(",")}]`;
}
let delayText = "";
if (ta.props.delay !== undefined && ta.props.delay !== 0) {
delayText = ` after ${ta.props.delay}s`;
}
return `${displayName} should ${action}${propertiesText}${valuesText}${delayText}`;
};
this.coIdToName = (coId, coType, scene, varDefMap = emptyROM()) => {
var _a, _b, _c, _d, _e, _f, _g;
let name = "";
let type = "UnknownType";
if (isSpecialType(coType)) {
type = specialElementDisplayNames[coType];
if (coType === SpecialType.scene) {
name = (_a = scene.name) !== null && _a !== void 0 ? _a : "";
}
}
else if (isVariableType(coType)) {
type = coType;
name = (_c = (_b = varDefMap.map[coId]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : "";
}
else if (isElementType(coType)) {
type = (_e = (_d = ElementUtils.getElementDefinition(coType)) === null || _d === void 0 ? void 0 : _d.elementDefaultName) !== null && _e !== void 0 ? _e : "";
const e = new RecordFactory(scene).getAllDeepChildrenWithFilter(RT.element, e => e.id === coId);
name = (_g = (_f = e[0]) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "";
}
if (name === "") {
return `${type}(${coId})`;
}
return `${type} ${name}(${coId})`;
};
}
}
ConsoleRulePrinter.getInstance = () => {
if (ConsoleRulePrinter.instance === undefined) {
ConsoleRulePrinter.instance = new ConsoleRulePrinter();
}
return ConsoleRulePrinter.instance;
};
/**
* Use this class via the singleton getter
* Eg: FriendlyRulePrinter.getInstance().doSomething....
*/
class FriendlyRulePrinter {
constructor() {
this.generateRuleTextsAndPrint = (project, scene, varDefMap = emptyROM()) => {
let ruleText;
const sceneF = new SceneFactory(scene);
for (const rule of sceneF.getRecords(RT.rule)) {
ruleText = this.generateRuleText(rule, project, scene, varDefMap);
console.log(this.friendlyRuleLine(ruleText));
}
};
this.generateRuleText = (rule, project, scene, varDefMap = emptyROM()) => {
const rf = new RecordFactory(rule);
const whenEventsArray = [];
const thenActionsArray = [];
rf.getRecords(RT.when_event).forEach(whenEvent => {
whenEventsArray.push(this.weText(whenEvent, scene, varDefMap));
});
rf.getRecords(RT.then_action).forEach(thenAction => {
thenActionsArray.push(this.taText(thenAction, project, scene, varDefMap));
});
return {
ruleIdText: `${rule.name}${rule.props.comment ? " " + rule.props.comment : ""}`,
weTexts: whenEventsArray,
weAndOr: rf.get(rtp.rule.events_and) ? "and" : "or",
taTexts: thenActionsArray,
};
};
this.friendlyRuleLine = (ruleText) => {
const ruleStart = `RULE ${ruleText.ruleIdText}`;
let ruleMid = "When ";
for (let i = 0; i < ruleText.weTexts.length; i++) {
ruleMid += i === 0 ? "" : ` ${ruleText.weAndOr} `;
ruleMid += ruleText.weTexts[i];
}
let ruleEnd = "Then ";
for (let i = 0; i < ruleText.taTexts.length; i++) {
ruleEnd += i === 0 ? "" : " and ";
ruleEnd += ruleText.taTexts[i];
}
const ruleS = `${ruleStart}: ${ruleMid} ${ruleEnd}`;
return ruleS;
};
// * Used in cog to print matched triggerred events
this.weText = (we, scene, varDefMap = emptyROM(), values) => {
var _a;
const displayName = this.coIdToName(we.props.co_id, we.props.co_type, scene, varDefMap);
const event = rEventDisplayName[we.props.event];
let propertiesText = "";
if (we.props.properties !== undefined && we.props.properties.length !== 0) {
propertiesText = `[${(_a = we.props.properties) === null || _a === void 0 ? void 0 : _a.join(",")}]`;
}
let valuesText = "";
if (values !== undefined && values.length !== 0) {
valuesText = ` values[${values.join(",")}]`;
}
return `${displayName} ${event}${propertiesText}${valuesText}`;
};
// * Used in cog to print matched triggerred actions
this.taText = (ta, project, scene, varDefMap = emptyROM(), values) => {
var _a;
const displayName = this.coIdToName(ta.props.co_id, ta.props.co_type, scene, varDefMap);
const action = rActionDisplayName[ta.props.action];
let propertiesText = "";
//Calculate propertiesText based on the action type
if (ta.props.properties !== undefined && ta.props.properties.length !== 0) {
const properties = ta.props.properties;
let coIdElement, e, coIdScene, propsScene;
switch (ta.props.action) {
case rn.RuleAction.point_to:
//properties[0] is the element id
coIdElement = properties[0];
e = new RecordFactory(scene).getAllDeepChildrenWithFilter(RT.element, e => e.id === coIdElement);
propertiesText = this.coIdToName(properties[0], (_a = e[0]) === null || _a === void 0 ? void 0 : _a.props.element_type, scene, varDefMap);
break;
case rn.RuleAction.change_scene:
//properties[0] is the scene id
coIdScene = properties[0];
propsScene = new ProjectFactory(project).getRecord(RT.scene, coIdScene);
if ((propsScene === null || propsScene === void 0 ? void 0 : propsScene.name) !== undefined) {
propertiesText = ` ${propsScene.name}`; //need a space before the scene name
}
break;
default:
propertiesText = `[${properties.join(",")}]`;
break;
}
}
//Values are needed only at runtime. Not while printing pre-existing rules
let valuesText = "";
if (values !== undefined && values.length !== 0) {
valuesText = ` values[${values.join(",")}]`;
}
let delayText = "";
if (ta.props.delay !== undefined && ta.props.delay !== 0) {
delayText = ` after ${ta.props.delay}s`;
}
return `${displayName} should ${action}${propertiesText}${valuesText}${delayText}`;
};
this.coIdToName = (coId, coType, scene, varDefMap = emptyROM()) => {
var _a, _b, _c, _d, _e, _f, _g;
let name = "";
let type = "UnknownType";
if (isSpecialType(coType)) {
type = specialElementDisplayNames[coType];
if (coType === SpecialType.scene) {
name = (_a = scene.name) !== null && _a !== void 0 ? _a : "";
}
}
else if (isVariableType(coType)) {
type = coType;
name = (_c = (_b = varDefMap.map[coId]) === null || _b === void 0 ? void 0 : _b.name) !== null && _c !== void 0 ? _c : "";
}
else if (isElementType(coType)) {
type = (_e = (_d = ElementUtils.getElementDefinition(coType)) === null || _d === void 0 ? void 0 : _d.elementDefaultName) !== null && _e !== void 0 ? _e : "";
const e = new RecordFactory(scene).getAllDeepChildrenWithFilter(RT.element, e => e.id === coId);
name = (_g = (_f = e[0]) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : "";
}
if (name === "") {
return `${type}`;
}
return `${type} ${name}`;
};
}
}
FriendlyRulePrinter.getInstance = () => {
if (FriendlyRulePrinter.instance === undefined) {
FriendlyRulePrinter.instance = new FriendlyRulePrinter();
}
return FriendlyRulePrinter.instance;
};