Created with <3 with dartpad.dev.
Last active
September 26, 2023 16:17
-
-
Save stephanedeluca/6bcf5142dccc0fe5f22111d75300b994 to your computer and use it in GitHub Desktop.
Debugger
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Interactive debugger by Sdl https://Stephanedeluca.com | |
// on Tuesday September 27th 2023 to answer https://stackoverflow.com/posts/77181687 | |
import "dart:async"; | |
import 'package:flutter/material.dart'; | |
const Color darkBlue = Color.fromARGB(255, 18, 32, 47); | |
void main() { | |
runApp(MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData.dark().copyWith( | |
scaffoldBackgroundColor: darkBlue, | |
), | |
debugShowCheckedModeBanner: false, | |
home: Scaffold( | |
body: Center( | |
child: MyWidget(), | |
), | |
), | |
); | |
} | |
} | |
class MyWidget extends StatelessWidget { | |
@override | |
Widget build(BuildContext context) { | |
return Debugger( | |
Simulator() | |
); | |
} | |
} | |
class Simulator extends ChangeNotifier { | |
/// The timer we use to run the program | |
late final Timer _timer ; | |
Simulator() { | |
_timer = Timer.periodic( | |
const Duration(seconds: 1), _simulator); | |
} | |
/// The program to execute | |
final List<String>program = List.generate(100,(e)=> | |
"Instruction $e"); | |
/// The instruction to execute | |
int _ip=0; | |
int get ip=>_ip; | |
set ip(int value) { | |
if (value>program.length) {_ip=0;} | |
else if (value<0) {_ip = 0;} | |
else { | |
_ip = value; | |
} | |
notifyListeners(); | |
} | |
/// Move to next instruction | |
void _simulator(t) { | |
ip = ip+1; | |
} | |
@override | |
void dispose() { | |
_timer.cancel(); | |
super.dispose(); | |
} | |
} | |
class Debugger extends StatelessWidget { | |
final Simulator simulator; | |
Debugger(this.simulator); | |
/// the key that points the current instruction widget | |
final currentIp = GlobalKey(); | |
@override Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: const Text("Battery BMS simulator"), | |
), | |
body: Card( | |
child: AnimatedBuilder( | |
animation: simulator, | |
builder: (context, child) { | |
final allSteps = <Widget>[]; | |
for(int i=0; i< simulator.program.length; i++){ | |
final v = simulator.program[i]; | |
bool isInstructionRunning = simulator._ip == i; | |
final key = isInstructionRunning? currentIp : null; | |
allSteps.add( | |
ListTile( | |
key:key, | |
leading:Icon(isInstructionRunning?Icons.run_circle:Icons.pause), | |
title: Text(v), | |
) | |
); | |
} | |
WidgetsBinding.instance.addPostFrameCallback((_) { | |
if (currentIp.currentContext == null) return; | |
/// Make the current IP visible | |
Scrollable.ensureVisible( | |
currentIp.currentContext!, | |
duration: const Duration(seconds: 1), | |
); | |
}); | |
return SingleChildScrollView( | |
physics: const BouncingScrollPhysics(), | |
child: Column(children: allSteps), | |
); | |
}), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment