Skip to content

Commit

Permalink
Merge pull request #11 from N-J-Martin/blockDataInput
Browse files Browse the repository at this point in the history
block data input block
  • Loading branch information
N-J-Martin authored Mar 12, 2024
2 parents 59530dd + aa2da27 commit 52434b5
Show file tree
Hide file tree
Showing 7 changed files with 220 additions and 49 deletions.
42 changes: 42 additions & 0 deletions src/blocks/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// A variation of code from https://blocklycodelabs.dev/codelabs/custom-generator/index.html?index=..%2F..index#0

import * as Blockly from 'blockly';

export const jsonBlocks = Blockly.common.createBlockDefinitionsFromJsonArray([{
"type": "object",
"message0": "{ %1 %2 }",
"args0": [
{
"type": "input_dummy"
},
{
"type": "input_statement",
"name": "MEMBERS"
}
],
"output": null,
"colour": 230,
},
{
"type": "member",
"message0": "%1 %2 %3",
"args0": [
{
"type": "input_value",
"name": "MEMBER_NAME",
},
{
"type": "field_label",
"name": "COLON",
"text": ":"
},
{
"type": "input_value",
"name": "MEMBER_VALUE"
}
],
"previousStatement": null,
"nextStatement": null,
"colour": 230,
"inputsInline": true
}]);
34 changes: 0 additions & 34 deletions src/generators/javascript.js

This file was deleted.

70 changes: 70 additions & 0 deletions src/generators/json.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// A variation of code from https://blocklycodelabs.dev/codelabs/custom-generator/index.html?index=..%2F..index#0


import * as Blockly from 'blockly';

export const jsonGenerator = new Blockly.Generator('JSON');
const Order = {
ATOMIC: 0,
};

jsonGenerator.forBlock['logic_null'] = function(block) {
return ['null', Order.ATOMIC];
};


jsonGenerator.forBlock['text'] = function(block) {
const textValue = block.getFieldValue('TEXT');
const code = `"${textValue}"`;
return [code, Order.ATOMIC];

};

jsonGenerator.forBlock['math_number'] = function(block) {
const code = String(block.getFieldValue('NUM'));
return [code, Order.ATOMIC];
};

jsonGenerator.forBlock['logic_boolean'] = function(block) {
const code = (block.getFieldValue('BOOL') === 'TRUE') ? 'true' : 'false';
return [code, Order.ATOMIC];
};

jsonGenerator.forBlock['member'] = function(block, generator) {
const name = generator.valueToCode(block, 'MEMBER_NAME', Order.ATOMIC);
const value = generator.valueToCode(block, 'MEMBER_VALUE', Order.ATOMIC);
const code = `"${name}": ${value}`;
return code;
};

jsonGenerator.forBlock['lists_create_with'] = function(block, generator) {
const values = [];
for (let i = 0; i < block.itemCount_; i++) {
const valueCode = generator.valueToCode(block, 'ADD' + i,
Order.ATOMIC);
if (valueCode) {
values.push(valueCode);
}
}
const valueString = values.join(',\n');
const indentedValueString =
generator.prefixLines(valueString, generator.INDENT);
const codeString = '[\n' + indentedValueString + '\n]';
return [codeString, Order.ATOMIC];
};

jsonGenerator.forBlock['object'] = function(block, generator) {
const statementMembers =
generator.statementToCode(block, 'MEMBERS');
const code = '{\n' + statementMembers + '\n}';
return [code, Order.ATOMIC];
};

jsonGenerator.scrub_ = function(block, code, thisOnly) {
const nextBlock =
block.nextConnection && block.nextConnection.targetBlock();
if (nextBlock && !thisOnly) {
return code + ',\n' + jsonGenerator.blockToCode(nextBlock);
}
return code;
};
6 changes: 6 additions & 0 deletions src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ pre, code {
min-width: 600px;
}

#dataInputDiv {
flex-basis: 100%;
height: 100%;
min-width: 600px;
}

#outputPane {
display: flex;
flex-direction: column;
Expand Down
7 changes: 5 additions & 2 deletions src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@
<body>
<div id="pageContainer">
<div id="outputPane">
<h3>Generated Essence Code</h3>
<pre id="generatedCode"><code></code></pre>
<h3>JSON Solution</h3>
<div id="output"></div>
</div>
<div id="blocklyDiv"></div>
<div id="blocklyDiv2"></div>
<div id="blocklyDiv"><h3>Block Essence</h3></div>
<div id = "dataInputDiv"><h3>Block Data Input</h3></div>
<div id="blocklyDiv2"><h3>Block Solution</h3></div>
</div>
</body>
</html>
66 changes: 53 additions & 13 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,32 @@ import * as Blockly from 'blockly';
import {TypedVariableModal} from '@blockly/plugin-typed-variable-modal';
//import {blocks} from './blocks/text';
import {blocks} from './blocks/essence';
import {jsonBlocks} from './blocks/json';
import {essenceGenerator} from './generators/essence';
import {jsonGenerator} from './generators/json';
import {save, load} from './serialization';
import {toolbox} from './toolbox';
import {jsonToolbox} from './jsonToolbox';
import './index.css';
import { variables } from 'blockly/blocks';

// Register the blocks and generator with Blockly
Blockly.common.defineBlocks(blocks);
//Object.assign(javascriptGenerator.forBlock, forBlock);
Blockly.common.defineBlocks(jsonBlocks);

