feat: sync arduino source board configurations

This commit is contained in:
yczpf2019
2026-01-24 16:16:48 +08:00
parent 6dce82e125
commit c9195c03e1
1051 changed files with 59815 additions and 0 deletions

View File

@@ -0,0 +1,165 @@
import * as Blockly from 'blockly/core';
import Names from './others/names';
export class ArduinoGenerator extends Blockly.Generator {
constructor(name) {
super(name ?? 'Arduino')
this.ORDER_ATOMIC = 0 // 0 "" ...
this.ORDER_UNARY_POSTFIX = 1 // expr++ expr-- () [] .
this.ORDER_UNARY_PREFIX = 2 // -expr !expr ~expr ++expr --expr
this.ORDER_MULTIPLICATIVE = 3 // * / % ~/
this.ORDER_ADDITIVE = 4 // + -
this.ORDER_SHIFT = 5 // << >>
this.ORDER_RELATIONAL = 6 // is is! >= > <= <
this.ORDER_EQUALITY = 7 // == != === !==
this.ORDER_BITWISE_AND = 8 // &
this.ORDER_BITWISE_XOR = 9 // ^
this.ORDER_BITWISE_OR = 10 // |
this.ORDER_LOGICAL_AND = 11 // &&
this.ORDER_LOGICAL_OR = 12 // ||
this.ORDER_CONDITIONAL = 13 // expr ? expr : expr
this.ORDER_ASSIGNMENT = 14 // = *= /= ~/= %= += -= <<= >>= &= ^= |=
this.ORDER_NONE = 99 // (...)
this.INDENT = ' '
this.isInitialized = false
this.PASS = ''
this.addReservedWords(
'setup,loop,if,else,for,switch,case,while,do,break,continue,return,goto,define,include,HIGH,LOW,INPUT,OUTPUT,INPUT_PULLUP,true,false,interger,constants,floating,point,void,bookean,char,unsigned,byte,int,short,word,long,float,double,string,String,array,static,volatile,const,sizeof'
)
}
init() {
super.init();
// Create a dictionary of definitions to be printed before setups.
this.definitions_ = Object.create(null)
// Create a dictionary of setups to be printed before the code.
this.setups_ = Object.create(null)
this.setups_begin_ = Object.create(null)
this.setups_end_ = Object.create(null)
this.libs_ = Object.create(null)
this.loops_begin_ = Object.create(null)
this.loops_end_ = Object.create(null)
//this.variableTypes_ = Object.create(null);//处理变量类型
if (!this.variableDB_) {
this.variableDB_ = new Names(
this.RESERVED_WORDS_
)
} else {
this.variableDB_.reset()
}
this.isInitialized = true;
}
finish(code) {
// Indent every line.
code = ' ' + code.replace(/\n/g, '\n ');
code = code.replace(/\n\s+$/, '\n');
// Convert the definitions dictionary into a list.
var imports = [];
var define = [];
var definitions_var = []; //变量定义
var definitions_fun = []; //函数定义
//var sorted_keys=Object.keys(this.definitions_).sort();
var sorted_keys = Object.keys(this.definitions_);
if (sorted_keys.length) {
for (var idx in sorted_keys) {
var name = sorted_keys[idx];
var def = this.definitions_[name];
if (name.match(/^define/)) {
define.push(def);
} else if (name.match(/^include/)) {
imports.push(def);
} else if (def.match(/^WiFiClient/)) {
imports.push(def);
} else if (name.match(/^var_declare/)) {
definitions_var.push(def);
} else {
definitions_fun.push(def);
}
}
}
// Convert the setups dictionary into a list.
var setups = [];
for (let name in this.setups_) {
setups.push(this.setups_[name]);
}
var setupsBegin = [], setupsEnd = [];
for (let name in this.setups_begin_) {
setupsBegin.push(this.setups_begin_[name]);
}
for (let name in this.setups_end_) {
setupsEnd.push(this.setups_end_[name]);
}
for (let name in this.libs_) {
imports.push(`#include "${name}.h"`);
}
var loopsBegin = [], loopsEnd = [];
for (let name in this.loops_begin_) {
loopsBegin.push(this.loops_begin_[name]);
}
for (let name in this.loops_end_) {
loopsEnd.push(this.loops_end_[name]);
}
code = 'void loop() {\n'
+ (loopsBegin.length ? (' ' + loopsBegin.join('\n ')) : '')
+ code
+ (loopsEnd.length ? (' ' + loopsEnd.join('\n ')) : '')
+ '\n}';
var allDefs = define.join('\n') + '\n' + imports.join('\n') + '\n\n'
+ definitions_var.join('\n')
+ '\n\n' + definitions_fun.join('\n')
+ '\n\nvoid setup() {\n '
+ setupsBegin.join('\n ') + ((setupsBegin.length && (setupsEnd.length || setups.length)) ? '\n ' : '')
+ setups.join('\n ') + ((setupsEnd.length && setups.length) ? '\n ' : '')
+ setupsEnd.join('\n ') + '\n}' + '\n\n';
return allDefs.replace(/\n\n+/g, '\n\n').replace(/\n*$/, '\n\n') + code;
}
scrubNakedValue(line) {
return line + ';\n'
}
quote_(string) {
// TODO: This is a quick hack. Replace with goog.string.quote
//return goog.string.quote(string);
return "\"" + string + "\"";
}
scrub_(block, code) {
if (code === null) {
// Block has handled code generation itself.
return '';
}
var commentCode = '';
// Only collect comments for blocks that aren't inline.
if (!block.outputConnection || !block.outputConnection.targetConnection) {
// Collect comment for this block.
let comment = block.getCommentText();
if (comment) {
commentCode += this.prefixLines(comment, '// ') + '\n';
}
// Collect comments for all value arguments.
// Don't collect comments for nested statements.
for (var x = 0; x < block.inputList.length; x++) {
if (block.inputList[x].type == Blockly.INPUT_VALUE) {
var childBlock = block.inputList[x].connection.targetBlock();
if (childBlock) {
let comment = this.allNestedComments(childBlock);
if (comment) {
commentCode += this.prefixLines(comment, '// ');
}
}
}
}
}
var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
var nextCode = this.blockToCode(nextBlock);
return commentCode + code + nextCode;
}
}
export const Arduino = new ArduinoGenerator();

View File

@@ -0,0 +1,223 @@
import * as Blockly from 'blockly/core';
import CITYS_DATA from '../templates/json/cities.json';
const ETHERNET_HUE = 0;
const WEATHER_HUE = '#27b6ac';
/**
* @name 模块名 Http GET请求
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
*/
export const http_get = {
init: function () {
this.appendDummyInput()
.appendField(Blockly.Msg.MIXLY_ETHERNET_CLINET_GET_REQUEST);
this.appendValueInput("api")
.setCheck(null)
.appendField(Blockly.Msg.blynk_SERVER_ADD);
this.appendStatementInput("success")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_SUCCESS);
this.appendStatementInput("failure")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_FAILED);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(ETHERNET_HUE);
this.setTooltip("");
}
};
/**
* @name 模块名 Http PATCH|POST|PUT请求
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
*/
export const http_post = {
init: function () {
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown([
["POST", "POST"],
["PATCH", "PATCH"],
["PUT", "PUT"]
]), "TYPE")
.appendField(Blockly.Msg.blockpy_REQUESTS);
this.appendValueInput("api")
.setCheck(null)
.appendField(Blockly.Msg.blynk_SERVER_ADD);
this.appendValueInput("data")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_SD_DATA);
this.appendStatementInput("success")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_SUCCESS);
this.appendStatementInput("failure")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_FAILED);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(ETHERNET_HUE);
this.setTooltip("");
}
};
var PROVINCES = [], key;
for (key in CITYS_DATA)
PROVINCES.push([key, key]);
function getCitysByProvince(a) {
var b = [], c;
for (c in CITYS_DATA[a])
b.push([c, c]);
return b;
}
var citysByProvince = {};
for (key of PROVINCES) {
citysByProvince[key[0]] = getCitysByProvince(key[0]);
}
export const china_city = {
init: function () {
const defaultOptions = [["-", "-"]];
this.appendDummyInput()
.appendField(new Blockly.FieldDropdown(PROVINCES), "province")
.appendField(new Blockly.FieldDependentDropdown("province", citysByProvince, defaultOptions), "city");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(WEATHER_HUE);
this.setHelpUrl("");
this.preProvince = null;
}
};
export const weather_private_key = {
init: function () {
this.setColour(WEATHER_HUE);
this.appendDummyInput("")
.appendField(new Blockly.FieldDropdown([['S9l2sb_ZK-UsWaynG', 'S9l2sb_ZK-UsWaynG'], ['SpRpSYb7QOMT0M8Tz', 'SpRpSYb7QOMT0M8Tz'], ['SboqGMxP4tYNXUN8f', 'SboqGMxP4tYNXUN8f'], ['SJiRrYGYFkGnfi081', 'SJiRrYGYFkGnfi081'], ['SMhSshUxuTL0GLVLS', 'SMhSshUxuTL0GLVLS']]), 'key');
this.setOutput(true, null);
}
};
export const weather_seniverse_city_weather = {
init: function () {
this.appendDummyInput("")
.appendField(Blockly.Msg.MSG.catweather)
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"], [Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"], [Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]]), "api")
.appendField(Blockly.Msg.MIXLY_INFORMATION_CONFIGURATION);
this.appendValueInput("location")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_GEOGRAPHIC_LOCATION);
this.appendValueInput("private_key")
.setCheck(null)
.appendField(Blockly.Msg.MIXLY_API_PRIVATE_KEY);
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_LANGUAGE)
.appendField(new Blockly.FieldDropdown([
["简体中文", "zh-Hans"],
["繁體中文", "zh-Hant"],
["English", "en"]
]), "language");
this.appendDummyInput("")
.appendField(Blockly.Msg.MIXLY_TEMPERATURE_UNIT)
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_CELSIUS + "(℃)", "c"], [Blockly.Msg.MIXLY_FAHRENHEIT + "(℉)", "f"]]), "unit");
this.setInputsInline(false);
this.setPreviousStatement(true, null);
this.setNextStatement(true, null);
this.setColour(WEATHER_HUE);
this.setTooltip("这里的API私钥免费体验有次数限制\n访问频率限制20次/分钟");
this.setHelpUrl("");
}
};
export const weather_get_seniverse_weather_info = {
init: function () {
this.appendDummyInput("")
//.appendField("心知天气")
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_LIVE_WEATHER, "weather/now"],
[Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST, "weather/daily"],
[Blockly.Msg.MIXLY_6_LIFE_INDEXES, "life/suggestion"]
]), "api")
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_AVAILABLE, "update"],
[Blockly.Msg.MIXLY_GET_DATA_UPDATE_TIME, "getLastUpdate"],
[Blockly.Msg.MIXLY_GET_SERVER_RESPONSE_STATUS_CODE, "getServerCode"]
]), "type");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(WEATHER_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};
export const weather_get_seniverse_weather_info1 = {
init: function () {
this.appendDummyInput("")
//.appendField("心知天气")
.appendField(Blockly.Msg.MIXLY_LIVE_WEATHER)
.appendField(Blockly.Msg.MIXLY_GET)
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_WEATHER_PHENOMENON, "getWeatherText"], [Blockly.Msg.MIXLY_WEATHER_PHENOMENON_CODE, "getWeatherCode"], [Blockly.Msg.MIXLY_TEMPERATURE, "getDegree"]]), "type");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(WEATHER_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};
export const weather_get_seniverse_weather_info2 = {
init: function () {
this.appendDummyInput("")
//.appendField("心知天气")
.appendField(Blockly.Msg.MIXLY_3_DAY_WEATHER_FORECAST)
.appendField(Blockly.Msg.MIXLY_GET)
.appendField(new Blockly.FieldDropdown([[Blockly.Msg.MIXLY_TODAY, "0"], [Blockly.Msg.MIXLY_TOMORROW, "1"], [Blockly.Msg.MIXLY_DAY_AFTER_TOMORROW, "2"]]), "date")
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.ForecastHigh, "getHigh"],
[Blockly.Msg.ForecastLow, "getLow"],
[Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON, "getDayText"],
[Blockly.Msg.MIXLY_DAYTIME_WEATHER_PHENOMENON_CODE, "getDayCode"],
[Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON, "getNightText"],
[Blockly.Msg.MIXLY_EVENING_WEATHER_PHENOMENON_CODE, "getNightCode"],
[Blockly.Msg.MIXLY_PROBABILITY_OF_PRECIPITATION, "getRain"],
[Blockly.Msg.ForecastFx, "getWindDirection"],
[Blockly.Msg.MIXLY_WIND_SPEED, "getWindSpeed"],
[Blockly.Msg.MIXLY_WIND_RATING, "getWindScale"],
[Blockly.Msg.MIXLY_Humidity, "getHumidity"]
]), "type");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(WEATHER_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};
export const weather_get_seniverse_weather_info3 = {
init: function () {
this.appendDummyInput("")
//.appendField("心知天气")
.appendField(Blockly.Msg.MIXLY_6_LIFE_INDEXES)
.appendField(Blockly.Msg.MIXLY_GET)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_CAR_WASH_INDEX, "getCarWash"],
[Blockly.Msg.MIXLY_DRESSING_INDEX, "getDressing"],
[Blockly.Msg.MIXLY_COLD_INDEX, "getFactorFlu"],
[Blockly.Msg.MIXLY_MOVEMENT_INDEX, "getExercise"],
[Blockly.Msg.MIXLY_TOURISM_INDEX, "getTravel"],
[Blockly.Msg.MIXLY_UV_INDEX, "getUV"]]
), "type");
this.setInputsInline(true);
this.setOutput(true, null);
this.setColour(WEATHER_HUE);
this.setTooltip("");
this.setHelpUrl("");
}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,24 @@
import * as Blockly from 'blockly/core';
const TEXTS_HUE = 160;
export const text_base64_url_codec = {
init: function () {
this.appendValueInput('VALUE')
.setCheck(null)
.setAlign(Blockly.inputs.Align.LEFT)
.appendField(new Blockly.FieldDropdown([
['Base64', 'BASE64'],
['URL', 'URL']
]), 'TYPE')
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXPY_TEXT_ENCODE, 'ENCODE'],
[Blockly.Msg.MIXPY_TEXT_DECODE, 'DECODE']
]), 'OPTION');
this.setOutput(true, null);
this.setColour(TEXTS_HUE);
this.setTooltip('');
this.setHelpUrl('');
}
};

