Skip to content

Commit

Permalink
Add Vue generator and support for reactive variables
Browse files Browse the repository at this point in the history
  • Loading branch information
pavi2410 committed Mar 31, 2024
1 parent 7d3a0a1 commit 06021a5
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 13 deletions.
49 changes: 49 additions & 0 deletions src/blocks/VueGenerator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import {javascriptGenerator, JavascriptGenerator} from "blockly/javascript";
import {Names, Variables, Workspace} from "blockly";
import NameType = Names.NameType;

class VueGenerator extends JavascriptGenerator {
init(workspace: Workspace) {
super.init(workspace);

if (!this.nameDB_) {
this.nameDB_ = new Names(this.RESERVED_WORDS_);
} else {
this.nameDB_.reset();
}

this.nameDB_.setVariableMap(workspace.getVariableMap());
this.nameDB_.populateVariables(workspace);
this.nameDB_.populateProcedures(workspace);

const defvars = [];
// Add developer variables (not created or named by the user).
const devVarList = Variables.allDeveloperVariables(workspace);
for (let i = 0; i < devVarList.length; i++) {
defvars.push(
this.nameDB_.getName(devVarList[i], NameType.DEVELOPER_VARIABLE),
);
}

// Add user variables, but only ones that are being used.
const variables = Variables.allUsedVarModels(workspace);
for (let i = 0; i < variables.length; i++) {
defvars.push(
this.nameDB_.getName(variables[i].getId(), NameType.VARIABLE),
);
}

// Declare all of the variables.
if (defvars.length) {
this.definitions_['variables'] = `let state = reactive({${defvars.map(v => `${v}: null`).join(',')}})`;
}
this.isInitialized = true;
}
}

export const vueGenerator = new VueGenerator('vue');


for (const name in javascriptGenerator.forBlock) {
vueGenerator.forBlock[name] = javascriptGenerator.forBlock[name];
}
6 changes: 5 additions & 1 deletion src/blocks/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ import {javascriptGenerator} from "blockly/javascript";
import {BaseDirectory, mkdir, writeTextFile} from '@tauri-apps/plugin-fs';
import {dirname, join} from "@tauri-apps/api/path";
import Blockly from "blockly";
import "./jigsaw.ts";
import {vueGenerator} from "./VueGenerator.ts";

const JIGSAW_PROJECTS_DIR = './JigsawProjects'

export async function generateAppCode(projectName: string, workspace: Blockly.Workspace) {
const code = javascriptGenerator.workspaceToCode(workspace);
// const code = javascriptGenerator.workspaceToCode(workspace);
const code = vueGenerator.workspaceToCode(workspace);

const projectPath = await join(JIGSAW_PROJECTS_DIR, projectName);

Expand All @@ -21,6 +24,7 @@ async function writeProjectFiles(projectName: string, projectPath: string, code:
// language=Vue
'src/App.vue': `
<script setup>
import {ref, reactive} from 'vue';
import * as Ionic from '@ionic/vue';
${code}
Expand Down
23 changes: 11 additions & 12 deletions src/blocks/jigsaw.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import * as Blockly from "blockly/core";
import {JavascriptGenerator, javascriptGenerator, Order} from "blockly/javascript";

import {blocks, registerProcedureSerializer, unregisterProcedureBlocks} from '@blockly/block-shareable-procedures';
import {vueGenerator} from "./VueGenerator.ts";

unregisterProcedureBlocks();
Blockly.common.defineBlocks(blocks);
Expand Down Expand Up @@ -152,7 +153,7 @@ Blockly.defineBlocksWithJsonArray([
// return code;
// };

javascriptGenerator.forBlock["jigsaw_app"] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock["jigsaw_app"] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const statements_children = generator.statementToCode(block, 'CHILDREN');
const code = `</script><template>
<Ionic.IonApp>
Expand All @@ -162,13 +163,13 @@ ${statements_children}
return code;
};

javascriptGenerator.forBlock['jigsaw_text'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['jigsaw_text'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const text = generator.valueToCode(block, 'TEXT', Order.ATOMIC);
const code = `<Ionic.IonText><p>{{ ${text} }}</p></Ionic.IonText>\n`;
return code;
};

javascriptGenerator.forBlock["jigsaw_button"] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock["jigsaw_button"] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const statements_onclick = generator.statementToCode(block, 'ONCLICK');
const statements_children = generator.statementToCode(block, 'CHILDREN');

Expand All @@ -185,20 +186,20 @@ ${statements_onclick}
return code;
};

javascriptGenerator.forBlock['jigsaw_flex'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['jigsaw_flex'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const dropdown_flex_dir = block.getFieldValue('FLEX_DIR');
const statements_items = generator.statementToCode(block, 'ITEMS');
const code = `<div style="display:flex;flex-direction:${dropdown_flex_dir};">\n${statements_items}</div>\n`;
return code;
};

javascriptGenerator.forBlock['jigsaw_input'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['jigsaw_input'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const value_state = generator.valueToCode(block, 'LABEL', Order.ATOMIC);
const code = `<Ionic.IonInput :label="${value_state}"></Ionic.IonInput>\n`;
return code;
};

javascriptGenerator.forBlock['jigsaw_toast'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['jigsaw_toast'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const message = generator.valueToCode(block, 'MESSAGE', Order.ATOMIC);
const duration = generator.valueToCode(block, 'DURATION', Order.ATOMIC);

Expand All @@ -221,17 +222,15 @@ javascriptGenerator.forBlock['jigsaw_toast'] = function (block: Blockly.Block, g

// TODO: temporary way to make the variables reactive.
// Try to separate normal variable from reactive/state variables.
/*
javascriptGenerator.forBlock['variables_set'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['variables_set'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const var_name = generator.getVariableName(block.getFieldValue("VAR"))
const var_value = generator.valueToCode(block, 'VALUE', Order.ATOMIC);

return `${var_name}.value = ${var_value};\n`
return `state.${var_name} = ${var_value};\n`
}

javascriptGenerator.forBlock['variables_get'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
vueGenerator.forBlock['variables_get'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
const var_name = generator.getVariableName(block.getFieldValue("VAR"))

return [`${var_name}.value`, Order.ATOMIC]
return [`state.${var_name}`, Order.ATOMIC]
}
*/

0 comments on commit 06021a5

Please sign in to comment.