Created
June 4, 2024 15:19
-
-
Save atreeon/2bc13fda4f6c5ca4d229995007b73ec9 to your computer and use it in GitHub Desktop.
BlocProvider placement efficiency
This file contains hidden or 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
// ignore_for_file: unused_field | |
import 'dart:async'; | |
import 'package:flutter/material.dart'; | |
import 'package:flutter_bloc/flutter_bloc.dart'; | |
void main() { | |
CounterRepo_Sing().init(0); | |
runApp(const MyApp()); | |
} | |
class MyApp extends StatelessWidget { | |
const MyApp({super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
title: 'Flutter Demo', | |
home: MyHomePage(), | |
); | |
} | |
} | |
class CounterRepo_Event {} | |
class CounterRepo_Sing { | |
factory CounterRepo_Sing() => _instance; | |
static final CounterRepo_Sing _instance = CounterRepo_Sing._internal(); | |
CounterRepo_Sing._internal(); | |
void init(int state) { | |
_state = state; | |
} | |
final _controller = StreamController<CounterRepo_Event>.broadcast(); | |
late int _state; | |
int get state => _state; | |
Stream<CounterRepo_Event> get onUpdate async* { | |
yield* _controller.stream; | |
} | |
void addOne() { | |
_state++; | |
_controller.add(CounterRepo_Event()); | |
} | |
} | |
class CounterBlocState { | |
final int counter; | |
final bool showStats; | |
CounterBlocState({required this.counter, required this.showStats}); | |
CounterBlocState copyWith({int? counter, bool? showStats}) => CounterBlocState( | |
counter: counter ?? this.counter, | |
showStats: showStats ?? this.showStats, | |
); | |
} | |
abstract class CounterBloc_Event {} | |
class CounterAddOne extends CounterBloc_Event {} | |
class ShowStatsToggle extends CounterBloc_Event {} | |
class CounterBloc extends Bloc<CounterBloc_Event, CounterBlocState> { | |
final CounterRepo_Sing _counterRepo; | |
CounterBloc({ | |
required CounterRepo_Sing counterRepo, | |
required CounterBlocState initialState, | |
}) : _counterRepo = counterRepo, | |
super(initialState) { | |
on<CounterAddOne>(_onCounterAddOne); | |
on<ShowStatsToggle>(_onShowStatsToggle); | |
} | |
void _onCounterAddOne(CounterAddOne event, Emitter<CounterBlocState> emit) { | |
_counterRepo.addOne(); | |
emit(state.copyWith(counter: _counterRepo.state)); | |
} | |
void _onShowStatsToggle(ShowStatsToggle event, Emitter<CounterBlocState> emit) { | |
emit(state.copyWith(showStats: !state.showStats)); | |
} | |
} | |
class StatsBloc_Event {} | |
class CounterRepoUpdated extends StatsBloc_Event {} | |
class StatsBloc extends Bloc<StatsBloc_Event, double> { | |
final CounterRepo_Sing _counterRepo; | |
late StreamSubscription<CounterRepo_Event> _counterSubscription; | |
StatsBloc({ | |
required CounterRepo_Sing counterRepo, | |
required double initialState, | |
}) : _counterRepo = counterRepo, | |
super(initialState) { | |
on<CounterRepoUpdated>(_onCounterRepoUpdated); | |
_counterSubscription = _counterRepo.onUpdate.listen((event) => // | |
this.add(CounterRepoUpdated())); | |
} | |
void _onCounterRepoUpdated(CounterRepoUpdated event, Emitter<double> emit) { | |
var piForDigits = calculatePi(_counterRepo.state); | |
emit(piForDigits); | |
} | |
@override | |
Future<void> close() { | |
_counterSubscription.cancel(); | |
return super.close(); | |
} | |
} | |
class MyHomePage extends StatelessWidget { | |
Widget build(BuildContext context) { | |
return BlocProvider( | |
create: (_) => CounterBloc( | |
counterRepo: CounterRepo_Sing(), | |
initialState: CounterBlocState(counter: 0, showStats: false), | |
), | |
child: MyCounterApp(), | |
); | |
} | |
} | |
class MyCounterApp extends StatelessWidget { | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar(backgroundColor: Theme.of(context).colorScheme.inversePrimary), | |
body: Center( | |
child: BlocBuilder<CounterBloc, CounterBlocState>( | |
builder: (context, state) => Column( | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: [ | |
const Text('You have pushed the button this many times:'), | |
Text( | |
'${state.counter}', | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
if (state.showStats) // | |
BlocProvider( | |
create: (_) => StatsBloc( | |
counterRepo: CounterRepo_Sing(), | |
initialState: 0, | |
), | |
child: BlocBuilder<StatsBloc, double>( | |
builder: (context, state) => Text( | |
'Value for pi is $state', | |
style: Theme.of(context).textTheme.headlineMedium, | |
), | |
), | |
), | |
], | |
), | |
), | |
), | |
persistentFooterButtons: [ | |
BlocBuilder<CounterBloc, CounterBlocState>( | |
builder: (context, state) => ElevatedButton( | |
onPressed: () => context.read<CounterBloc>().add(ShowStatsToggle()), | |
child: Text(state.showStats ? 'Hide Stats' : 'Show Stats'), | |
), | |
), | |
], | |
floatingActionButton: FloatingActionButton( | |
onPressed: () => context.read<CounterBloc>().add(CounterAddOne()), | |
tooltip: 'Increment', | |
child: const Icon(Icons.add), | |
), | |
); | |
} | |
} | |
double calculatePi(int iterations) { | |
double pi = 0.0; | |
for (int i = 0; i < iterations * 50000000; i++) { | |
// Simulate complex calculation using Leibniz formula for Pi | |
double term = ((i % 2) == 0) ? 1.0 : -1.0; | |
pi += (4.0 / (2 * i + 1)) * term; | |
} | |
return pi; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment