From f00274bdcdf9a4ba1413e7cf8e7f5e367b7a59bb Mon Sep 17 00:00:00 2001 From: qbjl Date: Thu, 18 Jan 2024 16:50:18 -0600 Subject: [PATCH 1/2] Create index.js incomplete pull req --- .../silvxrcat_carryforward/index.js | 307 ++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 src/extensions/silvxrcat_carryforward/index.js diff --git a/src/extensions/silvxrcat_carryforward/index.js b/src/extensions/silvxrcat_carryforward/index.js new file mode 100644 index 00000000000..18a4577c4ff --- /dev/null +++ b/src/extensions/silvxrcat_carryforward/index.js @@ -0,0 +1,307 @@ +const BlockType = Scratch.BlockType; +const ArgumentType = Scratch.ArgumentType; +const cstore = require('./iterStore'); +const store = new cstore(); + +class CarryForwards { + constructor(runtime) { + this.runtime = runtime; + } + // stolen code from gsa edited for this stuff + deserialize(data) { + store.iterators = {}; + for (const iter of data) { + store.newIterator(iter.name, iter.value, iter.id); + } + } + + serialize() { + return store.getAllIterators() + .map(variable => ({ + name: variable.name, + value: variable.value, + id: variable.id, + calc: variable.calc + })); + } + + orderCategoryBlocks(blocks) { + const button = blocks[0]; + const varBlock = blocks[1]; + delete blocks[0]; + delete blocks[1]; + const varBlocks = store.getAllIterators().map(i => varBlock + .replace('{iterId}', i.id)); + if (!varBlocks.length) { + return [button]; + } + varBlocks + .reverse() + .push(button); + blocks = varBlocks + .reverse() + .concat(blocks); + return blocks; + } + // not stolen code + getInfo() { + return { + id: "carryforwards", + name: "CarryForwards", + color1: "#75cc50", + color2: "#41ab4a", + color3: "#41ab4a", + isDynamic: true, + orderBlocks: this.orderCategoryBlocks, + blocks: [ + { + opcode: 'createIterator', + blockType: BlockType.BUTTON, + text: 'create iterator', + }, + { + opcode: 'iterGetter', + blockType: BlockType.REPORTER, + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: '{iterId}' + } + }, + text: '[iter]' + }, + { + blockType: BlockType.LABEL, + text: 'Edit', + }, + { + opcode: 'setFrequency', + blockType: BlockType.COMMAND, + text: 'set frequency of [iter] to [f]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + }, + f: { + type: ArgumentType.NUMBER, + defaultValue: 1 + } + }, + }, + { + opcode: 'setReaction', + blockType: BlockType.COMMAND, + text: 'set reaction speed of [iter] to [r]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + }, + r: { + type: ArgumentType.NUMBER, + defaultValue: 1 + } + }, + }, + { + opcode: 'setZeta', + blockType: BlockType.COMMAND, + text: 'set zeta of [iter] to [z]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + }, + z: { + type: ArgumentType.NUMBER, + defaultValue: 0.5 + } + }, + }, + '---', + { + opcode: 'initializeIterator', + blockType: BlockType.COMMAND, + text: 'initialize core values of [iter]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + } + }, + }, + { + blockType: BlockType.LABEL, + text: 'Execute', + }, + { + opcode: 'stepIterator', + blockType: BlockType.COMMAND, + text: 'step [iter] to [x] with time dialiation [t]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + }, + x: { + type: ArgumentType.NUMBER, + defaultValue: 0 + }, + t: { + type: ArgumentType.NUMBER, + defaultValue: 0.1 + } + }, + }, + { + opcode: 'setIterator', + blockType: BlockType.COMMAND, + text: 'set [iter] to [x]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + }, + x: { + type: ArgumentType.NUMBER, + defaultValue: 0 + } + }, + }, + { + blockType: BlockType.LABEL, + text: 'Information', + }, + { + opcode: 'getIteratorFrequency', + blockType: BlockType.REPORTER, + text: 'frequency of [iter]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + } + }, + }, + { + opcode: 'getIteratorReaction', + blockType: BlockType.REPORTER, + text: 'reaction time of [iter]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + } + }, + }, + { + opcode: 'getIteratorZeta', + blockType: BlockType.REPORTER, + text: 'zeta of [iter]', + arguments: { + iter: { + type: ArgumentType.STRING, + menu: 'iterators', + defaultValue: "" + } + }, + }, + ], + menus: { + iterators: { + acceptReporters: true, + items: this.getIteratorItems() + } + } + }; + } + + getIteratorItems() { + let items = store.getAllIterators(); + if (items.length < 1) return {text: '', value: ''}; + return items.map(i => ({ + text: i.name, + value: i.id + })) + } + + createIterator() { + const pi = prompt("Iterator name?", "default"); + if (!pi) return; + if (store.getIteratorByName(pi)) return alert("Iterator name already exists"); + store.newIterator(pi); + vm.emitWorkspaceUpdate(); + this.serialize(); + } + + iterGetter(args) { + return store.getIterator(args.iter).value; + } + + setFrequency(args) { + store.setCalcValue(args.iter, 'f', args.f); + } + + setReaction(args) { + store.setCalcValue(args.iter, 'r', args.r); + } + + setZeta(args) { + store.setCalcValue(args.iter, 'zeta', args.z); + } + + initializeIterator(args) { + const { iter, f, r, zeta, value } = store.getIterator(args.iter).calc; + const pi = Math.PI; + Object.assign(iter.calc, { + k1: zeta / (pi * f), + k2: 1 / ((2 * pi * f) ** 2), + k3: (r * zeta) / (2 * pi * f), + xp: value, + y: value, + yd: 0 + }); + } + + stepIterator(args) { + const { t, x, iter } = args; + const { xp, k1, k2, k3, y, yd } = store.getIterator(iter).calc; + const xd = (x - xp) / t; + iter.calc.xp = x; + const approx = 1.1 * (((t ** 2) / 4) + ((t * k1) / 2)); + if (k2 < approx) iter.calc.k2 = approx; + iter.calc.y += t * yd; + iter.calc.yd += (t * (((x + (k3 * xd)) - y) - (k1 * yd))) / k2; + iter.value = iter.calc.y; + } + + setIterator(args) { + const { iter, x } = args; + store.getIterator(iter).value = x; + store.getIterator(iter).calc.y = x; + } + + getIteratorFrequency(args) { + return store.getIterator(args.iter).calc.f; + } + + getIteratorReaction(args) { + return store.getIterator(args.iter).calc.r; + } + + getIteratorZeta(args) { + return store.getIterator(args.iter).calc.zeta; + } +} + +module.exports = CarryForwards; From e5d9383470148217992a09c2e83c86f3308af6a2 Mon Sep 17 00:00:00 2001 From: qbjl Date: Thu, 18 Jan 2024 16:53:07 -0600 Subject: [PATCH 2/2] Create iterStore.js --- .../silvxrcat_carryforward/iterStore.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 src/extensions/silvxrcat_carryforward/iterStore.js diff --git a/src/extensions/silvxrcat_carryforward/iterStore.js b/src/extensions/silvxrcat_carryforward/iterStore.js new file mode 100644 index 00000000000..720bb09dbb7 --- /dev/null +++ b/src/extensions/silvxrcat_carryforward/iterStore.js @@ -0,0 +1,50 @@ +const uid = require('../../util/uid'); + +class iterStore { + constructor() { + this.iterators = {}; + } + + getIterator(id) { + return this.iterators[id]; + } + + deleteIterator(id) { + const o = this.iterators[id]; + delete this.iterators[id]; + return o; + } + + newIterator(name, starter, opt_id) { + starter = starter || 0; + const id = opt_id || uid(); + const data = { + name: name, + id: id, + value: starter, + calc: { + f: 1, + r: 1, + zeta: 0.5, + k1: 0, + k2: 0, + k3: 0, + xp: 0, + y: 0, + yd: 0 + } + }; + this.iterators[id] = data; + return data; + } + + getIteratorByName(name) { + return Object.values(this.iterators).find((i) => i.name === name); + } + + getAllIterators() { + return Object.values(this.iterators); + } +} + +module.exports = iterStore;