From 16f4d62548985740d89a4da38ffce39d5eb74a3c Mon Sep 17 00:00:00 2001 From: Bryan Ashby Date: Tue, 3 Sep 2019 19:52:04 -0600 Subject: [PATCH] Initial support for random 'next', 'action', ... --- core/menu_stack.js | 5 ++++- core/menu_util.js | 36 +++++++++++++++++++++++++++++++++--- 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/core/menu_stack.js b/core/menu_stack.js index 080d0efa..42cd6987 100644 --- a/core/menu_stack.js +++ b/core/menu_stack.js @@ -7,6 +7,9 @@ const { Errors, ErrorReasons } = require('./enig_error.js'); +const { + getResolvedSpec +} = require('./menu_util.js'); // deps const _ = require('lodash'); @@ -53,7 +56,7 @@ module.exports = class MenuStack { next(cb) { const currentModuleInfo = this.top(); const menuConfig = currentModuleInfo.instance.menuConfig; - const nextMenu = this.client.acs.getConditionalValue(menuConfig.next, 'next'); + const nextMenu = getResolvedSpec(this.client, menuConfig.next, 'next'); if(!nextMenu) { return cb(Array.isArray(menuConfig.next) ? Errors.MenuStack('No matching condition for "next"', ErrorReasons.NoConditionMatch) : diff --git a/core/menu_util.js b/core/menu_util.js index 18b17d9f..a429415b 100644 --- a/core/menu_util.js +++ b/core/menu_util.js @@ -17,6 +17,7 @@ const _ = require('lodash'); exports.loadMenu = loadMenu; exports.getFormConfigByIDAndMap = getFormConfigByIDAndMap; exports.handleAction = handleAction; +exports.getResolvedSpec = getResolvedSpec; exports.handleNext = handleNext; function getMenuConfig(client, name, cb) { @@ -172,7 +173,7 @@ function handleAction(client, formData, conf, cb) { return cb(Errors.MissingParam('Missing config')); } - const action = client.acs.getConditionalValue(conf.action, 'action'); // handle any conditionals + const action = getResolvedSpec(client, conf.action, 'action'); // random/conditionals/etc. const actionAsset = asset.parseAsset(action); if(!_.isObject(actionAsset)) { return cb(Errors.Invalid('Unable to parse "conf.action"')); @@ -216,9 +217,38 @@ function handleAction(client, formData, conf, cb) { } } -function handleNext(client, nextSpec, conf, cb) { - nextSpec = client.acs.getConditionalValue(nextSpec, 'next'); // handle any conditionals +function getResolvedSpec(client, spec, memberName) { + // + // 'next', 'action', etc. can come in various flavors: + // (1) Simple string: + // next: foo + // (2) Array of objects with 'acs' checks; any object missing 'acs' + // is assumed to be "true": + // next: [ + // { + // acs: AR2 + // next: foo + // } + // { + // next: baz + // } + // ] + // (3) Simple array of strings. A random selection will be made: + // next: [ "foo", "baz", "fizzbang" ] + // + if(!Array.isArray(spec)) { + return spec; // (1) simple string, as-is + } + if(_.isObject(spec[0])) { + return client.acs.getConditionalValue(spec, memberName); // (2) ACS conditionals + } + + return spec[Math.floor(Math.random() * spec.length)]; // (3) random +} + +function handleNext(client, nextSpec, conf, cb) { + nextSpec = getResolvedSpec(client, nextSpec, 'next'); const nextAsset = asset.getAssetWithShorthand(nextSpec, 'menu'); // :TODO: getAssetWithShorthand() can return undefined - handle it!