View File

@@ -0,0 +1,85 @@
import * as Blockly from 'blockly/core';
import { Variables } from 'blockly/core';
const VARIABLES_HUE = 330;
export const variables_declare = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput('VALUE', null)
.appendField(Blockly.Msg.MIXLY_DECLARE)
.appendField(new Blockly.FieldDropdown([
[Blockly.Msg.MIXLY_GLOBAL_VARIABLE, 'global_variate'],
[Blockly.Msg.MIXLY_LOCAL_VARIABLE, 'local_variate']
]), 'variables_type')
.appendField(new Blockly.FieldTextInput('item'), 'VAR')
.appendField(Blockly.Msg.MIXLY_AS)
.appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), 'TYPE')
.appendField(Blockly.Msg.MIXLY_VALUE);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_DECLARE);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setFieldValue(newName, 'VAR');
}
}
};
export const variables_get = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('item'), 'VAR')
this.setOutput(true);
this.setTooltip(Blockly.Msg.VARIABLES_GET_TOOLTIP);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setFieldValue(newName, 'VAR');
}
}
};
export const variables_set = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput('VALUE')
.appendField(new Blockly.FieldTextInput('item'), 'VAR')
.appendField(Blockly.Msg.MIXLY_VALUE2);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.setTooltip(Blockly.Msg.VARIABLES_SET_TOOLTIP);
},
getVars: function () {
return [this.getFieldValue('VAR')];
},
renameVar: function (oldName, newName) {
if (Blockly.Names.equals(oldName, this.getFieldValue('VAR'))) {
this.setFieldValue(newName, 'VAR');
}
}
};
/**
* Block for basic data type change.
* @this Blockly.Block
*/
export const variables_change = {
init: function () {
this.setColour(VARIABLES_HUE);
this.appendValueInput('MYVALUE')
.appendField(new Blockly.FieldDropdown(Variables.DATA_TYPE), 'OP');
// Assign 'this' to a variable for use in the tooltip closure below.
this.setOutput(true);
this.setTooltip(Blockly.Msg.MIXLY_TOOLTIP_VARIABLES_CHANGE);
}
};

View File

@@ -0,0 +1,28 @@
import * as ArduinoEthernetBlocks from './blocks/ethernet';
import * as ArduinoProceduresBlocks from './blocks/procedures';
import * as ArduinoTextBlocks from './blocks/text';
import * as ArduinoVariablesBlocks from './blocks/variables';
import * as ArduinoProceduresGenerators from './generators/procedures';
import * as ArduinoEthernetGenerators from './generators/ethernet';
import * as ArduinoTextGenerators from './generators/text';
import * as ArduinoVariablesGenerators from './generators/variables';
import Names from './others/names';
import Procedures from './others/procedures';
import Variables from './others/variables';
import { ArduinoGenerator, Arduino } from './arduino_generator';
export {
ArduinoEthernetBlocks,
ArduinoProceduresBlocks,
ArduinoTextBlocks,
ArduinoVariablesBlocks,
ArduinoEthernetGenerators,
ArduinoProceduresGenerators,
ArduinoTextGenerators,
ArduinoVariablesGenerators,
Names,
Procedures,
Variables,
ArduinoGenerator,
Arduino
};

View File

