mirror of
https://github.com/dancojocaru2000/logic-circuits-simulator.git
synced 2025-02-22 17:19:36 +02:00
For now just the code, without UI that shows the simulation. However, the code works. Also added ground work for visual designer.
110 lines
No EOL
3.4 KiB
Dart
110 lines
No EOL
3.4 KiB
Dart
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:logic_circuits_simulator/models.dart';
|
|
import 'package:path_provider/path_provider.dart';
|
|
import 'package:path/path.dart' as path;
|
|
import 'package:uuid/uuid.dart';
|
|
|
|
class ProjectState extends ChangeNotifier {
|
|
bool _dirty = false;
|
|
final List<Future Function(ProjectEntry)> _saveHandlers = [];
|
|
|
|
ProjectEntry? _currentProject;
|
|
ProjectIndex _index = const ProjectIndex(components: []);
|
|
|
|
ProjectEntry? get currentProject => _currentProject;
|
|
ProjectIndex get index => _index;
|
|
bool get needsSaving => currentProject != null && _dirty;
|
|
|
|
Future<Directory> _getProjectDir() async {
|
|
if (_currentProject == null) {
|
|
throw Exception('Cannot get project directory of null');
|
|
}
|
|
final appDir = await getApplicationDocumentsDirectory();
|
|
final result = Directory(path.join(appDir.path, 'LogicCircuitsSimulator', 'projects', _currentProject!.projectId));
|
|
if (!await result.exists()) {
|
|
await result.create(recursive: true);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
Future<File> _getIndexFile() async {
|
|
final result = File(path.join((await _getProjectDir()).path, 'index.json'));
|
|
return result;
|
|
}
|
|
|
|
Future<void> _loadProjectFiles() async {
|
|
final indexFile = await _getIndexFile();
|
|
if (!await indexFile.exists()) {
|
|
_index = const ProjectIndex(components: []);
|
|
await indexFile.writeAsString(const JsonEncoder.withIndent(" ").convert(_index.toJson()));
|
|
}
|
|
else {
|
|
_index = ProjectIndex.fromJson(jsonDecode(await indexFile.readAsString()));
|
|
}
|
|
}
|
|
|
|
Future<void> _updateIndex(ProjectIndex newIndex) async {
|
|
_dirty = true;
|
|
_index = newIndex;
|
|
final indexFile = await _getIndexFile();
|
|
await indexFile.writeAsString(const JsonEncoder.withIndent(" ").convert(index.toJson()));
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> setCurrentProject(ProjectEntry? p) {
|
|
_currentProject = p;
|
|
return _loadProjectFiles().then((_) => notifyListeners());
|
|
}
|
|
|
|
void noProject() {
|
|
_currentProject = null;
|
|
_index = const ProjectIndex(components: []);
|
|
notifyListeners();
|
|
}
|
|
|
|
Future<void> deleteComponent(String componentId) async {
|
|
await _updateIndex(index.copyWith(components: index.components.where((c) => c.componentId != componentId).toList()));
|
|
}
|
|
|
|
Future<ComponentEntry> newComponent() async {
|
|
final newComponent = ComponentEntry(
|
|
componentId: const Uuid().v4(),
|
|
componentName: '',
|
|
inputs: [],
|
|
outputs: [],
|
|
visualDesigned: false,
|
|
dependencies: [],
|
|
);
|
|
await _updateIndex(index.copyWith(components: index.components + [newComponent]));
|
|
return newComponent;
|
|
}
|
|
|
|
Future<void> editComponent(ComponentEntry component) async {
|
|
if (!index.components.map((c) => c.componentId).contains(component.componentId)) {
|
|
throw Exception('Component not in index!');
|
|
}
|
|
await _updateIndex(
|
|
index.copyWith(
|
|
components: index.components
|
|
.where((c) => c.componentId != component.componentId)
|
|
.toList() + [component],
|
|
)
|
|
);
|
|
}
|
|
|
|
Future<void> saveProject() async {
|
|
if (!needsSaving) return;
|
|
_currentProject = currentProject?.copyWith(lastUpdate: DateTime.now());
|
|
await Future.wait(_saveHandlers.map((h) => h(_currentProject!)));
|
|
_saveHandlers.clear();
|
|
_dirty = false;
|
|
notifyListeners();
|
|
}
|
|
|
|
void registerSaveHandler(Future Function(ProjectEntry) handler) {
|
|
_saveHandlers.add(handler);
|
|
}
|
|
} |