From dd397542cc23107d5297af00221514034be100e0 Mon Sep 17 00:00:00 2001 From: Sebastian Schmittner Date: Thu, 26 Dec 2024 00:27:04 +0100 Subject: [PATCH] added comparison action, fixed addition action --- README.md | 6 +- commons/common.js | 65 ++++++++++++++++++++- editor/code.js | 144 +++++++++++++++++++++++++++------------------- stories/test.json | 37 ++++++++++++ 4 files changed, 190 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index b4322dc..d12c64b 100644 --- a/README.md +++ b/README.md @@ -50,8 +50,8 @@ We proudly acknowledge using the following open source components in this projec -[cytoscape-klay](https://github.com/cytoscape/cytoscape.js-klay) for the graph layout - [marked](https://github.com/markedjs/marked) for Markdown rendering in the viewer - [DOMPurify](https://github.com/cure53/DOMPurify) for HTML sanitization in the viewer -- [JSZip](https://github.com/Stuk/jszip) for zipping -- [file-saver](https://github.com/eligrey/FileSaver.js/tree/master) for more easily saving large files directly from the browsers memory +- [JSZip](https://github.com/Stuk/jszip) for zipping (bundle export) +- [file-saver](https://github.com/eligrey/FileSaver.js/tree/master) for large files directly from the browsers memory - [esm.sh](https://github.com/esm-dev/esm.sh) for converting the old JS packages among the above into esm modules See there for the corresponding licenses and meta-dependencies. @@ -64,7 +64,7 @@ Copyright 2024 Sebastian Schmittner AGPLV3
-All code published in this repository is free software: you can redistribute it and/or modify it under the terms of the +All code published in this repository is free software. Everything written by me, i.e. excluding the dependencies mentioned in the Acknowledgment, can be redistributed and/or modified under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. diff --git a/commons/common.js b/commons/common.js index 6a975f2..f8ab273 100644 --- a/commons/common.js +++ b/commons/common.js @@ -24,6 +24,40 @@ export const supported_actions = { ], action: add_to_variable, }, + COMPARE_DO: { + parameters: ["VARIABLE", "ENUM", "STRING", "ACTION"], + enum: ["=", "!=", ">", ">=", "<=", "<"], + action: function (story, parameters) { + if (!parameters || parameters.length < 4) { + console.log("To few parameters for COMPARE_DO action", parameters); + return; + } + if (!this.enum.includes(parameters[1])) { + console.log("Bad enum", parameters[1], "in"); + return; + } + const operator = parameters[1]; + + const next_action = supported_actions?.[parameters[3]]?.action + if (!next_action) { + console.log("No such action", parameters[3]); + return; + } + + if (!story?.state?.variables?.[parameters[0]]) { + console.debug(`COMPARE_DO var ${parameters[0]} not set`); + return; + } + const variable_value = story?.state?.variables?.[parameters[0]]; + + if (compare(variable_value, operator, parameters[2])) { + return next_action( + story, + parameters.slice(4) + ); + } + }, + }, IF_SET_DO: { parameters: ["VARIABLE", "ACTION"], action: (story, parameters) => { @@ -233,6 +267,35 @@ function add_to_variable(story, parameters) { set_story_variable( story, parameters[0], - String(Number(parameters[0]) + Number(parameters[1])) + String(Number(story?.state?.variables?.[parameters[0]]) + Number(parameters[1])) ); } + +function compare(value1, operator, value2) { + let result; + switch (operator) { + case "=": + result = value1 == value2; + break; + case "<": + result = Number(value1) < Number(value2); + break; + case ">": + result = Number(value1) > Number(value2); + break; + case "!=": + result = String(value1) != String(value2); + break; + case ">=": + result = Number(value1) >= Number(value2); + break; + case "<=": + result = Number(value1) <= Number(value2); + break; + default: + console.log("Unsupported operator", operator); + return false; + } + console.log(`Comparison result for ${value1} ${operator} ${value2}: ${result}`); + return result; +} diff --git a/editor/code.js b/editor/code.js index 377192c..cf06110 100644 --- a/editor/code.js +++ b/editor/code.js @@ -276,64 +276,92 @@ function add_parameter( ) { const parameter_type = supported_actions[action_type].parameters[parameter_type_index]; - if (parameter_type == "STRING") { - const input = col.appendChild(document.createElement("input")); - input.type = "text"; - input.classList.add("form-control"); - input.value = action.parameters[parameter_index]; - input.addEventListener("change", () => { - action.parameters[parameter_index] = input.value; - console.debug("changed action", action); - }); - } - if (parameter_type == "VARIABLE") { - const select = col.appendChild(document.createElement("select")); - select.classList.add("form-select"); - if (!story?.state?.variables) { - return; - } - for (const variable of Object.keys(story.state.variables)) { - const option = select.appendChild(document.createElement("option")); - select.classList.add("form-select"); - option.text = variable; - option.value = variable; - } - select.value = action.parameters[parameter_index]; - select.onchange = () => { - action.parameters[parameter_index] = - select.options[select.selectedIndex].value; - }; - } - if (parameter_type == "SECTION") { - const select = col.appendChild(document.createElement("select")); - select.classList.add("form-select"); - for (const section_key of Object.keys(story.sections)) { - const option = select.appendChild(document.createElement("option")); - select.classList.add("form-select"); - option.text = story.sections[section_key].id; - option.value = story.sections[section_key].id; - } - select.value = action.parameters[parameter_index]; - select.onchange = () => { - action.parameters[parameter_index] = - select.options[select.selectedIndex].value; - }; - } - if (parameter_type == "ACTION") { - col.remove(); - add_action_and_parameter_inputs_to_row( - row, - action, - (new_action) => { - action.parameters[parameter_index] = new_action; - action.parameters.splice(parameter_index + 1); - for (const parameter_type of supported_actions[new_action].parameters) { - action.parameters.push(""); - } - }, - action.parameters[parameter_index], - parameter_index + 1 - ); + switch (parameter_type) { + case "STRING": + const input = col.appendChild(document.createElement("input")); + input.type = "text"; + input.classList.add("form-control"); + input.value = action.parameters[parameter_index]; + input.addEventListener("change", () => { + action.parameters[parameter_index] = input.value; + console.debug("changed action", action); + }); + break; + case "VARIABLE": + const selectVariable = col.appendChild(document.createElement("select")); + selectVariable.classList.add("form-select"); + if (!story?.state?.variables) { + return; + } + for (const variable of Object.keys(story.state.variables)) { + const option = selectVariable.appendChild( + document.createElement("option") + ); + selectVariable.classList.add("form-select"); + option.text = variable; + option.value = variable; + } + selectVariable.value = action.parameters[parameter_index]; + selectVariable.onchange = () => { + action.parameters[parameter_index] = + selectVariable.options[selectVariable.selectedIndex].value; + }; + break; + case "SECTION": + const selectSection = col.appendChild(document.createElement("select")); + selectSection.classList.add("form-select"); + for (const section_key of Object.keys(story.sections)) { + const option = selectSection.appendChild( + document.createElement("option") + ); + selectSection.classList.add("form-select"); + option.text = story.sections[section_key].id; + option.value = story.sections[section_key].id; + } + selectSection.value = action.parameters[parameter_index]; + selectSection.onchange = () => { + action.parameters[parameter_index] = + selectSection.options[selectSection.selectedIndex].value; + }; + break; + case "ACTION": + col.remove(); + add_action_and_parameter_inputs_to_row( + row, + action, + (new_action) => { + action.parameters[parameter_index] = new_action; + action.parameters.splice(parameter_index + 1); + for (const parameter_type of supported_actions[new_action] + .parameters) { + action.parameters.push(""); + } + }, + action.parameters[parameter_index], + parameter_index + 1 + ); + break; + case "ENUM": + const selectEnum = col.appendChild(document.createElement("select")); + selectEnum.classList.add("form-select"); + const enum_options = supported_actions[action_type]?.enum; + if (!enum_options) { + console.error("Action does not specify enum values", action); + break; + } + for (const enumValue of enum_options) { + const option = selectEnum.appendChild(document.createElement("option")); + option.text = enumValue; + option.value = enumValue; + } + selectEnum.value = action.parameters[parameter_index]; + selectEnum.onchange = () => { + action.parameters[parameter_index] = + selectEnum.options[selectEnum.selectedIndex].value; + }; + break; + default: + console.error("Unsupported parameter type:", parameter_type); } } diff --git a/stories/test.json b/stories/test.json index e6df104..2e2637a 100644 --- a/stories/test.json +++ b/stories/test.json @@ -223,6 +223,43 @@ "- v4=${v4}", "- v5=${v5}", "- v6=${v6}" + ], + "next": [ + { + "text": "", + "next": 6 + } + ] + }, + "6": { + "id": "6", + "text_lines": [ + "# 6", + "", + "```", + "if (v1 < 5){", + " v1 += 5", + "}", + "```", + "- v1=${v1}", + "- v2=${v2}", + "- v3=${v3}", + "- v4=${v4}", + "- v5=${v5}", + "- v6=${v6}" + ], + "script": [ + { + "action": "COMPARE_DO", + "parameters": [ + "v1", + "<", + "5", + "ADD_TO_VARIABLE", + "v1", + "5" + ] + } ] } },