diff --git a/src/simulator/src/data/backupCircuit.js b/src/simulator/src/data/backupCircuit.js deleted file mode 100644 index e15f5e444..000000000 --- a/src/simulator/src/data/backupCircuit.js +++ /dev/null @@ -1,85 +0,0 @@ -import { projectSavedSet } from './project' -import { moduleList, updateOrder } from '../metadata' - -/* eslint-disable no-param-reassign */ -function extract(obj) { - return obj.saveObject() -} - -// Check if there is anything to backup - to be deprecated -/** - * Check if backup is available - * @param {Scope} scope - * @return {boolean} - * @category data - */ -export function checkIfBackup(scope) { - for (let i = 0; i < updateOrder.length; i++) { - if (scope[updateOrder[i]].length) return true - } - return false -} - -export function backUp(scope = globalScope) { - // Disconnection of subcircuits are needed because these are the connections between nodes - // in current scope and those in the subcircuit's scope - for (let i = 0; i < scope.SubCircuit.length; i++) { - scope.SubCircuit[i].removeConnections() - } - - var data = {} - - // Storing layout - data.layout = scope.layout - - // Storing Verilog Properties - data.verilogMetadata = scope.verilogMetadata - - // Storing all nodes - data.allNodes = scope.allNodes.map(extract) - - // Storing test attached to scope - data.testbenchData = scope.testbenchData - - // Storing other details - data.id = scope.id - data.name = scope.name - - // Storing details of all module objects - for (let i = 0; i < moduleList.length; i++) { - if (scope[moduleList[i]].length) { - data[moduleList[i]] = scope[moduleList[i]].map(extract) - } - } - - // Adding restricted circuit elements used in the save data - data.restrictedCircuitElementsUsed = scope.restrictedCircuitElementsUsed - - // Storing intermediate nodes (nodes in wires) - data.nodes = [] - for (let i = 0; i < scope.nodes.length; i++) { - data.nodes.push(scope.allNodes.indexOf(scope.nodes[i])) - } - - // Restoring the connections - for (let i = 0; i < scope.SubCircuit.length; i++) { - scope.SubCircuit[i].makeConnections() - } - - return data -} - -export function scheduleBackup(scope = globalScope) { - var backup = JSON.stringify(backUp(scope)) - if ( - scope.backups.length === 0 || - scope.backups[scope.backups.length - 1] !== backup - ) { - scope.backups.push(backup) - scope.history = [] - scope.timeStamp = new Date().getTime() - projectSavedSet(false) - } - - return backup -} diff --git a/src/simulator/src/data/backupCircuit.ts b/src/simulator/src/data/backupCircuit.ts new file mode 100644 index 000000000..b51d1aa45 --- /dev/null +++ b/src/simulator/src/data/backupCircuit.ts @@ -0,0 +1,122 @@ +import { projectSavedSet } from './project'; +import { moduleList, updateOrder } from '../metadata'; + +/* eslint-disable no-param-reassign */ + +// ------------------ +// Type Declarations +// ------------------ + +interface NodeLike { + saveObject: () => Record; +} + +interface SubCircuitLike { + removeConnections: () => void; + makeConnections: () => void; +} + +interface Scope { + SubCircuit: SubCircuitLike[]; + allNodes: NodeLike[]; + nodes: NodeLike[]; + layout: Record; + verilogMetadata: Record; + testbenchData: Record; + id: number; + name: string; + restrictedCircuitElementsUsed: Record; + backups: string[]; + history: string[]; + timeStamp: number; + [key: string]: any; // For dynamic moduleList entries +} + +// Global declaration (CircuitVerse uses globalScope) +declare const globalScope: Scope; + +// ------------------ +// Helper Functions +// ------------------ + +function extract(obj: NodeLike): Record { + return obj.saveObject(); +} + +/** + * Check if backup is available + * @param scope Circuit scope + * @returns true if any data exists for backup + * @category data + */ +export function checkIfBackup(scope: Scope): boolean { + for (let i = 0; i < updateOrder.length; i++) { + const key = updateOrder[i]; + if (scope[key]?.length) return true; + } + return false; +} + +/** + * Create a serialized backup of the current circuit state. + * @param scope Current working scope (defaults to globalScope) + * @returns JSON-compatible backup data object + */ +export function backUp(scope: Scope = globalScope): Record { + // Disconnect subcircuits before saving + for (const sub of scope.SubCircuit) { + sub.removeConnections(); + } + + const data: Record = { + layout: scope.layout, + verilogMetadata: scope.verilogMetadata, + allNodes: scope.allNodes.map(extract), + testbenchData: scope.testbenchData, + id: scope.id, + name: scope.name, + }; + + // Save all module objects dynamically + for (const moduleName of moduleList) { + if (scope[moduleName]?.length) { + data[moduleName] = scope[moduleName].map(extract); + } + } + + data.restrictedCircuitElementsUsed = scope.restrictedCircuitElementsUsed; + + // Save intermediate nodes (wire nodes) + data.nodes = scope.nodes.map(node => + scope.allNodes.indexOf(node) + ); + + // Reconnect subcircuits after saving + for (const sub of scope.SubCircuit) { + sub.makeConnections(); + } + + return data; +} + +/** + * Schedule a new backup in the current scope. + * Ensures duplicates aren’t stored consecutively. + * @param scope Current scope (default = globalScope) + * @returns The serialized backup string + */ +export function scheduleBackup(scope: Scope = globalScope): string { + const backup = JSON.stringify(backUp(scope)); + + if ( + scope.backups.length === 0 || + scope.backups[scope.backups.length - 1] !== backup + ) { + scope.backups.push(backup); + scope.history = []; + scope.timeStamp = Date.now(); + projectSavedSet(false); + } + + return backup; +}