Skip to content

Commit 5beca73

Browse files
committed
Extract compilable debugging examples from debugging_tracing.md (10/12)
Created debugging_patterns.dart with 8 regions: - track_rebuild_frequency - isolate_problem - measure_rebuild_cost - profile_memory - find_excessive_watch_calls - custom_watch_wrapper_logging - conditional_tracing - detect_watch_ordering_violations Extracted only GOOD (compilable) debugging examples. BAD examples showing errors are intentionally left inline in markdown. Examples compile successfully (10 info warnings only). Progress: 10 files done, 2 remaining.
1 parent 8995f94 commit 5beca73

File tree

2 files changed

+190
-169
lines changed

2 files changed

+190
-169
lines changed
Lines changed: 182 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// ignore_for_file: unused_local_variable, unreachable_from_main, undefined_class, unused_element, dead_code
2+
import 'package:flutter/material.dart';
3+
import 'package:watch_it/watch_it.dart';
4+
import '_shared/stubs.dart';
5+
6+
final di = GetIt.instance;
7+
8+
// NOTE: This file contains GOOD debugging examples only.
9+
// BAD examples that demonstrate errors are left inline in the documentation.
10+
11+
// #region track_rebuild_frequency
12+
class TrackRebuildFrequency extends WatchingWidget {
13+
static int _buildCount = 0;
14+
15+
@override
16+
Widget build(BuildContext context) {
17+
print('TodoList rebuild #${++_buildCount} at ${DateTime.now()}');
18+
19+
final todos = watchValue((TodoManager m) => m.todos);
20+
return ListView.builder(
21+
itemCount: todos.length,
22+
itemBuilder: (context, index) => Text(todos[index].title),
23+
);
24+
}
25+
}
26+
// #endregion track_rebuild_frequency
27+
28+
// #region isolate_problem
29+
// Minimal test widget
30+
class IsolateProblemDebugWidget extends WatchingWidget {
31+
@override
32+
Widget build(BuildContext context) {
33+
print('DebugWidget.build()');
34+
35+
final data = watchValue((DataManager m) => m.data);
36+
print('Data value: $data');
37+
38+
return Text('Data: $data');
39+
}
40+
}
41+
// #endregion isolate_problem
42+
43+
// #region measure_rebuild_cost
44+
class MeasureRebuildCost extends WatchingWidget {
45+
@override
46+
Widget build(BuildContext context) {
47+
final stopwatch = Stopwatch()..start();
48+
49+
final data = watchValue((DataManager m) => m.data);
50+
// ... build UI
51+
52+
stopwatch.stop();
53+
print('ExpensiveWidget.build() took ${stopwatch.elapsedMicroseconds}μs');
54+
55+
return Text(data);
56+
}
57+
}
58+
// #endregion measure_rebuild_cost
59+
60+
// #region profile_memory
61+
class MemoryProfiler {
62+
static void logCurrentUsage(String label) {
63+
// In real app, use dart:developer
64+
print('[$label] Memory check');
65+
}
66+
}
67+
68+
class ProfileMemoryWidget extends WatchingWidget {
69+
@override
70+
Widget build(BuildContext context) {
71+
MemoryProfiler.logCurrentUsage('TodoList.build');
72+
73+
final todos = watchValue((TodoManager m) => m.todos);
74+
return ListView.builder(
75+
itemCount: todos.length,
76+
itemBuilder: (context, index) => Text(todos[index].title),
77+
);
78+
}
79+
}
80+
// #endregion profile_memory
81+
82+
// #region find_excessive_watch_calls
83+
class FindExcessiveWatchCalls extends WatchingWidget {
84+
static final _watchCalls = <String, int>{};
85+
86+
T _profiledWatch<T>(String label, T Function() fn) {
87+
_watchCalls[label] = (_watchCalls[label] ?? 0) + 1;
88+
if (_watchCalls[label]! % 100 == 0) {
89+
print('$label called ${_watchCalls[label]} times');
90+
}
91+
return fn();
92+
}
93+
94+
@override
95+
Widget build(BuildContext context) {
96+
final todos = _profiledWatch(
97+
'todos',
98+
() => watchValue((TodoManager m) => m.todos),
99+
);
100+
101+
return ListView.builder(
102+
itemCount: todos.length,
103+
itemBuilder: (context, index) => Text(todos[index].title),
104+
);
105+
}
106+
}
107+
// #endregion find_excessive_watch_calls
108+
109+
// #region custom_watch_wrapper_logging
110+
extension WatchDebug on WatchingWidget {
111+
T debugWatch<T>(
112+
String label,
113+
T Function() watchFn,
114+
) {
115+
print('[WATCH] $label - subscribing');
116+
final result = watchFn();
117+
print('[WATCH] $label - value: $result');
118+
return result;
119+
}
120+
}
121+
122+
class CustomWatchWrapperWidget extends WatchingWidget {
123+
@override
124+
Widget build(BuildContext context) {
125+
final todos = debugWatch(
126+
'todos',
127+
() => watchValue((TodoManager m) => m.todos),
128+
);
129+
130+
return ListView.builder(
131+
itemCount: todos.length,
132+
itemBuilder: (context, index) => Text(todos[index].title),
133+
);
134+
}
135+
}
136+
// #endregion custom_watch_wrapper_logging
137+
138+
// #region conditional_tracing
139+
class ConditionalTracingWidget extends WatchingWidget {
140+
final bool enableTracing;
141+
142+
ConditionalTracingWidget({this.enableTracing = false});
143+
144+
@override
145+
Widget build(BuildContext context) {
146+
if (enableTracing) {
147+
print('Building $runtimeType');
148+
}
149+
150+
final data = watchValue((DataManager m) => m.data);
151+
152+
if (enableTracing) {
153+
print('Data value: $data');
154+
}
155+
156+
return Text('$data');
157+
}
158+
}
159+
// #endregion conditional_tracing
160+
161+
// #region detect_watch_ordering_violations
162+
class StrictWatchingWidget extends WatchingWidget {
163+
final _watchLabels = <String>[];
164+
165+
T _strictWatch<T>(String label, T Function() fn) {
166+
if (_watchLabels.contains(label)) {
167+
throw StateError('Duplicate watch call: $label');
168+
}
169+
_watchLabels.add(label);
170+
return fn();
171+
}
172+
173+
// Use in subclasses:
174+
// final todos = _strictWatch('todos', () => watchValue(...));
175+
@override
176+
Widget build(BuildContext context) {
177+
return Container();
178+
}
179+
}
180+
// #endregion detect_watch_ordering_violations
181+
182+
void main() {}

0 commit comments

Comments
 (0)