@@ -0,0 +1,196 @@
import * as Blockly from 'blockly/core';
import * as Mixly from 'mixly';
import CITYS_DATA from '../templates/json/cities.json';
/**
* @name 模块名 Http GET请求
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
*/
export const http_get = function () {
const BOARD_TYPE = Mixly.Boards.getType();
const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
branch = branch.replace(/(^\s*)|(\s*$)/g, "");
let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
let code = '';
if (BOARD_TYPE == 'arduino_esp8266') {
Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include <ESP8266HTTPClient.h>';
code
= 'if (WiFi.status() == WL_CONNECTED) {\n'
+ ' WiFiClient client;\n'
+ ' HTTPClient http;\n'
+ ' http.begin(client, ' + API + ');\n'
+ ' int httpCode = http.GET();\n'
+ ' if (httpCode > 0) {\n'
+ ' String Request_result = http.getString();\n'
+ ' ' + branch + '\n'
+ ' } else {\n'
+ ' ' + branch1 + '\n'
+ ' }\n'
+ ' http.end();\n'
+ '}\n';
} else {
Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
Blockly.Arduino.definitions_['include_HTTPClient'] = '#include <HTTPClient.h>';
code
= 'if (WiFi.status() == WL_CONNECTED) {\n'
+ ' HTTPClient http;\n'
+ ' http.begin(' + API + ');\n'
+ ' int httpCode = http.GET();\n'
+ ' if (httpCode > 0) {\n'
+ ' String Request_result = http.getString();\n'
+ ' ' + branch + '\n'
+ ' }\n'
+ ' else {\n'
+ ' ' + branch1 + '\n'
+ ' }\n'
+ ' http.end();\n'
+ '}\n';
}
return code;
};
/**
* @name 模块名 Http PATCH|POST|PUT请求
* @support 支持板卡 {ESP8266, ESP32, ESP32C3, ESP32S2, ESP32S3}
*/
export const http_post = function () {
const BOARD_TYPE = Mixly.Boards.getType();
const FIELD_TYPE = this.getFieldValue("TYPE");
const API = Blockly.Arduino.valueToCode(this, 'api', Blockly.Arduino.ORDER_ATOMIC);
const DATA = Blockly.Arduino.valueToCode(this, 'data', Blockly.Arduino.ORDER_ATOMIC);
let branch = Blockly.Arduino.statementToCode(this, 'success') || '';
branch = branch.replace(/(^\s*)|(\s*$)/g, "");
let branch1 = Blockly.Arduino.statementToCode(this, 'failure') || '';
branch1 = branch1.replace(/(^\s*)|(\s*$)/g, "");
let code = '';
if (BOARD_TYPE == 'arduino_esp8266') {
Blockly.Arduino.definitions_['include_ESP8266WiFi'] = '#include <ESP8266WiFi.h>';
Blockly.Arduino.definitions_['include_ESP8266HTTPClient'] = '#include <ESP8266HTTPClient.h>';
code
= 'if (WiFi.status() == WL_CONNECTED) {\n'
+ ' HTTPClient http;\n'
+ ' WiFiClient client;\n'
+ ' http.begin(client, ' + API + ');\n'
+ ' http.addHeader("Content-Type", "application/json");\n'
+ ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
+ ' if (httpCode > 0) {\n'
+ ' String Request_result = http.getString();\n'
+ ' ' + branch + '\n'
+ ' } else {\n'
+ ' ' + branch1 + '\n'
+ ' }\n'
+ ' http.end();\n'
+ '}\n';
} else {
Blockly.Arduino.definitions_['include_WiFi'] = '#include <WiFi.h>';
Blockly.Arduino.definitions_['include_HTTPClient'] = '#include <HTTPClient.h>';
code
= 'if (WiFi.status() == WL_CONNECTED) {\n'
+ ' HTTPClient http;\n'
+ ' http.begin(' + API + ');\n'
+ ' http.addHeader("Content-Type", "application/json");\n'
+ ' int httpCode = http.' + FIELD_TYPE + '(' + DATA + ');\n'
+ ' if (httpCode > 0) {\n'
+ ' String Request_result = http.getString();\n'
+ ' ' + branch + '\n'
+ ' }\n'
+ ' else {\n'
+ ' ' + branch1 + '\n'
+ ' }\n'
+ ' http.end();\n'
+ '}\n';
}
return code;
};
//网络天气
export const china_city = function () {
var a = this.getFieldValue("province");
var b = this.getFieldValue("city");
var code = "";
try {
code = '"' + CITYS_DATA[a][b].pinyin + '"';
} catch (e) {
console.log(e);
}
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
export const weather_private_key = function () {
var a = this.getFieldValue("key");
var code = '"' + a + '"';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
export const weather_seniverse_city_weather = function () {
var api = this.getFieldValue("api");
var location = Blockly.Arduino.valueToCode(this, "location", Blockly.Arduino.ORDER_ATOMIC);
var private_key = Blockly.Arduino.valueToCode(this, "private_key", Blockly.Arduino.ORDER_ATOMIC);
//private_key = private_key.replace(/\"/g, "")
var language = this.getFieldValue("language");
var unit = this.getFieldValue("unit");
Blockly.Arduino.definitions_['include_ESP8266_Seniverse'] = '#include <ESP8266_Seniverse.h>';
Blockly.Arduino.setups_['setup_serial_Serial'] = 'Serial.begin(9600);';
switch (api) {
case 'weather/now':
Blockly.Arduino.definitions_['var_declare_weatherNow'] = 'WeatherNow weatherNow;';
Blockly.Arduino.setups_['setup_seniverse_weatherNow'] = 'weatherNow.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
break;
case 'weather/daily':
Blockly.Arduino.definitions_['var_declare_forecast'] = 'Forecast forecast;';
Blockly.Arduino.setups_['setup_seniverse_forecast'] = 'forecast.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
break;
case 'life/suggestion':
default:
Blockly.Arduino.definitions_['var_declare_lifeInfo'] = 'LifeInfo lifeInfo;';
Blockly.Arduino.setups_['setup_seniverse_lifeInfo'] = 'lifeInfo.config(' + private_key + ', ' + location + ', "' + unit + '", "' + language + '");';
}
var code = '';
return code;
};
export const weather_get_seniverse_weather_info = function () {
var api = this.getFieldValue("api");
var type = this.getFieldValue("type");
var code = '';
switch (api) {
case 'weather/now':
code = 'weatherNow.' + type + '()';
break;
case 'weather/daily':
code = 'forecast.' + type + '()';
break;
case 'life/suggestion':
default:
code = 'lifeInfo.' + type + '()';
}
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
export const weather_get_seniverse_weather_info1 = function () {
var type = this.getFieldValue("type");
var code = 'weatherNow.' + type + '()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
export const weather_get_seniverse_weather_info2 = function () {
var date = this.getFieldValue("date");
var type = this.getFieldValue("type");
var code = 'forecast.' + type + '(' + date + ')';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};
export const weather_get_seniverse_weather_info3 = function () {
var type = this.getFieldValue("type");
var code = 'lifeInfo.' + type + '()';
return [code, Blockly.Arduino.ORDER_ATOMIC];
};

View File

@@ -0,0 +1,114 @@
import { Variables, Procedures } from 'blockly/core';
export const procedures_defreturn = function (_, generator) {
// Define a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Procedures.NAME_TYPE);
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + this.id + '\'') + branch;
}
var returnValue = generator.valueToCode(this, 'RETURN',
generator.ORDER_NONE) || '';
var type = this.getFieldValue('TYPE');
if (type === 'CUSTOM') {
if (this.getField('RETRUN_TYPE')) {
type = this.getFieldValue('RETRUN_TYPE');
} else {
type = 'void';
}
}
if (returnValue) {
returnValue = ' return ' + returnValue + ';\n';
}
var returnType = type ? type : 'void';
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
Variables.NAME_TYPE);
}
var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
branch + returnValue + '}\n';
code = generator.scrub_(this, code);
generator.definitions_[funcName] = code;
return null;
}
export const procedures_defnoreturn = function (_, generator) {
// Define a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Procedures.NAME_TYPE);
var branch = (this.getInput('STACK') && generator.statementToCode(this, 'STACK'));
if (generator.INFINITE_LOOP_TRAP) {
branch = generator.INFINITE_LOOP_TRAP.replace(/%1/g,
'\'' + this.id + '\'') + branch;
}
var returnType = 'void';
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = this.argumentstype_[x] + ' ' + generator.variableDB_.getName(this.arguments_[x],
Variables.NAME_TYPE);
}
var code = returnType + ' ' + funcName + '(' + args.join(', ') + ') {\n' +
branch + '}\n';
code = generator.scrub_(this, code);
generator.definitions_[funcName] = code;
return null;
}
export const procedures_callreturn = function (_, generator) {
// Call a procedure with a return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Procedures.NAME_TYPE);
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = generator.valueToCode(this, 'ARG' + x,
generator.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ')';
return [code, generator.ORDER_UNARY_POSTFIX];
}
export const procedures_callnoreturn = function (_, generator) {
// Call a procedure with no return value.
var funcName = generator.variableDB_.getName(this.getFieldValue('NAME'),
Procedures.NAME_TYPE);
var args = [];
for (var x = 0; x < this.arguments_.length; x++) {
args[x] = generator.valueToCode(this, 'ARG' + x,
generator.ORDER_NONE) || 'null';
}
var code = funcName + '(' + args.join(', ') + ');\n';
return code;
}
export const procedures_ifreturn = function (_, generator) {
// Conditionally return value from a procedure.
var condition = generator.valueToCode(this, 'CONDITION',
generator.ORDER_NONE) || 'false';
var code = 'if (' + condition + ') {\n';
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || '';
code += ' return ' + value + ';\n';
} else {
code += ' return;\n';
}
code += '}\n';
return code;
}
export const procedures_return = function (_, generator) {
// Conditionally return value from a procedure.
var code = ""
if (this.hasReturnValue_) {
var value = generator.valueToCode(this, 'VALUE',
generator.ORDER_NONE) || 'None';
code += 'return ' + value + ';\n';
} else {
code += 'return;\n';
}
code += '\n';
return code;
}

View File