// Set up UI elements and inject Blockly
const codeDiv = document.getElementById('generatedCode').firstChild;
const outputDiv = document.getElementById('output');
const blocklyDiv = document.getElementById('blocklyDiv');
const dataDiv = document.getElementById("dataInputDiv");
const ws = Blockly.inject(blocklyDiv, {toolbox});
const blockOut = Blockly.inject(document.getElementById('blocklyDiv2'), {});
const dataWS = Blockly.inject(dataDiv, {toolbox: jsonToolbox});
// adds start block to data input section
let startBlock = dataWS.newBlock("object");
startBlock.initSvg();
dataWS.render()

const blockOut = Blockly.inject(document.getElementById('blocklyDiv2'), {readOnly:true});

//variable category using https://www.npmjs.com/package/@blockly/plugin-typed-variable-modal.
// much of the code below is from the usage instructions
Expand Down Expand Up @@ -54,20 +64,43 @@ ws.registerToolboxCategoryCallback(
createFlyout,
);

// adding variable category to data input WS
const createDataFlyout = function () {
let xmlList = [];
const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(ws);
xmlList = xmlList.concat(blockList);
// adjust so forced to set variables by declarations.
xmlList.splice(0,1);
return xmlList;
};


dataWS.registerToolboxCategoryCallback(
'GET_VARIABLE',
createDataFlyout,
);

// setting up typed var model
const typedVarModal = new TypedVariableModal(ws, 'callbackName', [
['int', 'int'],
['enum', 'enum'],
['unnamed', 'unnamed']
]);
typedVarModal.init();

// generator
// generators for get variable block
essenceGenerator.forBlock['variables_get_dynamic'] = function(block) {
var vars = block.getVars()
const code = ws.getVariableById(vars[0]).name
return [code, 0];
}

jsonGenerator.forBlock['variables_get_dynamic'] = function(block) {
var vars = block.getVars()
const code = dataWS.getVariableById(vars[0]).name
return [code, 0];
}

//add output button
var outputButton = document.createElement("BUTTON");
var outputButtonText = document.createTextNode("SOLVE");
Expand Down Expand Up @@ -129,7 +162,8 @@ function printGeneratedCode(){
console.log(essenceGenerator.workspaceToCode(ws));
}

// from https://conjure-aas.cs.st-andrews.ac.uk/submitDemo.html
// submits data and code to conjure
//from https://conjure-aas.cs.st-andrews.ac.uk/submitDemo.html
async function submit(inputData) {
return new Promise((resolve, reject) => {
fetch("https://conjure-aas.cs.st-andrews.ac.uk/submit", {
Expand All @@ -147,7 +181,8 @@ async function submit(inputData) {
.then(json => resolve(json.jobid))
.catch(err => reject(err))
})}


// get conjure solution/ response
async function get(currentJobid) {
return new Promise((resolve, reject) => {
fetch("https://conjure-aas.cs.st-andrews.ac.uk/get", {
Expand All @@ -167,27 +202,30 @@ async function get(currentJobid) {

}

// Runs essence code in conjure, outputs solution logs
// from https://conjure-aas.cs.st-andrews.ac.uk/submitDemo.html
async function getSolution() {
let data = prompt("Please enter the data used in JSON format", "{\n\n}");
if (data == null || data == ""){
data = "{}";
}
// gets the data from the data input workspace
let data = jsonGenerator.workspaceToCode(dataWS) + "\n";
console.log("data" + data);
solutionText.innerHTML = "Solving..."
// waits for code to be submitted to conjure, until jobID returned
const currentJobid = await submit(data);
// get solution for our job. Need to wait until either solution found, code failed, or timed out
var solution = await get(currentJobid);
while (solution.status == 'wait'){
solution = await get(currentJobid);
}
// outputs text solution
solutionText.innerHTML = JSON.stringify(solution, undefined, 2);

// if solved, create relevant blocks and add to output workspace
if (solution.status == "ok"){
for (let sol of solution.solution){
for (let v in sol){
blockOut.createVariable(v);
let varBlock = blockOut.newBlock('variables_set');
varBlock.setFieldValue(blockOut.getVariable(v).getId(), 'VAR');
//console.log(typeof(sol[v]));
let valueBlock;
switch (typeof(sol[v])){
case("bigint"):
Expand All @@ -210,9 +248,11 @@ async function getSolution() {

};
varBlock.getInput("VALUE").connection.connect(valueBlock.outputConnection);
let addVarBlock = new Blockly.Events.BlockCreate(varBlock);
addVarBlock.run(true);

//let addVarBlock = new Blockly.Events.BlockCreate(varBlock);
//addVarBlock.run(true);
varBlock.initSvg();
valueBlock.initSvg();
blockOut.render();
}
}

Expand Down
44 changes: 44 additions & 0 deletions src/jsonToolbox.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// A variation of code from https://blocklycodelabs.dev/codelabs/custom-generator/index.html?index=..%2F..index#0

export const jsonToolbox = {
'kind': 'categoryToolbox',
'contents': [ {
'kind' : 'category',
'name' : 'Values',
'contents': [
{
'kind': 'block',
'type': 'object'
},
{
'kind': 'block',
'type': 'member'
},
{
'kind': 'block',
'type': 'math_number'
},
{
'kind': 'block',
'type': 'text'
},
{
'kind': 'block',
'type': 'logic_boolean'
},
{
'kind': 'block',
'type': 'logic_null'
},
{
'kind': 'block',
'type': 'lists_create_with'
},
]},
{
'kind': 'category',
'name': 'Variables',
'custom': 'GET_VARIABLE'
}
]
}

0 comments on commit 52434b5

Please sign in to comment.