mirror of
https://github.com/damp11113-software/ccIDE.git
synced 2025-04-27 14:38:12 +00:00
update 1.2
add new block: CCSystem and CCTextutils Fixed some bug
This commit is contained in:
parent
218bb18b29
commit
5a4cbb455a
1
TestProject/serialize example 2.ccp
Normal file
1
TestProject/serialize example 2.ccp
Normal file
@ -0,0 +1 @@
|
||||
{"usedlibrary":["CCTextutils"],"content":{"blocks":{"languageVersion":0,"blocks":[{"type":"ide_start","id":"%k|1C%^t;XMrXr0{%gB|","x":330,"y":270,"inputs":{"DO":{"block":{"type":"variables_set","id":"NSMcwqhVU(1::#UWOflD","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}},"inputs":{"VALUE":{"block":{"type":"lists_create_with","id":"Rt}My_DC8m7QIYsmta-T","extraState":{"itemCount":3},"inputs":{"ADD0":{"block":{"type":"math_number","id":"7SKw2+Md2.{tznxyfe{T","fields":{"NUM":1}}},"ADD1":{"block":{"type":"math_number","id":"7UV1y^XFKM!,-6RK);`{","fields":{"NUM":2}}},"ADD2":{"block":{"type":"math_number","id":"MrfY2v6g)h3lj7e0jgqE","fields":{"NUM":3}}}}}}},"next":{"block":{"type":"text_print","id":"3+Z|78w,QkD{/[:jPv:e","inputs":{"TEXT":{"shadow":{"type":"text","id":"+OF[F($(eq]G$:h;Kt*w","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"d{!#Az)#[M2rmGXXW,J,","fields":{"COMPACT":false,"ALLOWREPETI":true},"inputs":{"OBJECT":{"block":{"type":"lists_create_with","id":"W~HzfCNp_n@LA6c6fwp~","extraState":{"itemCount":2},"inputs":{"ADD0":{"block":{"type":"variables_get","id":"bVs`6KM30qehpXe901*:","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}},"ADD1":{"block":{"type":"variables_get","id":"@l4-(?lC]/$VetN_E!|^","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}}}}}}}}},"next":{"block":{"type":"text_print","id":"I^mHjxNqwwaU!Or,/m5@","inputs":{"TEXT":{"shadow":{"type":"text","id":"/!sl#s%!LHS,s5h05pQ;","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"t7R?`7;1c%3!.jd.dW9F","fields":{"COMPACT":true,"ALLOWREPETI":false},"inputs":{"OBJECT":{"block":{"type":"variables_get","id":"!yZhT^MMVuSQ:[q|puo`","fields":{"VAR":{"id":"6z)4i^N`L0rGnHo}k6w~"}}}}}}}}}}}}}}}}]},"variables":[{"name":"test","id":"6z)4i^N`L0rGnHo}k6w~"}]}}
|
1
TestProject/serialize example 3.ccp
Normal file
1
TestProject/serialize example 3.ccp
Normal file
@ -0,0 +1 @@
|
||||
{"usedlibrary":["CCSystem","CCTextutils"],"content":{"blocks":{"languageVersion":0,"blocks":[{"type":"ide_start","id":"?udZVah+}|wlY2LCZ-bl","x":110,"y":150,"inputs":{"DO":{"block":{"type":"variables_set","id":"Q1no.e|r^Ds4Z(cOo6ks","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}},"inputs":{"VALUE":{"block":{"type":"lists_create_with","id":"Qzp}4**d+m``G!B7ydBd","extraState":{"itemCount":0}}}},"next":{"block":{"type":"controls_repeat_ext","id":"h[fG-)EnPfn?;Dw,4JS;","inputs":{"TIMES":{"shadow":{"type":"math_number","id":"0,DMR{6Yro.qGGmsNI!m","fields":{"NUM":10}}},"DO":{"block":{"type":"sys_table_append_data","id":"_{Wr/]apCKw;wuLM!~tb","inputs":{"DATA":{"block":{"type":"math_random_int","id":"/dj{qRb:`dKxV-I6fB:c","inputs":{"FROM":{"shadow":{"type":"math_number","id":"6_%M8#LXu7~[op|p6@i+","fields":{"NUM":1}}},"TO":{"shadow":{"type":"math_number","id":"%dJUjQmbir}H?ZXa!Ghv","fields":{"NUM":10}}}}}},"TABLE":{"block":{"type":"variables_get","id":",7[Gq|+k;K=kAnpK0.dR","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}}}}}}}},"next":{"block":{"type":"text_print","id":"bHx3OISYn{5x.-F2(|Y`","inputs":{"TEXT":{"shadow":{"type":"text","id":"jVr603(C3eOIz#G*N}UC","fields":{"TEXT":"abc"}},"block":{"type":"textutils_serialize","id":"}`]U9*1|Ev{J=[`ru9Q;","fields":{"COMPACT":false,"ALLOWREPETI":false},"inputs":{"OBJECT":{"block":{"type":"lists_sort","id":"EZpHsG`jZ.gBI;D?$b~L","fields":{"TYPE":"NUMERIC","DIRECTION":"1"},"inputs":{"LIST":{"block":{"type":"variables_get","id":"$Uf4s5MK,FWh^4jvKmFo","fields":{"VAR":{"id":"|]HEFfXY)7GgpQb83nOc"}}}}}}}}}}}}}}}}}}}]},"variables":[{"name":"mylist","id":"|]HEFfXY)7GgpQb83nOc"}]}}
|
@ -2,8 +2,22 @@ local ws = assert(http.websocket("ws://127.0.0.1:5133"))
|
||||
print("connected to server")
|
||||
|
||||
local id
|
||||
local isrunning = true
|
||||
|
||||
function exitcheck()
|
||||
while true do
|
||||
local event = os.pullEventRaw("terminate")
|
||||
if event == "terminate" then
|
||||
print("Exiting...")
|
||||
isrunning = false
|
||||
ws.close()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
while isrunning do
|
||||
print("ready")
|
||||
local message, error = ws.receive()
|
||||
if message then
|
||||
@ -30,5 +44,7 @@ while true do
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ws.close()
|
||||
parallel.waitForAny(exitcheck, main)
|
||||
print("Exited")
|
249
blocks/CCSystem/block_design.json
Normal file
249
blocks/CCSystem/block_design.json
Normal file
@ -0,0 +1,249 @@
|
||||
{
|
||||
"sysos_pullevent": {
|
||||
"message0": "Pull %1 event",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "EVENT",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"output": "Multiple",
|
||||
"colour": 0,
|
||||
"tooltip": "Pause execution of the current thread and waits for any events matching filter.",
|
||||
"helpUrl": "https://tweaked.cc/module/os.html#v:pullEvent"
|
||||
},
|
||||
"sysos_pullrawevent": {
|
||||
"message0": "Pull raw %1 event",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "EVENT",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"output": "Multiple",
|
||||
"colour": 0,
|
||||
"tooltip": "Pause execution of the current thread and waits for events, including the terminate event.",
|
||||
"helpUrl": "https://tweaked.cc/module/os.html#v:pullEventRaw"
|
||||
},
|
||||
"sysos_version": {
|
||||
"message0": "Get system version",
|
||||
"output": "String",
|
||||
"colour": 0,
|
||||
"tooltip": "Get the current CraftOS version (for example, CraftOS 1.9)."
|
||||
},
|
||||
"sysos_run": {
|
||||
"message0": "Run %1\nEnvironment %2\nArgs %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "RUN",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ENV",
|
||||
"check": "Array"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ARGS",
|
||||
"check": "Multiple"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Run the program at the given path with the specified environment and arguments.",
|
||||
"helpUrl": "https://tweaked.cc/module/os.html#v:run"
|
||||
},
|
||||
"sysos_queue_event": {
|
||||
"message0": "Add event %1 to queue with args %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "EVENT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ARGS",
|
||||
"check": "Multiple"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Adds an event to the event queue. This event can later be pulled with os.pullEvent."
|
||||
},
|
||||
"sysos_start_timer": {
|
||||
"message0": "Start timer at %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TIME",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"output": "Number",
|
||||
"colour": 0,
|
||||
"tooltip": "Starts a timer that will run for the specified number of seconds. Once the timer fires, a timer event will be added to the queue with the ID returned from this function as the first parameter.",
|
||||
"helpUrl": "https://tweaked.cc/module/os.html#v:startTimer"
|
||||
},
|
||||
"sysos_cancel_timer": {
|
||||
"message0": "Stop timer id %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ID",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Cancels a timer previously started with startTimer. This will stop the timer from firing."
|
||||
},
|
||||
"sysos_set_alarm": {
|
||||
"message0": "Set alarm to %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TIME",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"output": "Number",
|
||||
"colour": 0,
|
||||
"tooltip": "Sets an alarm that will fire at the specified in-game time."
|
||||
},
|
||||
"sysos_cancel_alarm": {
|
||||
"message0": "Stop alarm id %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ID",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Cancels an alarm previously started with setAlarm."
|
||||
},
|
||||
"sysos_shutdown": {
|
||||
"message0": "Shutdown computer",
|
||||
"previousStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Shuts down the computer immediately."
|
||||
},
|
||||
"sysos_reboot": {
|
||||
"message0": "Restart computer",
|
||||
"previousStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Reboots the computer immediately."
|
||||
},
|
||||
"sysos_get_computer_id": {
|
||||
"message0": "Get computer id",
|
||||
"output": "Number",
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the ID of the computer."
|
||||
},
|
||||
"sysos_get_computer_label": {
|
||||
"message0": "Get computer label",
|
||||
"output": "String",
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the label of the computer, or nil if none is set."
|
||||
},
|
||||
"sysos_set_computer_label": {
|
||||
"message0": "Set computer label to %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "LABEL",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Set the label of this computer."
|
||||
},
|
||||
"sysos_clock": {
|
||||
"message0": "Get Uptime",
|
||||
"output": "String",
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the number of seconds that the computer has been running."
|
||||
},
|
||||
"sysos_time": {
|
||||
"message0": "Get time of %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "LOCATE",
|
||||
"options": [
|
||||
["In Game World", "ingame"],
|
||||
["UTC", "utc"],
|
||||
["Local", "local"]
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the current time depending on the string passed in. This will always be in the range [0.0, 24.0)."
|
||||
},
|
||||
"sysos_day": {
|
||||
"message0": "Get day of %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "LOCATE",
|
||||
"options": [
|
||||
["In Game World", "ingame"],
|
||||
["UTC", "utc"],
|
||||
["Local", "local"]
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the day depending on the locale specified."
|
||||
},
|
||||
"sysos_epoch": {
|
||||
"message0": "Get epoch of %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "field_dropdown",
|
||||
"name": "LOCATE",
|
||||
"options": [
|
||||
["In Game World", "ingame"],
|
||||
["UTC", "utc"],
|
||||
["Local", "local"]
|
||||
]
|
||||
}
|
||||
],
|
||||
"output": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Returns the number of milliseconds since an epoch depending on the locale."
|
||||
},
|
||||
"sysos_date": {
|
||||
"message0": "Format date with patten %1 from time %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "FORMAT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TIME",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"output": null,
|
||||
"colour": 0,
|
||||
"tooltip": "Returns a date string (or table) using a specified format string and optional time to format.",
|
||||
"helpUrl": "https://cplusplus.com/reference/ctime/strftime/"
|
||||
}
|
||||
}
|
130
blocks/CCSystem/generator.js
Normal file
130
blocks/CCSystem/generator.js
Normal file
@ -0,0 +1,130 @@
|
||||
// this file not for generator only
|
||||
|
||||
const { luaGenerator } = require('blockly/lua');
|
||||
|
||||
// Check if luaGenerator.forBlock is defined and initialize if necessary
|
||||
if (!luaGenerator.forBlock) {
|
||||
luaGenerator.forBlock = {};
|
||||
}
|
||||
|
||||
luaGenerator.forBlock['sysos_pullevent'] = function(block, generator) {
|
||||
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
|
||||
|
||||
if (event == "") {
|
||||
return [`os.pullevent()`, luaGenerator.ORDER_NONE];
|
||||
} else {
|
||||
return [`os.pullevent(${event})`, luaGenerator.ORDER_NONE];
|
||||
}
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_pullrawevent'] = function(block, generator) {
|
||||
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
|
||||
|
||||
if (event == "") {
|
||||
return [`os.pullEventRaw()`, luaGenerator.ORDER_NONE];
|
||||
} else {
|
||||
return [`os.pullEventRaw(${event})`, luaGenerator.ORDER_NONE];
|
||||
}
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_version'] = function(block, generator) {
|
||||
return [`os.version()`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_run'] = function(block, generator) {
|
||||
var env = generator.valueToCode(block, 'ENV', generator.ORDER_ATOMIC) || "{}";
|
||||
var run = generator.valueToCode(block, 'RUN', generator.ORDER_ATOMIC);
|
||||
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
|
||||
|
||||
if (args == "") {
|
||||
return `os.run(${env}, ${run})\n`;
|
||||
} else {
|
||||
return `os.run(${env}, ${run}, ${args})\n`;
|
||||
}
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_queue_event'] = function(block, generator) {
|
||||
var event = generator.valueToCode(block, 'EVENT', generator.ORDER_ATOMIC);
|
||||
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
|
||||
|
||||
if (args == "") {
|
||||
return `os.queueEvent(${event})\n`;
|
||||
} else {
|
||||
return `os.queueEvent(${event}, ${args})\n`;
|
||||
}
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_start_timer'] = function(block, generator) {
|
||||
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`os.queueEvent(${time})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_cancel_timer'] = function(block, generator) {
|
||||
var id = generator.valueToCode(block, 'ID', generator.ORDER_ATOMIC);
|
||||
|
||||
return `os.cancelTimer(${id}\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_set_alarm'] = function(block, generator) {
|
||||
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`os.setAlarm(${time})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_cancel_alarm'] = function(block, generator) {
|
||||
var id = generator.valueToCode(block, 'ID', generator.ORDER_ATOMIC);
|
||||
|
||||
return `os.cancelAlarm(${id})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_shutdown'] = function(block, generator) {
|
||||
return `os.shutdown()`
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_reboot'] = function(block, generator) {
|
||||
return `os.reboot()`
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_get_computer_id'] = function(block, generator) {
|
||||
return [`os.getComputerID()`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_get_computer_label'] = function(block, generator) {
|
||||
return [`os.getComputerLabel()`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_set_computer_label'] = function(block, generator) {
|
||||
var label = generator.valueToCode(block, 'LABEL', generator.ORDER_ATOMIC);
|
||||
|
||||
return `os.setComputerLabel(${label})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_clock'] = function(block, generator) {
|
||||
return [`os.clock()`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_time'] = function(block, generator) {
|
||||
var locate = block.getFieldValue('LOCATE');
|
||||
|
||||
return [`os.time("${locate}")`, generator.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_day'] = function(block, generator) {
|
||||
var locate = block.getFieldValue('LOCATE');
|
||||
|
||||
return [`os.day("${locate}")`, generator.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_epoch'] = function(block, generator) {
|
||||
var locate = block.getFieldValue('LOCATE');
|
||||
|
||||
return [`os.epoch("${locate}")`, generator.ORDER_ATOMIC];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sysos_date'] = function(block, generator) {
|
||||
var format = generator.valueToCode(block, 'FORMAT', generator.ORDER_ATOMIC);
|
||||
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`os.date(${format}, ${time})`, luaGenerator.ORDER_NONE];
|
||||
};
|
22
blocks/CCSystem/index.json
Normal file
22
blocks/CCSystem/index.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "CC: System (OS)",
|
||||
"author": "DPSoftware Foundation",
|
||||
"description": "The os API allows interacting with the current computer.",
|
||||
"version": "1.0.0",
|
||||
"category": "System",
|
||||
"keyword": "System, OS",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"peripherals": false,
|
||||
"library": true,
|
||||
"require_network": false,
|
||||
"dependencies": {},
|
||||
"design_for_computer": {
|
||||
"basic": true,
|
||||
"adv": true,
|
||||
"command": true,
|
||||
"pocket": true,
|
||||
"advpocket": true,
|
||||
"turtle": true,
|
||||
"advturtle": true
|
||||
}
|
||||
}
|
56
blocks/CCSystem/toolbox.xml
Normal file
56
blocks/CCSystem/toolbox.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<xml id="toolbox" style="display: none;">
|
||||
<category name="System" colour="0">
|
||||
<block type="sysos_pullevent">
|
||||
<value name="EVENT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">All</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sysos_pullrawevent">
|
||||
<value name="EVENT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">All</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sysos_version"></block>
|
||||
<block type="sysos_run"></block>
|
||||
<block type="sysos_queue_event"></block>
|
||||
<block type="sysos_start_timer">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sysos_cancel_timer"></block>
|
||||
<block type="sysos_set_alarm">
|
||||
<value name="TIME">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">0</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sysos_cancel_alarm"></block>
|
||||
<block type="sysos_shutdown"></block>
|
||||
<block type="sysos_reboot"></block>
|
||||
<block type="sysos_get_computer_id"></block>
|
||||
<block type="sysos_get_computer_label"></block>
|
||||
<block type="sysos_set_computer_label"></block>
|
||||
<block type="sysos_clock"></block>
|
||||
<block type="sysos_time"></block>
|
||||
<block type="sysos_day"></block>
|
||||
<block type="sysos_epoch"></block>
|
||||
<block type="sysos_date">
|
||||
<value name="FORMAT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">%A %d %B %Y</field>
|
||||
</shadow>
|
||||
</value>
|
||||
<value name="TIME">
|
||||
<shadow type="sysos_time"></shadow>
|
||||
</value>
|
||||
</block>
|
||||
</category>
|
||||
</xml>
|
237
blocks/CCTextutils/block_design.json
Normal file
237
blocks/CCTextutils/block_design.json
Normal file
@ -0,0 +1,237 @@
|
||||
{
|
||||
"textutils_slow_write": {
|
||||
"message0": "Write %1 with rate %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TEXT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "RATE",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 32,
|
||||
"tooltip": "Slowly writes string text at current cursor position, character-by-character."
|
||||
},
|
||||
"textutils_slow_print": {
|
||||
"message0": "Print %1 with rate %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TEXT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "RATE",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 32,
|
||||
"tooltip": "Slowly prints string text at current cursor position, character-by-character."
|
||||
},
|
||||
"textutils_format_time": {
|
||||
"message0": "Format time from %1\n24-Hour %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TIME",
|
||||
"check": "Number"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "24H"
|
||||
}
|
||||
],
|
||||
"output": "String",
|
||||
"colour": 32,
|
||||
"tooltip": "Takes input time and formats it in a more readable format such as 6:30 PM."
|
||||
},
|
||||
"textutils_paged_print": {
|
||||
"message0": "Print %1\nlimit %2 lines",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TEXT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "FREELINES",
|
||||
"check": "Number"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 32,
|
||||
"tooltip": "Prints a given string to the display.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:pagedPrint"
|
||||
},
|
||||
"textutils_tabulate": {
|
||||
"message0": "Print table %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ARGS",
|
||||
"check": "Multiple"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 32,
|
||||
"tooltip": "Prints tables in a structured form.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:tabulate"
|
||||
},
|
||||
"textutils_paged_tabulate": {
|
||||
"message0": "Print table %1 with paged",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ARGS",
|
||||
"check": "Multiple"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 32,
|
||||
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal."
|
||||
},
|
||||
"textutils_empty_json_array": {
|
||||
"message0": "Empty json array",
|
||||
"output": "Array",
|
||||
"colour": 32,
|
||||
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal."
|
||||
},
|
||||
"textutils_json_null": {
|
||||
"message0": "Json null",
|
||||
"output": "Array",
|
||||
"colour": 32,
|
||||
"tooltip": "A table representing the JSON null value."
|
||||
},
|
||||
"textutils_serialize": {
|
||||
"message0": "Serialize %1\nCompact %2\nAllow repetitions %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "OBJECT",
|
||||
"check": "Array"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "COMPACT"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "ALLOWREPETI"
|
||||
}
|
||||
],
|
||||
"output": "String",
|
||||
"colour": 32,
|
||||
"tooltip": "Prints tables in a structured form, stopping and prompting for input should the result not fit on the terminal.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:serialize"
|
||||
},
|
||||
"textutils_unserialize": {
|
||||
"message0": "UnSerialize %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "OBJECT",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"output": "Array",
|
||||
"colour": 32,
|
||||
"tooltip": "Converts a serialised string back into a reassembled Lua object."
|
||||
},
|
||||
"textutils_serialize_json": {
|
||||
"message0": "Serialize %1 to json\nNBT style %2\nUnicode %3\nAllow repetitions %4",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "OBJECT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "NBT"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "UNICODE"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "ALLOWREPETI"
|
||||
}
|
||||
],
|
||||
"output": "String",
|
||||
"colour": 32,
|
||||
"tooltip": "Returns a JSON representation of the given data.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:serializeJSON"
|
||||
},
|
||||
"textutils_unserialize_json": {
|
||||
"message0": "UnSerialize %1 to json\nNBT style %2\nParse null %3\nParse empty array %4",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "OBJECT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "NBT"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "PARSENULL"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "PARSEEA"
|
||||
}
|
||||
],
|
||||
"output": ["Array", "Multiple"],
|
||||
"colour": 32,
|
||||
"tooltip": "Converts a serialised JSON string back into a reassembled Lua object.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:unserializeJSON"
|
||||
},
|
||||
"textutils_url_encode": {
|
||||
"message0": "Encode URL %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "URL",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"output": "String",
|
||||
"colour": 32,
|
||||
"tooltip": "Replaces certain characters in a string to make it safe for use in URLs or POST data."
|
||||
},
|
||||
"textutils_complete": {
|
||||
"message0": "Complete %1 in table %2",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "SEARCH_TEXT",
|
||||
"check": "String"
|
||||
},
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "SEARCH_TABLE",
|
||||
"check": "Table"
|
||||
}
|
||||
],
|
||||
"output": "Array",
|
||||
"colour": 32,
|
||||
"tooltip": "Provides a list of possible completions for a partial Lua expression.",
|
||||
"helpUrl": "https://tweaked.cc/module/textutils.html#v:complete"
|
||||
}
|
||||
}
|
107
blocks/CCTextutils/generator.js
Normal file
107
blocks/CCTextutils/generator.js
Normal file
@ -0,0 +1,107 @@
|
||||
// this file not for generator only
|
||||
|
||||
const { luaGenerator } = require('blockly/lua');
|
||||
|
||||
// Check if luaGenerator.forBlock is defined and initialize if necessary
|
||||
if (!luaGenerator.forBlock) {
|
||||
luaGenerator.forBlock = {};
|
||||
}
|
||||
|
||||
luaGenerator.forBlock['textutils_slow_write'] = function(block, generator) {
|
||||
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
|
||||
var rate = generator.valueToCode(block, 'RATE', generator.ORDER_ATOMIC);
|
||||
|
||||
return `textutils.slowWrite(${text}, ${rate})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_slow_print'] = function(block, generator) {
|
||||
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
|
||||
var rate = generator.valueToCode(block, 'RATE', generator.ORDER_ATOMIC);
|
||||
|
||||
return `textutils.slowPrint(${text}, ${rate})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_format_time'] = function(block, generator) {
|
||||
var time = generator.valueToCode(block, 'TIME', generator.ORDER_ATOMIC);
|
||||
var is24hour = generator.valueToCode(block, '24H', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`textutils.formatTime(${time}, ${is24hour})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_paged_print'] = function(block, generator) {
|
||||
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_ATOMIC);
|
||||
var freeline = generator.valueToCode(block, 'FREELINES', generator.ORDER_ATOMIC);
|
||||
|
||||
return `textutils.pagedPrint(${text}, ${freeline})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_tabulate'] = function(block, generator) {
|
||||
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
|
||||
|
||||
return `textutils.tabulate(${args})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_paged_tabulate'] = function(block, generator) {
|
||||
var args = generator.valueToCode(block, 'ARGS', generator.ORDER_ATOMIC);
|
||||
|
||||
return `textutils.pagedTabulate(${args})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_empty_json_array'] = function(block, generator) {
|
||||
return [`textutils.textutils_empty_json_array`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_json_null'] = function(block, generator) {
|
||||
return [`textutils.json_null`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_serialize'] = function(block, generator) {
|
||||
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
|
||||
var compact = block.getFieldValue('COMPACT') == 'TRUE';
|
||||
var repetitions = block.getFieldValue('ALLOWREPETI') == 'TRUE';
|
||||
|
||||
|
||||
return [`textutils.serialize(${object}, {compact=${compact}, allow_repetitions=${repetitions}})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_unserialize'] = function(block, generator) {
|
||||
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`textutils.unserialize(${object})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_serialize_json'] = function(block, generator) {
|
||||
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
|
||||
var nbt = block.getFieldValue('NBT') == 'TRUE';
|
||||
var unicode = block.getFieldValue('UNICODE') == 'TRUE';
|
||||
var repetitions = block.getFieldValue('ALLOWREPETI') == 'TRUE';
|
||||
|
||||
return [`textutils.serializeJSON(${object}, {nbt_style=${nbt}, unicode_strings=${unicode}, allow_repetitions=${repetitions}})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_unserialize_json'] = function(block, generator) {
|
||||
var object = generator.valueToCode(block, 'OBJECT', generator.ORDER_ATOMIC);
|
||||
var nbt = block.getFieldValue('NBT') == 'TRUE';
|
||||
var parse_null = block.getFieldValue('PARSENULL') == 'TRUE';
|
||||
var parse_empty_array = block.getFieldValue('PARSEEA') == 'TRUE';
|
||||
|
||||
return [`textutils.unserializeJSON(${object}, {nbt_style=${nbt}, parse_null=${parse_null}, parse_empty_array=${parse_empty_array}})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_url_encode'] = function(block, generator) {
|
||||
var url = generator.valueToCode(block, 'URL', generator.ORDER_ATOMIC);
|
||||
|
||||
return [`textutils.urlEncode(${url})`, luaGenerator.ORDER_NONE];
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['textutils_complete'] = function(block, generator) {
|
||||
var value_search_text = generator.valueToCode(block, 'SEARCH_TEXT', Blockly.Lua.ORDER_ATOMIC) || '""';
|
||||
var value_search_table = generator.valueToCode(block, 'SEARCH_TABLE', Blockly.Lua.ORDER_ATOMIC) || '_G';
|
||||
|
||||
if (value_search_table == "") {
|
||||
return [`textutils.complete(${value_search_text})`];
|
||||
} else {
|
||||
return [`textutils.complete(${value_search_text}, ${value_search_table})`];
|
||||
}
|
||||
};
|
||||
|
22
blocks/CCTextutils/index.json
Normal file
22
blocks/CCTextutils/index.json
Normal file
@ -0,0 +1,22 @@
|
||||
{
|
||||
"name": "CC: Textutils",
|
||||
"author": "DPSoftware Foundation",
|
||||
"description": "Helpful utilities for formatting and manipulating strings.",
|
||||
"version": "1.0.0",
|
||||
"category": "utils",
|
||||
"keyword": "utils",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"peripherals": false,
|
||||
"library": true,
|
||||
"require_network": false,
|
||||
"dependencies": {},
|
||||
"design_for_computer": {
|
||||
"basic": true,
|
||||
"adv": true,
|
||||
"command": true,
|
||||
"pocket": true,
|
||||
"advpocket": true,
|
||||
"turtle": true,
|
||||
"advturtle": true
|
||||
}
|
||||
}
|
37
blocks/CCTextutils/toolbox.xml
Normal file
37
blocks/CCTextutils/toolbox.xml
Normal file
@ -0,0 +1,37 @@
|
||||
<xml id="toolbox" style="display: none;">
|
||||
<category name="Textutils" colour="32">
|
||||
<block type="textutils_slow_write">
|
||||
<value name="RATE">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">20</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="textutils_slow_print">
|
||||
<value name="RATE">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">20</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="textutils_paged_print">
|
||||
<value name="FREELINES">
|
||||
<shadow type="math_number">
|
||||
<field name="NUM">20</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="textutils_tabulate"></block>
|
||||
<block type="textutils_paged_tabulate"></block>
|
||||
<block type="textutils_empty_json_array"></block>
|
||||
<block type="textutils_json_null"></block>
|
||||
<block type="textutils_serialize"></block>
|
||||
<block type="textutils_unserialize"></block>
|
||||
<block type="textutils_serialize_json"></block>
|
||||
<block type="textutils_unserialize_json"></block>
|
||||
<block type="textutils_url_encode"></block>
|
||||
<block type="textutils_complete"></block>
|
||||
<block type="textutils_format_time"></block>
|
||||
|
||||
</category>
|
||||
</xml>
|
Binary file not shown.
40
index.js
40
index.js
@ -16,6 +16,22 @@ let isopennewproject = false;
|
||||
|
||||
app.whenReady().then(() => {
|
||||
reloadall(false);
|
||||
var splash = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 300,
|
||||
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
||||
transparent: true,
|
||||
frame: false,
|
||||
center: true,
|
||||
webPreferences: {
|
||||
nodeIntegration: true,
|
||||
contextIsolation: false,
|
||||
}
|
||||
});
|
||||
|
||||
splash.loadFile('src/splash.html');
|
||||
splash.webContents.send("change-status", "Initializing...")
|
||||
|
||||
const win = new BrowserWindow({
|
||||
width: 1280,
|
||||
height: 720,
|
||||
@ -30,20 +46,17 @@ app.whenReady().then(() => {
|
||||
center: true,
|
||||
})
|
||||
|
||||
var splash = new BrowserWindow({
|
||||
width: 600,
|
||||
height: 300,
|
||||
icon: path.join(__dirname, 'assets', 'ccIDEIcon.ico'),
|
||||
transparent: true,
|
||||
frame: false,
|
||||
center: true
|
||||
});
|
||||
|
||||
try {
|
||||
win.loadFile('src/index.html');
|
||||
splash.loadFile('src/splash.html');
|
||||
} catch {
|
||||
try {
|
||||
win.loadFile('dist_src/index.html');
|
||||
} catch {
|
||||
dialog.showErrorBox("Error on startup", "Can't find index.html");
|
||||
}
|
||||
}
|
||||
win.setTitle(`ccIDE`)
|
||||
|
||||
|
||||
ipc.once('ready', () => {
|
||||
console.log("ready")
|
||||
if (splash) {
|
||||
@ -58,7 +71,9 @@ app.whenReady().then(() => {
|
||||
//win.openDevTools();
|
||||
});
|
||||
|
||||
|
||||
ipc.on('update-startup-status', (event, status) => {
|
||||
splash.webContents.send("change-status", status)
|
||||
});
|
||||
|
||||
//app.on('activate', () => {
|
||||
// if (BrowserWindow.getAllWindows().length === 0) {
|
||||
@ -80,7 +95,6 @@ app.whenReady().then(() => {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Define a custom menu template
|
||||
const menuTemplate = [
|
||||
{
|
||||
|
2270
package-lock.json
generated
2270
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -5,14 +5,19 @@
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"dev": "electron .",
|
||||
"build": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite"
|
||||
"build": "electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite",
|
||||
"full_build": "webpack --mode production && electron-packager . ccIDE --platform=win32 --arch=x64 --icon=assets/ccIDEIcon.ico --out=dist --overwrite"
|
||||
},
|
||||
"author": "DPSoftware Foundation",
|
||||
"license": "GPL-3.0-or-later",
|
||||
"devDependencies": {
|
||||
"electron": "^31.1.0"
|
||||
"electron": "^31.1.0",
|
||||
"webpack": "^5.93.0",
|
||||
"webpack-cli": "^5.1.4",
|
||||
"webpack-node-externals": "^3.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@blockly/plugin-workspace-search": "^9.0.5",
|
||||
"@electron/remote": "^2.1.2",
|
||||
"blockly": "^11.1.1",
|
||||
"bootstrap": "^5.3.3",
|
||||
|
18
remote.lua
18
remote.lua
@ -2,8 +2,22 @@ local ws = assert(http.websocket("ws://127.0.0.1:5133"))
|
||||
print("connected to server")
|
||||
|
||||
local id
|
||||
local isrunning = true
|
||||
|
||||
function exitcheck()
|
||||
while true do
|
||||
local event = os.pullEventRaw("terminate")
|
||||
if event == "terminate" then
|
||||
print("Exiting...")
|
||||
isrunning = false
|
||||
ws.close()
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function main()
|
||||
while isrunning do
|
||||
print("ready")
|
||||
local message, error = ws.receive()
|
||||
if message then
|
||||
@ -28,5 +42,7 @@ while true do
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ws.close()
|
||||
parallel.waitForAny(exitcheck, main)
|
||||
print("Exited")
|
@ -10,19 +10,61 @@ class CCRemote {
|
||||
console.log("Server is started");
|
||||
|
||||
this.socket.on('connection', (ws) => {
|
||||
document.getElementById("navbar-button-computer-disconnect").disabled = false;
|
||||
document.getElementById("navbar-button-computer-run").disabled = false;
|
||||
|
||||
document.getElementById('statusMessage').textContent = "Computer connected";
|
||||
setTimeout(() => {
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 1000);
|
||||
|
||||
console.log('WebSocket connection established.');
|
||||
|
||||
// Set up heartbeat
|
||||
ws.isAlive = true;
|
||||
ws.on('pong', () => {
|
||||
ws.isAlive = true;
|
||||
});
|
||||
|
||||
ws.on('message', (message) => {
|
||||
console.log(`Received message => ${message}`);
|
||||
});
|
||||
|
||||
ws.on('close', () => {
|
||||
document.getElementById("navbar-button-computer-disconnect").disabled = true;
|
||||
document.getElementById("navbar-button-computer-run").disabled = true;
|
||||
|
||||
document.getElementById('statusMessage').textContent = "Computer disconnected";
|
||||
setTimeout(() => {
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
ws.on('error', (error) => {
|
||||
console.error('Client error:', error);
|
||||
});
|
||||
});
|
||||
|
||||
// Ping clients every 30 seconds to check if they are alive
|
||||
const interval = setInterval(() => {
|
||||
this.socket.clients.forEach((ws) => {
|
||||
if (ws.isAlive === false) {
|
||||
console.log('Client did not respond to ping, terminating connection.');
|
||||
return ws.terminate();
|
||||
}
|
||||
|
||||
ws.isAlive = false;
|
||||
ws.ping();
|
||||
});
|
||||
}, 1000);
|
||||
|
||||
this.socket.on('close', () => {
|
||||
console.log('WebSocket connection closed.');
|
||||
clearInterval(interval);
|
||||
console.log('WebSocket server closed.');
|
||||
});
|
||||
|
||||
this.socket.on('error', (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
console.error('WebSocket server error:', error);
|
||||
});
|
||||
}
|
||||
|
||||
@ -36,7 +78,6 @@ class CCRemote {
|
||||
}
|
||||
|
||||
sendCommand(command) {
|
||||
// Iterate over each connected client and send the command
|
||||
this.socket.clients.forEach((client) => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send(command);
|
||||
@ -45,27 +86,20 @@ class CCRemote {
|
||||
}
|
||||
|
||||
sendCode(Code) {
|
||||
// Iterate over each connected client and send the command
|
||||
this.socket.clients.forEach((client) => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send("sendcode");
|
||||
setTimeout(() => {
|
||||
client.send(Code);
|
||||
return true
|
||||
}, 500);
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
runCode() {
|
||||
// Iterate over each connected client and send the command
|
||||
this.socket.clients.forEach((client) => {
|
||||
if (client.readyState === WebSocket.OPEN) {
|
||||
client.send("runcode");
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -77,7 +111,6 @@ class CCRemote {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
module.exports = { CCRemote };
|
||||
|
@ -21,13 +21,15 @@
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Packages Managers" style="background-color: #0087bd;" onclick="openlibraryselect()">
|
||||
<svg viewBox="0 0 24 24"><path d="M21 16.5c0 .38-.21.71-.53.88l-7.9 4.44c-.16.12-.36.18-.57.18-.21 0-.41-.06-.57-.18l-7.9-4.44A.991.991 0 0 1 3 16.5v-9c0-.38.21-.71.53-.88l7.9-4.44c.16-.12.36-.18.57-.18.21 0 .41.06.57.18l7.9 4.44c.32.17.53.5.53.88v9M12 4.15l-1.89 1.07L16 8.61l1.96-1.11L12 4.15M6.04 7.5 12 10.85l1.96-1.1-5.88-3.4L6.04 7.5M5 15.91l6 3.38v-6.71L5 9.21v6.7m14 0v-6.7l-6 3.37v6.71l6-3.38z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Preview code" style="background-color: #0087bd; margin-left: auto; position: absolute; right: 115px;" onclick="clientexit()">
|
||||
<!--
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Preview code" style="background-color: #0087bd; margin-left: auto; position: absolute; right: 115px;">
|
||||
<svg viewBox="0 0 24 24"><path d="M12 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0 8a5 5 0 0 1-5-5 5 5 0 0 1 5-5 5 5 0 0 1 5 5 5 5 0 0 1-5 5m0-12.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()">
|
||||
-->
|
||||
<button class="navbar-button" id="navbar-button-computer-disconnect" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Disconnect Client" style="background-color: #bd0000; margin-left: auto; position: absolute; right: 65px;" onclick="clientexit()" disabled>
|
||||
<svg viewBox="0 0 24 24"><path d="M19 3H5c-1.11 0-2 .89-2 2v4h2V5h14v14H5v-4H3v4a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2V5a2 2 0 0 0-2-2m-8.92 12.58L11.5 17l5-5-5-5-1.42 1.41L12.67 11H3v2h9.67l-2.59 2.58z" /></svg>
|
||||
</button>
|
||||
<button class="navbar-button" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()">
|
||||
<button class="navbar-button" id="navbar-button-computer-run" data-bs-toggle="tooltip" data-bs-placement="bottom" data-bs-title="Run" style="background-color: #10bd00; margin-left: auto;" onclick="gencode()" disabled>
|
||||
<svg viewBox="0 0 24 24"><path d="M8 5.14v14l11-7-11-7z" /></svg>
|
||||
</button>
|
||||
</nav>
|
||||
@ -131,12 +133,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="frontend.js"></script>
|
||||
<script src="virtualcode.js"></script>
|
||||
<script src="index.js"></script>
|
||||
<script src="codegen.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,37 +1,28 @@
|
||||
const { ipcRenderer } = require("electron");
|
||||
const ipc = ipcRenderer;
|
||||
|
||||
// override prompt command
|
||||
window.prompt = function(promptText, defaultValue) {
|
||||
return ipc.sendSync("prompt", promptText, defaultValue);
|
||||
};
|
||||
|
||||
ipc.send("update-startup-status", "Importing module...")
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { ipcRenderer } = require("electron");
|
||||
const { loadperipheral, scanindex } = require("./blocksmanager");
|
||||
const Blockly = require('blockly');
|
||||
const ipc = ipcRenderer;
|
||||
const { WorkspaceSearch } = require("@blockly/plugin-workspace-search")
|
||||
|
||||
let isprojectsaved = false;
|
||||
let isprojectopened = false;
|
||||
let usedlibinproject = []
|
||||
|
||||
ipc.send("update-startup-status", "Initializing blockly workspace...")
|
||||
Blockly.utils.colour.setHsvSaturation(0.9)
|
||||
|
||||
let originaltoolbar = fs.readFileSync(path.join(__dirname, "toolbox.xml"), 'utf8');
|
||||
|
||||
// load some system library
|
||||
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
|
||||
const blocksJson = JSON.parse(sysmodulejson);
|
||||
for (const blockId in blocksJson) {
|
||||
if (blocksJson.hasOwnProperty(blockId)) {
|
||||
Blockly.Blocks[blockId] = {
|
||||
init: function() {
|
||||
this.jsonInit(blocksJson[blockId]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
require("./module_generator")
|
||||
|
||||
try {
|
||||
var workspace = Blockly.inject('blocklyDiv', {
|
||||
toolbox: originaltoolbar,
|
||||
trashcan: true,
|
||||
@ -52,12 +43,36 @@ var workspace = Blockly.inject('blocklyDiv', {
|
||||
}
|
||||
});
|
||||
|
||||
const workspaceSearch = new WorkspaceSearch(workspace);
|
||||
workspaceSearch.init();
|
||||
|
||||
workspace.getToolbox().getFlyout().autoClose = false;
|
||||
} catch (e) {
|
||||
ipc.send("erroronstart", `Error on initializing workspace: ${e}`)
|
||||
}
|
||||
|
||||
try {
|
||||
ipc.send("update-startup-status", "Importing system library...")
|
||||
const sysmodulejson = fs.readFileSync(path.join(__dirname, "module_block_design.json"), 'utf8');
|
||||
const blocksJson = JSON.parse(sysmodulejson);
|
||||
for (const blockId in blocksJson) {
|
||||
if (blocksJson.hasOwnProperty(blockId)) {
|
||||
Blockly.Blocks[blockId] = {
|
||||
init: function() {
|
||||
this.jsonInit(blocksJson[blockId]);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
require("./module_generator")
|
||||
|
||||
ipc.send("update-startup-status", "Scanning library...")
|
||||
scanindex();
|
||||
} catch (e) {
|
||||
ipc.send("erroronstart", `Error on loading block: ${e}`)
|
||||
}
|
||||
workspace.getToolbox().getFlyout().autoClose = false;
|
||||
|
||||
ipc.send("update-startup-status", "Initializing event...")
|
||||
|
||||
ipc.on('export-lua-request', (event) => {
|
||||
console.log("exporting lua")
|
||||
@ -111,6 +126,21 @@ ipc.on('load-workspace', (event, json) => {
|
||||
}, 1000);
|
||||
})
|
||||
|
||||
ipc.on('workspace-saved', (event, success) => {
|
||||
isprojectsaved = success
|
||||
if (!isprojectopened) {
|
||||
isprojectopened = true;
|
||||
}
|
||||
document.getElementById('statusMessage').textContent = `Project Saved`;
|
||||
setTimeout(() => {
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
ipc.on("open-about", () => {
|
||||
document.getElementById('about-popup').style.display = 'block';
|
||||
})
|
||||
|
||||
workspace.addChangeListener(function(event) {
|
||||
if ([Blockly.Events.UI,
|
||||
Blockly.Events.VIEWPORT_CHANGE,
|
||||
@ -149,24 +179,15 @@ document.getElementById("packageman-import-btn").addEventListener('click', () =>
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
ipc.on('workspace-saved', (event, success) => {
|
||||
isprojectsaved = success
|
||||
if (!isprojectopened) {
|
||||
isprojectopened = true;
|
||||
}
|
||||
document.getElementById('statusMessage').textContent = `Project Saved`;
|
||||
setTimeout(() => {
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
ipc.on("open-about", () => {
|
||||
document.getElementById('about-popup').style.display = 'block';
|
||||
})
|
||||
|
||||
// Ensure Blockly container is shown after the workspace is injected
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
ipc.send("update-startup-status", "Finished")
|
||||
setTimeout(() => {
|
||||
ipc.send("ready")
|
||||
}, 500);
|
||||
|
||||
document.getElementById('statusMessage').textContent = "Computer isn't connect";
|
||||
setTimeout(() => {
|
||||
document.getElementById('statusMessage').textContent = `Ready`;
|
||||
}, 10000);
|
@ -67,7 +67,7 @@
|
||||
"colour": 260
|
||||
},
|
||||
"sys_table_add_key_value": {
|
||||
"message0": "Add key %1 with data %2",
|
||||
"message0": "Add key %1 with data %2\nShorthand %3",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
@ -77,6 +77,10 @@
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "VALUE"
|
||||
},
|
||||
{
|
||||
"type": "field_checkbox",
|
||||
"name": "SHORT"
|
||||
}
|
||||
],
|
||||
"output": "Array_Pair",
|
||||
@ -95,7 +99,8 @@
|
||||
"check": "Array"
|
||||
}
|
||||
],
|
||||
"output": "Array",
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 260
|
||||
},
|
||||
"ide_addcode": {
|
||||
@ -121,5 +126,37 @@
|
||||
],
|
||||
"colour": 220,
|
||||
"tooltip": "Not require but make your code easy to read."
|
||||
},
|
||||
"sys_exit": {
|
||||
"message0": "Exit the code",
|
||||
"previousStatement": null,
|
||||
"colour": 38
|
||||
},
|
||||
"sys_write": {
|
||||
"message0": "Write %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "TEXT",
|
||||
"check": "String"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 110,
|
||||
"tooltip": "Writes a line of text to the screen without a newline at the end, wrapping text if necessary."
|
||||
},
|
||||
"sys_print_error": {
|
||||
"message0": "Print error %1",
|
||||
"args0": [
|
||||
{
|
||||
"type": "input_value",
|
||||
"name": "ERROR"
|
||||
}
|
||||
],
|
||||
"previousStatement": null,
|
||||
"nextStatement": null,
|
||||
"colour": 110,
|
||||
"tooltip": "Prints the specified values to the screen in red, separated by spaces, wrapping if necessary. After printing, the cursor is moved to the next line."
|
||||
}
|
||||
}
|
||||
|
@ -41,8 +41,12 @@ luaGenerator.forBlock['sys_table_unpack_to_args'] = function(block, generator) {
|
||||
luaGenerator.forBlock['sys_table_add_key_value'] = function(block, generator) {
|
||||
var key = generator.valueToCode(block, 'KEY', generator.ORDER_NONE);
|
||||
var value = generator.valueToCode(block, 'VALUE', generator.ORDER_NONE);
|
||||
|
||||
var shorted = block.getFieldValue('SHORT') == 'TRUE';
|
||||
if (!shorted) {
|
||||
return [`[${key}] = ${value}`, luaGenerator.ORDER_NONE];
|
||||
} else {
|
||||
return [`${key} = ${value}`, luaGenerator.ORDER_NONE];
|
||||
}
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sys_table_append_data'] = function(block, generator) {
|
||||
@ -81,3 +85,20 @@ main()
|
||||
`
|
||||
return code;
|
||||
};
|
||||
|
||||
|
||||
luaGenerator.forBlock['sys_exit'] = function(block, generator) {
|
||||
return `exit()\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sys_write'] = function(block, generator) {
|
||||
var text = generator.valueToCode(block, 'TEXT', generator.ORDER_NONE);
|
||||
|
||||
return `write(${text})\n`;
|
||||
};
|
||||
|
||||
luaGenerator.forBlock['sys_print_error'] = function(block, generator) {
|
||||
var error = generator.valueToCode(block, 'ERROR', generator.ORDER_NONE);
|
||||
|
||||
return `printError(${error})\n`;
|
||||
};
|
@ -64,9 +64,18 @@
|
||||
<div class="progress-bar">
|
||||
<div class="progress-bar-value"></div>
|
||||
</div>
|
||||
<h6 id="status">Initializing...</h6>
|
||||
</div>
|
||||
<div id="copyright">
|
||||
© 2024 DPSoftware Foundation. Licensed under GPL v3.
|
||||
</div>
|
||||
<script>
|
||||
const { ipcRenderer } = require("electron");
|
||||
const ipc = ipcRenderer;
|
||||
|
||||
ipc.on('change-status', (event, status) => {
|
||||
document.getElementById('status').textContent = status;
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@ -37,6 +37,16 @@ body {
|
||||
font-size: 1.5em; /* Adjust size as needed */
|
||||
}
|
||||
|
||||
.navbar-button:disabled {
|
||||
background-color: #7f8c8d; /* Gray color for disabled state */
|
||||
cursor: not-allowed;
|
||||
opacity: 0.6; /* Makes the button look disabled */
|
||||
}
|
||||
|
||||
.navbar-button:disabled svg {
|
||||
fill: #ffffff; /* Change icon color if needed */
|
||||
}
|
||||
|
||||
.navbar-button:hover {
|
||||
background-color: #0066cc; /* Darken color on hover */
|
||||
z-index: 99;
|
||||
|
@ -3,14 +3,28 @@
|
||||
<block type="text_print">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="text_prompt_ext">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sys_write">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
<block type="sys_print_error">
|
||||
<value name="ERROR">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
@ -60,9 +74,7 @@
|
||||
</block>
|
||||
<block type="controls_forEach"></block>
|
||||
<block type="controls_flow_statements"></block>
|
||||
</category>
|
||||
<category name="Events" colour="45">
|
||||
|
||||
<block type="sys_exit"></block>
|
||||
</category>
|
||||
<category name="Math" colour="230">
|
||||
<block type="math_number" gap="32">
|
||||
@ -176,7 +188,7 @@
|
||||
<block type="text_length">
|
||||
<value name="VALUE">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
@ -195,7 +207,7 @@
|
||||
</value>
|
||||
<value name="FIND">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
@ -216,7 +228,7 @@
|
||||
<block type="text_changeCase">
|
||||
<value name="TEXT">
|
||||
<shadow type="text">
|
||||
<field name="TEXT">abc</field>
|
||||
<field name="TEXT">Hello World!</field>
|
||||
</shadow>
|
||||
</value>
|
||||
</block>
|
||||
|
30
webpack.config.js
Normal file
30
webpack.config.js
Normal file
@ -0,0 +1,30 @@
|
||||
const path = require('path');
|
||||
const nodeExternals = require('webpack-node-externals');
|
||||
|
||||
module.exports = {
|
||||
mode: 'development',
|
||||
entry: './index.js',
|
||||
target: 'electron-main',
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'bundle.js',
|
||||
},
|
||||
externals: [nodeExternals()],
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
presets: ['@babel/preset-env']
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.json']
|
||||
},
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user