@@ -0,0 +1,37 @@
import * as Blockly from 'blockly/core';
export const text_base64_url_codec = function () {
const FIELD_TYPE = this.getFieldValue("TYPE");
const FIELD_OPTION = this.getFieldValue("OPTION");
const VALUE_INPUT_VALUE = Blockly.Arduino.valueToCode(this, "VALUE", Blockly.Arduino.ORDER_ATOMIC);
let code = '';
if (FIELD_TYPE === 'BASE64') {
Blockly.Arduino.definitions_['include_rBase64'] = '#include <rBase64.h>';
if (FIELD_OPTION === 'ENCODE') {
code = 'rbase64.encode(' + VALUE_INPUT_VALUE + ')';
} else {
code = 'rbase64.decode(' + VALUE_INPUT_VALUE + ')';
}
} else {
Blockly.Arduino.definitions_['include_URLCode'] = '#include <URLCode.h>';
Blockly.Arduino.definitions_['var_declare_urlCode'] = 'URLCode urlCode;';
if (FIELD_OPTION === 'ENCODE') {
Blockly.Arduino.definitions_['function_urlEncode']
= 'String urlEncode(String urlStr) {\n'
+ ' urlCode.strcode = urlStr;\n'
+ ' urlCode.urlencode();\n'
+ ' return urlCode.urlcode;\n'
+ '}\n';
code = 'urlEncode(' + VALUE_INPUT_VALUE + ')';
} else {
Blockly.Arduino.definitions_['function_urlDecode']
= 'String urlDecode(String urlStr) {\n'
+ ' urlCode.urlcode = urlStr;\n'
+ ' urlCode.urldecode();\n'
+ ' return urlCode.strcode;\n'
+ '}\n';
code = 'urlDecode(' + VALUE_INPUT_VALUE + ')';
}
}
return [code, Blockly.Arduino.ORDER_ATOMIC];
};

View File

@@ -0,0 +1,61 @@
import { Variables } from 'blockly/core';
export const variables_get = function (_, generator) {
// Variable getter.
var code = generator.variableDB_.getName(this.getFieldValue('VAR'),
Variables.NAME_TYPE);
return [code, generator.ORDER_ATOMIC];
}
export const variables_declare = function (_, generator) {
var dropdown_type = this.getFieldValue('TYPE');
var dropdown_variables_type = this.getFieldValue('variables_type');
var argument0;
var code = '';
//TODO: settype to variable
if (dropdown_variables_type == 'global_variate') {
if (dropdown_type == 'String') {
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
} else {
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
}
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Variables.NAME_TYPE);
if (dropdown_type == 'String' || dropdown_type == 'char*')
generator.definitions_['var_declare' + varName] = dropdown_type + ' ' + varName + ';';
else
generator.definitions_['var_declare' + varName] = 'volatile ' + dropdown_type + ' ' + varName + ';';
generator.setups_['setup_var' + varName] = varName + ' = ' + argument0 + ';';
}
else {
if (dropdown_type == 'String') {
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '""';
} else {
argument0 = generator.valueToCode(this, 'VALUE', generator.ORDER_ASSIGNMENT) || '0';
}
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Variables.NAME_TYPE);
code = dropdown_type + ' ' + varName + ' = ' + argument0 + ';\n';
}
//generator.variableTypes_[varName] = dropdown_type;//处理变量类型
return code;
}
export const variables_set = function (_, generator) {
// Variable setter.
var argument0 = generator.valueToCode(this, 'VALUE',
generator.ORDER_ASSIGNMENT) || '0';
var varName = generator.variableDB_.getName(this.getFieldValue('VAR'),
Variables.NAME_TYPE);
return varName + ' = ' + argument0 + ';\n';
}
export const variables_change = function (_, generator) {
// Variable setter.
var operator = this.getFieldValue('OP');
var varName = generator.valueToCode(this, 'MYVALUE', generator.ORDER_ASSIGNMENT);
//修复强制类型转换不正确的bug
var code = '((' + operator + ')(' + varName + '))';
return [code, generator.ORDER_ATOMIC];
}

View File

@@ -0,0 +1,199 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling variables and procedure names.
* @author fraser@google.com (Neil Fraser)
*/
import { Variables } from 'blockly/core';
/**
* Class for a database of entity names (variables, functions, etc).
* @param {string} reservedWords A comma-separated string of words that are
* illegal for use as names in a language (e.g. 'new,if,this,...').
* @param {string=} opt_variablePrefix Some languages need a '$' or a namespace
* before all variable names.
* @constructor
*/
const Names = function (reservedWords, opt_variablePrefix) {
this.variablePrefix_ = opt_variablePrefix || '';
this.reservedDict_ = Object.create(null);
if (reservedWords) {
var splitWords = reservedWords.split(',');
for (var i = 0; i < splitWords.length; i++) {
this.reservedDict_[splitWords[i]] = true;
}
}
this.reset();
};
/**
* Constant to separate developer variable names from user-defined variable
* names when running generators.
* A developer variable will be declared as a global in the generated code, but
* will never be shown to the user in the workspace or stored in the variable
* map.
*/
Names.DEVELOPER_VARIABLE_TYPE = 'DEVELOPER_VARIABLE';
/**
* When JavaScript (or most other languages) is generated, variable 'foo' and
* procedure 'foo' would collide. However, Blockly has no such problems since
* variable get 'foo' and procedure call 'foo' are unambiguous.
* Therefore, Blockly keeps a separate type name to disambiguate.
* getName('foo', 'variable') -> 'foo'
* getName('foo', 'procedure') -> 'foo2'
*/
/**
* Empty the database and start from scratch. The reserved words are kept.
*/
Names.prototype.reset = function () {
this.db_ = Object.create(null);
this.dbReverse_ = Object.create(null);
this.variableMap_ = null;
};
/**
* Set the variable map that maps from variable name to variable object.
* @param {!Blockly.VariableMap} map The map to track.
* @package
*/
Names.prototype.setVariableMap = function (map) {
this.variableMap_ = map;
};
/**
* Get the name for a user-defined variable, based on its ID.
* This should only be used for variables of type Variables.NAME_TYPE.
* @param {string} id The ID to look up in the variable map.
* @return {?string} The name of the referenced variable, or null if there was
* no variable map or the variable was not found in the map.
* @private
*/
Names.prototype.getNameForUserVariable_ = function (id) {
if (!this.variableMap_) {
/*
console.log('Deprecated call to Names.prototype.getName without ' +
'defining a variable map. To fix, add the folowing code in your ' +
'generator\'s init() function:\n' +
'Blockly.YourGeneratorName.variableDB_.setVariableMap(' +
'workspace.getVariableMap());');
*/
return null;
}
var variable = this.variableMap_.getVariableById(id);
if (variable) {
return variable.name;
}
return null;
};
/**
* Convert a Blockly entity name to a legal exportable entity name.
* @param {string} name The Blockly entity name (no constraints).
* @param {string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
Names.prototype.getName = function (name, type) {
if (type == Variables.NAME_TYPE) {
var varName = this.getNameForUserVariable_(name);
if (varName) {
name = varName;
}
}
var normalized = name + '_' + type;
var isVarType = type == Variables.NAME_TYPE ||
type == Names.DEVELOPER_VARIABLE_TYPE;
var prefix = isVarType ? this.variablePrefix_ : '';
if (normalized in this.db_) {
return prefix + this.db_[normalized];
}
var safeName = this.getDistinctName(name, type);
this.db_[normalized] = safeName.substr(prefix.length);
return safeName;
};
/**
* Convert a Blockly entity name to a legal exportable entity name.
* Ensure that this is a new name not overlapping any previously defined name.
* Also check against list of reserved words for the current language and
* ensure name doesn't collide.
* @param {string} name The Blockly entity name (no constraints).
* @param {string} type The type of entity in Blockly
* ('VARIABLE', 'PROCEDURE', 'BUILTIN', etc...).
* @return {string} An entity name that is legal in the exported language.
*/
Names.prototype.getDistinctName = function (name, type) {
var safeName = this.safeName_(name);
var i = '';
while (this.dbReverse_[safeName + i] ||
(safeName + i) in this.reservedDict_) {
// Collision with existing name. Create a unique name.
i = i ? i + 1 : 2;
}
safeName += i;
this.dbReverse_[safeName] = true;
var isVarType = type == Variables.NAME_TYPE ||
type == Names.DEVELOPER_VARIABLE_TYPE;
var prefix = isVarType ? this.variablePrefix_ : '';
return prefix + safeName;
};
/**
* Given a proposed entity name, generate a name that conforms to the
* [_A-Za-z][_A-Za-z0-9]* format that most languages consider legal for
* variables.
* @param {string} name Potentially illegal entity name.
* @return {string} Safe entity name.
* @private
*/
Names.prototype.safeName_ = function (name) {
if (!name) {
name = 'unnamed';
} else {
// Unfortunately names in non-latin characters will look like
// _E9_9F_B3_E4_B9_90 which is pretty meaningless.
// https://github.com/google/blockly/issues/1654
name = encodeURI(name.replace(/ /g, '_')).replace(/[^,\w]/g, '_');
// Most languages don't allow names with leading numbers.
if ('0123456789'.indexOf(name[0]) != -1) {
name = 'my_' + name;
}
}
return name;
};
/**
* Do the given two entity names refer to the same entity?
* Blockly names are case-insensitive.
* @param {string} name1 First name.
* @param {string} name2 Second name.
* @return {boolean} True if names are the same.
*/
Names.equals = function (name1, name2) {
return name1 == name2;
};
export default Names;

View File

@@ -0,0 +1,338 @@
/**
* @license
* Copyright 2012 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling procedures.
* @author fraser@google.com (Neil Fraser)
*/
/**
* @name Blockly.Procedures
* @namespace
*/
import * as Blockly from 'blockly/core';
import Variables from './variables';
const Procedures = {};
Procedures.DATA_TYPE = [
...Variables.DATA_TYPE,
[Blockly.Msg.MIXLY_OTHER, 'CUSTOM']
];
/**
* Constant to separate procedure names from variables and generated functions
* when running generators.
* @deprecated Use Blockly.PROCEDURE_CATEGORY_NAME
*/
Procedures.NAME_TYPE = Blockly.PROCEDURE_CATEGORY_NAME;
/**
* Find all user-created procedure definitions in a workspace.
* @param {!Blockly.Workspace} root Root workspace.
* @return {!Array.<!Array.<!Array>>} Pair of arrays, the
* first contains procedures without return variables, the second with.
* Each procedure is defined by a three-element list of name, parameter
* list, and return value boolean.
*/
Procedures.allProcedures = function (root) {
var blocks = root.getAllBlocks(false);
var proceduresReturn = [];
var proceduresNoReturn = [];
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureDef) {
var tuple = blocks[i].getProcedureDef();
if (tuple) {
if (tuple[2]) {
proceduresReturn.push(tuple);
} else {
proceduresNoReturn.push(tuple);
}
}
}
}
proceduresNoReturn.sort(Procedures.procTupleComparator_);
proceduresReturn.sort(Procedures.procTupleComparator_);
return [proceduresNoReturn, proceduresReturn];
};
/**
* Comparison function for case-insensitive sorting of the first element of
* a tuple.
* @param {!Array} ta First tuple.
* @param {!Array} tb Second tuple.
* @return {number} -1, 0, or 1 to signify greater than, equality, or less than.
* @private
*/
Procedures.procTupleComparator_ = function (ta, tb) {
return ta[0].toLowerCase().localeCompare(tb[0].toLowerCase());
};
/**
* Ensure two identically-named procedures don't exist.
* Take the proposed procedure name, and return a legal name i.e. one that
* is not empty and doesn't collide with other procedures.
* @param {string} name Proposed procedure name.
* @param {!Blockly.Block} block Block to disambiguate.
* @return {string} Non-colliding name.
*/
Procedures.findLegalName = function (name, block) {
if (block.isInFlyout) {
// Flyouts can have multiple procedures called 'do something'.
return name;
}
name = name || Blockly.Msg['UNNAMED_KEY'] || 'unnamed';
while (!Procedures.isLegalName_(name, block.workspace, block)) {
// Collision with another procedure.
var r = name.match(/^(.*?)(\d+)$/);
if (!r) {
name += '2';
} else {
name = r[1] + (parseInt(r[2], 10) + 1);
}
}
return name;
};
/**
* Does this procedure have a legal name? Illegal names include names of
* procedures already defined.
* @param {string} name The questionable name.
* @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
* @param {Blockly.Block=} opt_exclude Optional block to exclude from
* comparisons (one doesn't want to collide with oneself).
* @return {boolean} True if the name is legal.
* @private
*/
Procedures.isLegalName_ = function (name, workspace, opt_exclude) {
return !Procedures.isNameUsed(name, workspace, opt_exclude);
};
/**
* Return if the given name is already a procedure name.
* @param {string} name The questionable name.
* @param {!Blockly.Workspace} workspace The workspace to scan for collisions.
* @param {Blockly.Block=} opt_exclude Optional block to exclude from
* comparisons (one doesn't want to collide with oneself).
* @return {boolean} True if the name is used, otherwise return false.
*/
Procedures.isNameUsed = function (name, workspace, opt_exclude) {
var blocks = workspace.getAllBlocks(false);
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i] == opt_exclude) {
continue;
}
if (blocks[i].getProcedureDef) {
var procName = blocks[i].getProcedureDef();
if (Blockly.Names.equals(procName[0], name)) {
return true;
}
}
}
return false;
};
/**
* Rename a procedure. Called by the editable field.
* @param {string} name The proposed new name.
* @return {string} The accepted name.
* @this {Blockly.Field}
*/
Procedures.rename = function (name) {
// Strip leading and trailing whitespace. Beyond this, all names are legal.
name = name.trim();
var legalName = Procedures.findLegalName(name, this.getSourceBlock());
var oldName = this.getValue();
if (oldName != name && oldName != legalName) {
// Rename any callers.
var blocks = this.getSourceBlock().workspace.getAllBlocks(false);
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].renameProcedure) {
blocks[i].renameProcedure(oldName, legalName);
}
}
}
return legalName;
};
/**
* Construct the blocks required by the flyout for the procedure category.
* @param {!Blockly.Workspace} workspace The workspace containing procedures.
* @return {!Array.<!Element>} Array of XML block elements.
*/
Procedures.flyoutCategory = function (workspace) {
var xmlList = [];
if (Blockly.Blocks['procedures_defnoreturn']) {
// <block type="procedures_defnoreturn" gap="16">
// <field name="NAME">do something</field>
// </block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_defnoreturn');
block.setAttribute('gap', 16);
var nameField = Blockly.utils.xml.createElement('field');
nameField.setAttribute('name', 'NAME');
nameField.appendChild(Blockly.utils.xml.createTextNode(
Blockly.Msg['PROCEDURES_DEFNORETURN_PROCEDURE']));
block.appendChild(nameField);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_defreturn']) {
// <block type="procedures_defreturn" gap="16">
// <field name="NAME">do something</field>
// </block>
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_defreturn');
block.setAttribute('gap', 16);
let nameField = Blockly.utils.xml.createElement('field');
nameField.setAttribute('name', 'NAME');
nameField.appendChild(Blockly.utils.xml.createTextNode(
Blockly.Msg['PROCEDURES_DEFRETURN_PROCEDURE']));
block.appendChild(nameField);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_return']) {
// <block type="procedures_return" gap="16"></block>
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_return');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (Blockly.Blocks['procedures_ifreturn']) {
// <block type="procedures_ifreturn" gap="16"></block>
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'procedures_ifreturn');
block.setAttribute('gap', 16);
xmlList.push(block);
}
if (xmlList.length) {
// Add slightly larger gap between system blocks and user calls.
xmlList[xmlList.length - 1].setAttribute('gap', 24);
}
function populateProcedures(procedureList, templateName) {
for (var i = 0; i < procedureList.length; i++) {
var name = procedureList[i][0];
var args = procedureList[i][1];
// <block type="procedures_callnoreturn" gap="16">
// <mutation name="do something">
// <arg name="x"></arg>
// </mutation>
// </block>
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', templateName);
block.setAttribute('gap', 16);
var mutation = Blockly.utils.xml.createElement('mutation');
mutation.setAttribute('name', name);
block.appendChild(mutation);
for (var j = 0; j < args.length; j++) {
var arg = Blockly.utils.xml.createElement('arg');
arg.setAttribute('name', args[j]);
mutation.appendChild(arg);
}
xmlList.push(block);
}
}
var tuple = Procedures.allProcedures(workspace);
populateProcedures(tuple[0], 'procedures_callnoreturn');
populateProcedures(tuple[1], 'procedures_callreturn');
return xmlList;
};
/**
* Find all the callers of a named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to find callers in.
* @return {!Array.<!Blockly.Block>} Array of caller blocks.
*/
Procedures.getCallers = function (name, workspace) {
var callers = [];
var blocks = workspace.getAllBlocks(false);
// Iterate through every block and check the name.
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureCall) {
var procName = blocks[i].getProcedureCall();
// Procedure name may be null if the block is only half-built.
if (procName && Blockly.Names.equals(procName, name)) {
callers.push(blocks[i]);
}
}
}
return callers;
};
/**
* When a procedure definition changes its parameters, find and edit all its
* callers.
* @param {!Blockly.Block} defBlock Procedure definition block.
*/
Procedures.mutateCallers = function (defBlock) {
const oldRecordUndo = Blockly.Events.getRecordUndo();
const procedureBlock = defBlock;
const name = procedureBlock.getProcedureDef()[0];
const xmlElement = defBlock.mutationToDom(true);
const callers = Procedures.getCallers(name, defBlock.workspace);
for (let i = 0, caller; (caller = callers[i]); i++) {
const oldMutationDom = caller.mutationToDom();
const oldMutation = oldMutationDom && Blockly.utils.xml.domToText(oldMutationDom);
if (caller.domToMutation) {
caller.domToMutation(xmlElement);
}
const newMutationDom = caller.mutationToDom();
const newMutation = newMutationDom && Blockly.utils.xml.domToText(newMutationDom);
if (oldMutation !== newMutation) {
// Fire a mutation on every caller block. But don't record this as an
// undo action since it is deterministically tied to the procedure's
// definition mutation.
Blockly.Events.setRecordUndo(false);
Blockly.Events.fire(
new (Blockly.Events.get(Blockly.Events.BLOCK_CHANGE))(
caller,
'mutation',
null,
oldMutation,
newMutation,
),
);
Blockly.Events.setRecordUndo(oldRecordUndo);
}
}
};
/**
* Find the definition block for the named procedure.
* @param {string} name Name of procedure.
* @param {!Blockly.Workspace} workspace The workspace to search.
* @return {Blockly.Block} The procedure definition block, or null not found.
*/
Procedures.getDefinition = function (name, workspace) {
// Assume that a procedure definition is a top block.
var blocks = workspace.getTopBlocks(false);
for (var i = 0; i < blocks.length; i++) {
if (blocks[i].getProcedureDef) {
var tuple = blocks[i].getProcedureDef();
if (tuple && Blockly.Names.equals(tuple[0], name)) {
return blocks[i];
}
}
}
return null;
};
export default Procedures;

