-
Notifications
You must be signed in to change notification settings - Fork 136
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactored load.js to load.ts and added a new file loadScope.ts in types #460
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,296 @@ | ||
import { resetScopeList, newCircuit, switchCircuit } from '../circuit' | ||
import { setProjectName } from './save' | ||
import { | ||
scheduleUpdate, | ||
update, | ||
updateSimulationSet, | ||
updateCanvasSet, | ||
gridUpdateSet, | ||
} from '../engine' | ||
import { updateRestrictedElementsInScope } from '../restrictedElementDiv' | ||
import { simulationArea } from '../simulationArea' | ||
|
||
import { loadSubCircuit } from '../subcircuit' | ||
import { scheduleBackup } from './backupCircuit' | ||
import { showProperties } from '../ux' | ||
import { constructNodeConnections, loadNode, replace } from '../node' | ||
import { generateId } from '../utils' | ||
import modules from '../modules' | ||
import { oppositeDirection } from '../canvasApi' | ||
import plotArea from '../plotArea' | ||
import { TestbenchData } from '#/simulator/src/testbench' | ||
import { SimulatorStore } from '#/store/SimulatorStore/SimulatorStore' | ||
import { toRefs } from 'vue' | ||
import { moduleList } from '../metadata' | ||
import { Scope, ProjectData, VerilogMetadata, Layout,TestbenchData, NodeData, CircuitElement, ModuleData } from '../types/loadScope'; // Import required interfaces | ||
|
||
|
||
/** | ||
* Backward compatibility - needs to be deprecated | ||
* @param {CircuitElement} obj - the object to be rectified | ||
* @category data | ||
*/ | ||
function rectifyObjectType(obj: string): string { | ||
const rectify: Record<string, string> = { | ||
FlipFlop: 'DflipFlop', | ||
Ram: 'Rom', | ||
}; | ||
return rectify[obj] || obj; | ||
} | ||
|
||
/** | ||
* Function to load CircuitElements | ||
* @param {ModuleData} data - JSOn data | ||
* @param {Scope} scope - circuit in which we want to load modules | ||
* @category data | ||
*/ | ||
function loadModule(data: ModuleData, scope: Scope): void { | ||
// Create circuit element | ||
const obj = new modules[rectifyObjectType(data.objectType)]( | ||
data.x, | ||
data.y, | ||
scope, | ||
...(data.customData.constructorParamaters || []) | ||
); | ||
// Sets directions | ||
obj.label = data.label; | ||
obj.labelDirection = data.labelDirection || oppositeDirection[fixDirection[obj.direction]]; | ||
|
||
// Sets delay | ||
obj.propagationDelay = data.propagationDelay || obj.propagationDelay; | ||
obj.fixDirection(); | ||
|
||
// Restore other values | ||
if (data.customData.values) { | ||
for (const prop in data.customData.values) { | ||
if (Object.prototype.hasOwnProperty.call(data.customData.values, prop)) { | ||
obj[prop] = data.customData.values[prop]; | ||
} | ||
} | ||
} | ||
|
||
// Replace new nodes with the correct old nodes (with connections) | ||
if (data.customData.nodes) { | ||
for (const node in data.customData.nodes) { | ||
if (Object.prototype.hasOwnProperty.call(data.customData.nodes, node)) { | ||
const n = data.customData.nodes[node]; | ||
if (Array.isArray(n)) { | ||
for (let i = 0; i < n.length; i++) { | ||
obj[node][i] = replace(obj[node][i], n[i].id); // Pass the id of NodeConnection instead of the whole object | ||
} | ||
} else { | ||
obj[node] = replace(obj[node], n.id); // Again, pass the id property of NodeConnection | ||
} | ||
|
||
} | ||
} | ||
} | ||
if (data.subcircuitMetadata) obj.subcircuitMetadata = data.subcircuitMetadata; | ||
} | ||
|
||
/** | ||
* This function shouldn't ideally exist. But temporary fix | ||
* for some issues while loading nodes. | ||
* @category data | ||
*/ | ||
function removeBugNodes(scope: Scope = globalScope): void { | ||
let x = scope.allNodes.length; | ||
for (let i = 0; i < x; i++) { | ||
if ( | ||
scope.allNodes[i].type !== 2 && | ||
scope.allNodes[i].parent.objectType === 'CircuitElement' | ||
) { | ||
scope.allNodes[i].delete?.(); //even if delete doesn't exist, it won't cause any errors | ||
} | ||
if (scope.allNodes.length !== x) { | ||
i = 0; | ||
x = scope.allNodes.length; | ||
} | ||
} | ||
} | ||
Comment on lines
+96
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Consider removing 'removeBugNodes' or clarifying its usage. The 'removeBugNodes' function is labelled as a “temporary fix” but still persists. If this logic is essential, consider documenting the exact cases it covers or incorporate a more robust long-term solution. |
||
|
||
/** | ||
* Function to load a full circuit | ||
* @param {Scope} scope | ||
* @param {ProjectData} data | ||
* @category data | ||
*/ | ||
export function loadScope(scope: Scope, data: ProjectData): void { | ||
const ML = moduleList.slice(); // Module List copy | ||
scope.restrictedCircuitElementsUsed = data.restrictedCircuitElementsUsed; | ||
|
||
// Load all nodes | ||
data.allNodes.forEach((x) => loadNode(x, scope)); | ||
|
||
// Make all connections | ||
for (let i = 0; i < data.allNodes.length; i++) { | ||
constructNodeConnections(scope.allNodes[i], data.allNodes[i]); | ||
} | ||
|
||
// Load all modules | ||
for (let i = 0; i < ML.length; i++) { | ||
if (data[ML[i]]) { | ||
if (ML[i] === 'SubCircuit') { | ||
// Load subcircuits differently | ||
for (let j = 0; j < data[ML[i]].length; j++) { | ||
loadSubCircuit(data[ML[i]][j], scope); | ||
} | ||
} else { | ||
// Load everything else similarly | ||
for (let j = 0; j < data[ML[i]].length; j++) { | ||
loadModule(data[ML[i]][j], scope); | ||
} | ||
} | ||
} | ||
} | ||
|
||
// Update wires accordingly | ||
scope.wires.forEach((x) => { | ||
x.updateData(scope); | ||
}); | ||
|
||
removeBugNodes(scope); // To be deprecated | ||
|
||
// If Verilog Circuit Metadata exists, then restore | ||
if (data.verilogMetadata) { | ||
scope.verilogMetadata = data.verilogMetadata; | ||
} | ||
|
||
// If Test exists, then restore | ||
if (data.testbenchData) { | ||
globalScope.testbenchData = new TestbenchData( | ||
data.testbenchData.testData, | ||
data.testbenchData.currentGroup, | ||
data.testbenchData.currentCase | ||
); | ||
} | ||
|
||
// If layout exists, then restore | ||
if (data.layout) { | ||
scope.layout = data.layout; | ||
} else { | ||
// Else generate new layout according to how it would have been otherwise (backward compatibility) | ||
scope.layout = {}; | ||
scope.layout.width = 100; | ||
scope.layout.height = | ||
Math.max(scope.Input.length, scope.Output.length) * 20 + 20; | ||
scope.layout.title_x = 50; | ||
scope.layout.title_y = 13; | ||
for (let i = 0; i < scope.Input.length; i++) { | ||
scope.Input[i].layoutProperties = { | ||
x: 0, | ||
y: | ||
scope.layout.height / 2 - | ||
scope.Input.length * 10 + | ||
20 * i + | ||
10, | ||
id: generateId(), | ||
}; | ||
} | ||
for (let i = 0; i < scope.Output.length; i++) { | ||
scope.Output[i].layoutProperties = { | ||
x: scope.layout.width, | ||
y: | ||
scope.layout.height / 2 - | ||
scope.Output.length * 10 + | ||
20 * i + | ||
10, | ||
id: generateId(), | ||
}; | ||
} | ||
} | ||
// Backward compatibility | ||
if (scope.layout.titleEnabled === undefined) { | ||
scope.layout.titleEnabled = true; | ||
} | ||
} | ||
|
||
// Function to load project from data | ||
/** | ||
* loads a saved project | ||
* @param {ProjectData} data - the json data of the | ||
* @category data | ||
* @exports load | ||
*/ | ||
export default function load(data: ProjectData | null): void { | ||
// If project is new and no data is there, then just set project name | ||
const simulatorStore = SimulatorStore(); | ||
const { circuit_list } = toRefs(simulatorStore); | ||
|
||
if (!data) { | ||
setProjectName(__projectName); | ||
return; | ||
} | ||
|
||
const { projectId } = data; | ||
setProjectName(data.name); | ||
|
||
globalScope = undefined; | ||
resetScopeList(); // Remove default scope | ||
|
||
// Load all according to the dependency order | ||
for (let i = 0; i < data.scopes.length; i++) { | ||
let isVerilogCircuit = false; | ||
let isMainCircuit = false; | ||
if (data.scopes[i].verilogMetadata) { | ||
isVerilogCircuit = data.scopes[i].verilogMetadata.isVerilogCircuit; | ||
isMainCircuit = data.scopes[i].verilogMetadata.isMainCircuit; | ||
} | ||
|
||
// Create new circuit | ||
const scope = newCircuit( | ||
data.scopes[i].name || 'Untitled', | ||
data.scopes[i].id, | ||
isVerilogCircuit, | ||
isMainCircuit | ||
); | ||
|
||
// Load circuit data | ||
loadScope(scope, data.scopes[i]); | ||
|
||
// Focus circuit | ||
globalScope = scope; | ||
|
||
// Center circuit | ||
if (embed) { | ||
globalScope.centerFocus(true); | ||
} else { | ||
globalScope.centerFocus(false); | ||
} | ||
|
||
// update and backup circuit once | ||
update(globalScope, true); | ||
|
||
// Updating restricted element list initially on loading | ||
updateRestrictedElementsInScope(); | ||
|
||
scheduleBackup(); | ||
} | ||
|
||
// Restore clock | ||
simulationArea.changeClockTime(data.timePeriod || 500); | ||
simulationArea.clockEnabled = | ||
data.clockEnabled === undefined ? true : data.clockEnabled; | ||
|
||
if (!embed) { | ||
showProperties(simulationArea.lastSelected); | ||
} | ||
|
||
// Reorder tabs according to the saved order | ||
if (data.orderedTabs?.length) { | ||
circuit_list.value.sort((a, b) => { | ||
return data.orderedTabs.indexOf(String(a.id)) - data.orderedTabs.indexOf(String(b.id)); | ||
}); | ||
} | ||
|
||
// Switch to last focussedCircuit | ||
if (data.focussedCircuit) switchCircuit(String(data.focussedCircuit)); | ||
|
||
updateSimulationSet(true); | ||
updateCanvasSet(true); | ||
gridUpdateSet(true); | ||
|
||
// Reset Timing | ||
if (!embed) plotArea.reset(); | ||
scheduleUpdate(1); | ||
} |
Check failure
Code scanning / CodeQL
Unvalidated dynamic method call High