Skip to content

Instantly share code, notes, and snippets.

@atreeon
Created June 4, 2024 15:19
Show Gist options
  • Save atreeon/2bc13fda4f6c5ca4d229995007b73ec9 to your computer and use it in GitHub Desktop.
Save atreeon/2bc13fda4f6c5ca4d229995007b73ec9 to your computer and use it in GitHub Desktop.
BlocProvider placement efficiency
// 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