View File

@@ -0,0 +1,255 @@
/**
* @license
* Visual Blocks Editor
*
* Copyright 2012 Google Inc.
* https://developers.google.com/blockly/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @fileoverview Utility functions for handling variables.
* @author fraser@google.com (Neil Fraser)
*/
import * as Blockly from 'blockly/core';
const Variables = {};
/**
* Category to separate variable names from procedures and generated functions.
*/
Variables.NAME_TYPE = 'VARIABLE';
Variables.DATA_TYPE = [
[Blockly.Msg.LANG_MATH_INT, 'int'],
[Blockly.Msg.LANG_MATH_UNSIGNED_INT, 'unsigned int'],
[Blockly.Msg.LANG_MATH_WORD, 'word'],
[Blockly.Msg.LANG_MATH_LONG, 'long'],
[Blockly.Msg.LANG_MATH_UNSIGNED_LONG, 'unsigned long'],
[Blockly.Msg.LANG_MATH_FLOAT, 'float'],
[Blockly.Msg.LANG_MATH_DOUBLE, 'double'],
[Blockly.Msg.LANG_MATH_BOOLEAN, 'bool'],
[Blockly.Msg.LANG_MATH_BYTE, 'byte'],
[Blockly.Msg.LANG_MATH_CHAR, 'char'],
[Blockly.Msg.LANG_MATH_UNSIGNED_CHAR, 'unsigned char'],
[Blockly.Msg.LANG_MATH_STRING, 'String'],
['uint8_t', 'uint8_t'],
['uint16_t', 'uint16_t'],
['uint32_t', 'uint32_t'],
['uint64_t', 'uint64_t'],
['int*', 'int*'],
['unsigned int*', 'unsigned int*'],
['word*', 'word*'],
['long*', 'long*'],
['unsigned long*', 'unsigned long*'],
['float*', 'float*'],
['double*', 'double*'],
['bool*', 'bool*'],
['byte*', 'byte*'],
['char*', 'char*'],
['unsigned char*', 'unsigned char*'],
['String*', 'String*'],
['uint8_t*', 'uint8_t*'],
['uint16_t*', 'uint16_t*'],
['uint32_t*', 'uint32_t*'],
['uint64_t*', 'uint64_t*']
];
/**
* Find all user-created variables.
* @param {!Blockly.Block|!Blockly.Workspace} root Root block or workspace.
* @return {!Array.<string>} Array of variable names.
*/
Variables.allVariables = function (root) {
var blocks;
if (root.getDescendants) {
// Root is Block.
blocks = root.getDescendants();
} else if (root.getAllBlocks) {
// Root is Workspace.
blocks = root.getAllBlocks();
} else {
throw 'Not Block or Workspace: ' + root;
}
var variableHash = Object.create(null);
// Iterate through every block and add each variable to the hash.
for (var x = 0; x < blocks.length; x++) {
var blockVariables = blocks[x].getVars();
for (var y = 0; y < blockVariables.length; y++) {
var varName = blockVariables[y];
// Variable name may be null if the block is only half-built.
if (varName) {
variableHash[varName] = varName;
}
}
}
// Flatten the hash into a list.
var variableList = [];
for (var name in variableHash) {
variableList.push(variableHash[name]);
}
return variableList;
};
/**
* Find all instances of the specified variable and rename them.
* @param {string} oldName Variable to rename.
* @param {string} newName New variable name.
* @param {!Blockly.Workspace} workspace Workspace rename variables in.
*/
Variables.renameVariable = function (oldName, newName, workspace) {
Blockly.Events.setGroup(true);
var blocks = workspace.getAllBlocks();
// Iterate through every block.
for (var i = 0; i < blocks.length; i++) {
blocks[i].renameVar(oldName, newName);
}
Blockly.Events.setGroup(false);
};
/**
* Construct the blocks required by the flyout for the variable category.
* @param {!Blockly.Workspace} workspace The workspace contianing variables.
* @return {!Array.<!Element>} Array of XML block elements.
*/
Variables.flyoutCategory = function (workspace) {
var variableList = Variables.allVariables(workspace);
//variableList.sort(goog.string.caseInsensitiveCompare);
// In addition to the user's variables, we also want to display the default
// variable name at the top. We also don't want this duplicated if the
// user has created a variable of the same name.
//在变量分类里添加默认变量取值与赋值模块时使用
//goog.array.remove(variableList, Blockly.Msg.VARIABLES_DEFAULT_NAME);
//variableList.unshift(Blockly.Msg.VARIABLES_DEFAULT_NAME);
var xmlList = [];
if (Blockly.Blocks['variables_declare']) {
//增加variables_declare模块
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_declare');
xmlList.push(block);
}
//在变量分类里添加默认变量取值与赋值模块时使用
/*
if (Blockly.Blocks['variables_set']) {
//增加variables_declare模块
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_set');
xmlList.push(block);
}
if (Blockly.Blocks['variables_get']) {
//增加variables_declare模块
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_get');
xmlList.push(block);
}
*/
//change tyep
if (Blockly.Blocks['variables_change']) {
//增加variables_declare模块
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_change');
xmlList.push(block);
}
for (var i = 0; i < variableList.length; i++) {
//if(i==0&&!(Blockly.Arduino.definitions_['var_declare'+'item'])){
// continue;
//}
if (Blockly.Blocks['variables_set']) {
let block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_set');
if (Blockly.Blocks['variables_get']) {
block.setAttribute('gap', 8);
}
let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
let name = Blockly.utils.xml.createTextNode(variableList[i]);
field.appendChild(name);
block.appendChild(field);
xmlList.push(block);
}
if (Blockly.Blocks['variables_get']) {
var block = Blockly.utils.xml.createElement('block');
block.setAttribute('type', 'variables_get');
if (Blockly.Blocks['variables_set']) {
block.setAttribute('gap', 24);
}
let field = Blockly.utils.xml.createElement('field', null, variableList[i]);
field.setAttribute('name', 'VAR');
let name = Blockly.utils.xml.createTextNode(variableList[i]);
field.appendChild(name);
block.appendChild(field);
xmlList.push(block);
}
}
return xmlList;
};
/**
* Return a new variable name that is not yet being used. This will try to
* generate single letter variable names in the range 'i' to 'z' to start with.
* If no unique name is located it will try 'i' to 'z', 'a' to 'h',
* then 'i2' to 'z2' etc. Skip 'l'.
* @param {!Blockly.Workspace} workspace The workspace to be unique in.
* @return {string} New variable name.
*/
Variables.generateUniqueName = function (workspace) {
var variableList = Variables.allVariables(workspace);
var newName = '';
if (variableList.length) {
var nameSuffix = 1;
var letters = 'ijkmnopqrstuvwxyzabcdefgh'; // No 'l'.
var letterIndex = 0;
var potName = letters.charAt(letterIndex);
while (!newName) {
var inUse = false;
for (var i = 0; i < variableList.length; i++) {
if (variableList[i] == potName) {
// This potential name is already used.
inUse = true;
break;
}
}
if (inUse) {
// Try the next potential name.
letterIndex++;
if (letterIndex == letters.length) {
// Reached the end of the character sequence so back to 'i'.
// a new suffix.
letterIndex = 0;
nameSuffix++;
}
potName = letters.charAt(letterIndex);
if (nameSuffix > 1) {
potName += nameSuffix;
}
} else {
// We can use the current potential name.
newName = potName;
}
}
} else {
newName = 'i';
}
return newName;
};
export default Variables;

