Skip to content

Commit 45c8da9

Browse files
committed
adding sample project
1 parent e58fb85 commit 45c8da9

File tree

2 files changed

+63
-26
lines changed

2 files changed

+63
-26
lines changed

logic-editor/src/App.tsx

Lines changed: 62 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useCallback, useMemo } from 'react';
1+
import React, { useState, useCallback, useMemo, useEffect } from 'react';
22
import ReactFlow, {
33
addEdge,
44
MiniMap,
@@ -12,6 +12,7 @@ import ReactFlow, {
1212
import 'reactflow/dist/style.css';
1313
import { downloadJson, uploadJson } from './utils';
1414
import { bytecodeToString, generateBytecode } from './bytecode-gen';
15+
import { defaultProject } from './sample-project';
1516

1617
// Improved ID management
1718
let nodeIdCounter = 0;
@@ -313,6 +314,11 @@ export default function App() {
313314
toggleNode: ToggleNode,
314315
}), []);
315316

317+
// Load default project on first render
318+
useEffect(() => {
319+
loadProjectData(defaultProject);
320+
}, []);
321+
316322
const handleInitialStateChange = useCallback((nodeId: string, initialState: number) => {
317323
setNodes((nds) =>
318324
nds.map((n) =>
@@ -417,32 +423,56 @@ export default function App() {
417423
downloadJson({ nodes, edges, board: selectedBoard }, 'my-logic-project');
418424
};
419425

426+
// Function to load project data (reusable)
427+
const loadProjectData = (data: any) => {
428+
// Reset ID counter based on loaded nodes
429+
resetIdCounter(data.nodes);
430+
431+
// Add event handlers to all nodes when loading
432+
const updatedNodes = data.nodes.map((node: any) => ({
433+
...node,
434+
data: {
435+
...node.data,
436+
selectedBoard: data.board || selectedBoard,
437+
onChangePin: handlePinChange,
438+
onChangeInputs: handleInputsChange,
439+
onChangeInitialState: node.type === 'latchNode' || node.type === 'toggleNode' ? handleInitialStateChange : undefined,
440+
onChangePulseLength: node.type === 'pulseNode' ? handlePulseLengthChange : undefined,
441+
onChangeInterval: node.type === 'pulseNode' ? handleIntervalChange : undefined,
442+
},
443+
}));
444+
445+
setNodes(updatedNodes);
446+
setEdges(data.edges);
447+
if (data.board) setSelectedBoard(data.board);
448+
};
449+
420450
const handleUpload = () => {
421451
uploadJson((data) => {
422452
if (data.nodes && data.edges) {
423-
// Reset ID counter based on loaded nodes
424-
resetIdCounter(data.nodes);
425-
426-
// Add event handlers to all nodes when loading
427-
const updatedNodes = data.nodes.map((node: any) => ({
428-
...node,
429-
data: {
430-
...node.data,
431-
selectedBoard: data.board || selectedBoard,
432-
onChangePin: handlePinChange,
433-
onChangeInputs: handleInputsChange,
434-
},
435-
}));
436-
437-
setNodes(updatedNodes);
438-
setEdges(data.edges);
439-
if (data.board) setSelectedBoard(data.board);
453+
loadProjectData(data);
440454
} else {
441455
alert('Invalid project file');
442456
}
443457
});
444458
};
445459

460+
// Reset UI function
461+
const handleReset = () => {
462+
setNodes([]);
463+
setEdges([]);
464+
nodeIdCounter = 0;
465+
setUploadStatus('UI has been reset');
466+
setTimeout(() => setUploadStatus(null), 3000);
467+
};
468+
469+
// Load default project function
470+
const loadDefaultProject = () => {
471+
loadProjectData(defaultProject);
472+
setUploadStatus('Default project loaded');
473+
setTimeout(() => setUploadStatus(null), 3000);
474+
};
475+
446476
const getArduinoInoFile = async () => {
447477
const githubUrl = 'https://raw.githubusercontent.com/MerzSebastian/OpenPLC/refs/heads/main/arduino/arduino.ino';
448478
const response = await fetch(githubUrl);
@@ -609,26 +639,32 @@ export default function App() {
609639
</div>
610640
))}
611641

612-
<button onClick={handleDownload} className="mt-6 w-full bg-blue-500 text-white p-1 rounded">
642+
<button onClick={handleUpload} className="mt-6 w-full bg-gray-500 text-white p-1 rounded">
643+
Load Project
644+
</button>
645+
<button onClick={handleDownload} className="mt-1 w-full bg-blue-500 text-white p-1 rounded">
613646
Download Project
614647
</button>
615-
<button onClick={handleUpload} className="mt-1 w-full bg-gray-500 text-white p-1 rounded">
616-
Load Project
648+
<button onClick={handleReset} className="mt-1 w-full bg-red-500 text-white p-1 rounded">
649+
Reset Project
617650
</button>
618-
<button onClick={copyBytecode} className="mt-1 w-full bg-green-600 text-white p-1 rounded">
651+
<button onClick={loadDefaultProject} className="mt-1 w-full bg-indigo-500 text-white p-1 rounded">
652+
Load Default Project
653+
</button>
654+
<button onClick={uploadBytecodeViaWebSerial} className="mt-6 w-full bg-purple-600 text-white p-1 rounded">
655+
Upload Project to Arduino
656+
</button>
657+
<button onClick={copyBytecode} className="mt-1 mb-5 w-full bg-green-600 text-white p-1 rounded">
619658
Copy Code for testing on Wokwi.com
620659
</button>
621660
<button onClick={copyArduinoCode} className="mt-1 w-full bg-orange-600 text-white p-1 rounded">
622661
Copy Arduino Code
623662
</button>
624-
<button onClick={uploadBytecodeViaWebSerial} className="mt-1 w-full bg-purple-600 text-white p-1 rounded">
625-
Upload Project to Arduino
626-
</button>
627663
When you want to test on Wokwi.com you can use see the default project <a className='text-blue-700' href='https://wokwi.com/projects/441553408946374657'>here</a>
628664

629665
{uploadStatus && (
630666
<div className={`mt-2 p-2 text-center text-sm rounded ${
631-
uploadStatus.includes('success') || uploadStatus.includes('copied')
667+
uploadStatus.includes('success') || uploadStatus.includes('copied') || uploadStatus.includes('loaded') || uploadStatus.includes('reset')
632668
? 'bg-green-100 text-green-800'
633669
: 'bg-red-100 text-red-800'
634670
}`}>

logic-editor/src/sample-project.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const defaultProject = { "nodes": [{ "id": "dndnode_0", "type": "orNode", "position": { "x": 241.241969952952, "y": 216.73858248031 }, "data": { "label": "orNode", "inputs": 2, "selectedBoard": "arduino_nano" }, "width": 109, "height": 76, "selected": false, "positionAbsolute": { "x": 241.241969952952, "y": 216.73858248031 }, "dragging": false }, { "id": "dndnode_1", "type": "inputNode", "position": { "x": 99.0525726762845, "y": 120.38101845944 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "2" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 99.0525726762845, "y": 120.38101845944 }, "dragging": false }, { "id": "dndnode_2", "type": "outputNode", "position": { "x": 583.847337035519, "y": 260.636051960996 }, "data": { "label": "outputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "8" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 583.847337035519, "y": 260.636051960996 }, "dragging": false }, { "id": "dndnode_3", "type": "inputNode", "position": { "x": 99.4330577928179, "y": 186.453426300785 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "3" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 99.4330577928179, "y": 186.453426300785 }, "dragging": false }, { "id": "dndnode_4", "type": "inputNode", "position": { "x": 99.1067031003101, "y": 251.878940946015 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "4" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 99.1067031003101, "y": 251.878940946015 }, "dragging": false }, { "id": "dndnode_5", "type": "inputNode", "position": { "x": 98.912141723119, "y": 316.686258832949 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "5" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 98.912141723119, "y": 316.686258832949 }, "dragging": false }, { "id": "dndnode_6", "type": "inputNode", "position": { "x": 98.0021028990381, "y": 383.119092990855 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "6" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 98.0021028990381, "y": 383.119092990855 }, "dragging": false }, { "id": "dndnode_8", "type": "notNode", "position": { "x": 259.629661527553, "y": 143.97344363477 }, "data": { "label": "notNode", "inputs": 2, "selectedBoard": "arduino_nano" }, "width": 80, "height": 48, "selected": false, "positionAbsolute": { "x": 259.629661527553, "y": 143.97344363477 }, "dragging": false }, { "id": "dndnode_12", "type": "andNode", "position": { "x": 446.273766755506, "y": 259.353231519314 }, "data": { "label": "andNode", "inputs": 4, "selectedBoard": "arduino_nano" }, "width": 100, "height": 65, "selected": false, "dragging": false, "positionAbsolute": { "x": 446.273766755506, "y": 259.353231519314 } }, { "id": "dndnode_13", "type": "toggleNode", "position": { "x": 240.352027954439, "y": 319.013558181499 }, "data": { "label": "toggleNode", "inputs": 2, "selectedBoard": "arduino_nano" }, "width": 115, "height": 62, "selected": false, "positionAbsolute": { "x": 240.352027954439, "y": 319.013558181499 }, "dragging": false }, { "id": "dndnode_14", "type": "latchNode", "position": { "x": 240.352027954439, "y": 413.701592373082 }, "data": { "label": "latchNode", "inputs": 2, "selectedBoard": "arduino_nano" }, "width": 115, "height": 90, "selected": false, "positionAbsolute": { "x": 240.352027954439, "y": 413.701592373082 }, "dragging": false }, { "id": "dndnode_15", "type": "inputNode", "position": { "x": 97.8163169107269, "y": 447.95045580408 }, "data": { "label": "inputNode", "inputs": 2, "selectedBoard": "arduino_nano", "pin": "7" }, "width": 100, "height": 62, "selected": false, "positionAbsolute": { "x": 97.8163169107269, "y": 447.95045580408 }, "dragging": false }], "edges": [{ "source": "dndnode_1", "sourceHandle": "out", "target": "dndnode_8", "targetHandle": "in", "id": "reactflow__edge-dndnode_1out-dndnode_8in" }, { "source": "dndnode_3", "sourceHandle": "out", "target": "dndnode_0", "targetHandle": "in0", "id": "reactflow__edge-dndnode_3out-dndnode_0in0" }, { "source": "dndnode_4", "sourceHandle": "out", "target": "dndnode_0", "targetHandle": "in1", "id": "reactflow__edge-dndnode_4out-dndnode_0in1" }, { "source": "dndnode_8", "sourceHandle": "out", "target": "dndnode_12", "targetHandle": "in0", "id": "reactflow__edge-dndnode_8out-dndnode_12in0" }, { "source": "dndnode_0", "sourceHandle": "out", "target": "dndnode_12", "targetHandle": "in1", "id": "reactflow__edge-dndnode_0out-dndnode_12in1" }, { "source": "dndnode_12", "sourceHandle": "out", "target": "dndnode_2", "targetHandle": "in", "id": "reactflow__edge-dndnode_12out-dndnode_2in" }, { "source": "dndnode_5", "sourceHandle": "out", "target": "dndnode_13", "targetHandle": "in", "id": "reactflow__edge-dndnode_5out-dndnode_13in" }, { "source": "dndnode_13", "sourceHandle": "out", "target": "dndnode_12", "targetHandle": "in2", "id": "reactflow__edge-dndnode_13out-dndnode_12in2" }, { "source": "dndnode_6", "sourceHandle": "out", "target": "dndnode_14", "targetHandle": "set", "id": "reactflow__edge-dndnode_6out-dndnode_14set" }, { "source": "dndnode_15", "sourceHandle": "out", "target": "dndnode_14", "targetHandle": "reset", "id": "reactflow__edge-dndnode_15out-dndnode_14reset" }, { "source": "dndnode_14", "sourceHandle": "out", "target": "dndnode_12", "targetHandle": "in3", "id": "reactflow__edge-dndnode_14out-dndnode_12in3" }], "board": "arduino_nano" };

0 commit comments

Comments
 (0)