View File

@@ -0,0 +1,32 @@
{
"name": "@mixly/arduino",
"version": "1.8.0",
"description": "适用于mixly的arduino模块",
"scripts": {
"build:dev": "webpack --config=webpack.dev.js",
"build:prod": "npm run build:examples & webpack --config=webpack.prod.js",
"build:examples": "node ../../../scripts/build-examples.js -t special",
"build:examples:ob": "node ../../../scripts/build-examples.js -t special --obfuscate",
"publish:board": "npm publish --registry https://registry.npmjs.org/"
},
"main": "./export.js",
"author": "Mixly Team",
"keywords": [
"mixly",
"mixly-plugin",
"arduino"
],
"homepage": "https://gitee.com/bnu_mixly/mixly3/tree/master/boards/default_src/arduino",
"bugs": {
"url": "https://gitee.com/bnu_mixly/mixly3/issues"
},
"repository": {
"type": "git",
"url": "https://gitee.com/bnu_mixly/mixly3.git",
"directory": "default_src/arduino"
},
"publishConfig": {
"access": "public"
},
"license": "Apache 2.0"
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
const common = require('../../../webpack.common');
const { merge } = require('webpack-merge');
module.exports = merge(common, {
module: {
rules: [
{
test: /\.(txt|c|cpp|h|hpp)$/,
type: 'asset/source'
}
]
}
});

View File

@@ -0,0 +1,21 @@
const path = require('path');
const common = require('./webpack.common');
const { merge } = require('webpack-merge');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ESLintPlugin = require('eslint-webpack-plugin');
module.exports = merge(common, {
mode: 'development',
devtool: 'source-map',
plugins: [
new ESLintPlugin({
context: process.cwd(),
}),
new HtmlWebpackPlugin({
inject: false,
template: path.resolve(process.cwd(), 'template.xml'),
filename: 'index.xml',
minify: false
}),
]
});

View File

@@ -0,0 +1,27 @@
const path = require('path');
const common = require('./webpack.common');
const { merge } = require('webpack-merge');
const TerserPlugin = require('terser-webpack-plugin');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = merge(common, {
mode: 'production',
optimization: {
minimize: true,
minimizer: [
new TerserPlugin({
extractComments: false,
}),
new HtmlWebpackPlugin({
inject: false,
template: path.resolve(process.cwd(), 'template.xml'),
filename: 'index.xml',
minify: {
removeAttributeQuotes: true,
collapseWhitespace: true,
removeComments: true,
}
})
]
}
});