Oolite 1.91.0.7644-241112-7f5034b
Loading...
Searching...
No Matches
OODebugInspector.m
Go to the documentation of this file.
1/*
2
3OODebugInspector.m
4
5
6Oolite Debug Bundle
7
8Copyright © 2007-2013 Jens Ayton
9
10Permission is hereby granted, free of charge, to any person obtaining a copy
11of this software and associated documentation files (the “Software”), to deal
12in the Software without restriction, including without limitation the rights
13to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14copies of the Software, and to permit persons to whom the Software is
15furnished to do so, subject to the following conditions:
16
17The above copyright notice and this permission notice shall be included in all
18copies or substantial portions of the Software.
19
20THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26SOFTWARE.
27
28*/
29
30#import "OODebugInspector.h"
33
34
35static NSMutableDictionary *sActiveInspectors = nil;
36
37
38@interface OODebugInspector ()
39
40- (id) initWithObject:(id <OOWeakReferenceSupport>)object;
41
42- (void) placeModules;
43
44- (void) update;
45
46@end
47
48
49@implementation OODebugInspector
50
51+ (id) inspectorForObject:(id <OOWeakReferenceSupport>)object
52{
53 OODebugInspector *inspector = nil;
54 NSValue *key = nil;
55
56 if (object == nil) return nil;
57
58 // Look for existing inspector
59 key = [NSValue valueWithNonretainedObject:object];
60 inspector = [sActiveInspectors objectForKey:key];
61 if (inspector != nil)
62 {
63 if ([inspector object] == object) return inspector;
64 else
65 {
66 // Existing inspector is for an old object that used to be at the same address.
67 [sActiveInspectors removeObjectForKey:key];
68 }
69 }
70
71 // No existing inspector; create one.
72 inspector = [[[self alloc] initWithObject:object] autorelease];
73
74 return inspector;
75}
76
77
78- (void) dealloc
79{
80 [_timer invalidate];
81 _timer = nil;
82 _panel = nil;
83 [_object release];
84 _object = nil;
85 if (_key != nil) [sActiveInspectors removeObjectForKey:_key];
86 [_key release];
87 _key = nil;
88 [_modules release];
89 [_panel close];
90
91 [super dealloc];
92}
93
94
95- (id <OOWeakReferenceSupport>) object
96{
97 if (_object != nil)
98 {
99 id result = [_object weakRefUnderlyingObject];
100 if (result == nil)
101 {
102 [_object release];
103 _object = nil;
104 }
105 return result;
106 }
107 else
108 {
109 return nil;
110 }
111}
112
113
114- (void) bringToFront
115{
116 if (![_panel isVisible]) [self update];
117 [_panel orderFront:nil];
118}
119
120
121+ (void) cleanUpInspectors
122{
123 [[sActiveInspectors allValues] makeObjectsPerformSelector:@selector(cleanSelfUp)];
124}
125
126
127- (id) initWithObject:(id <OOWeakReferenceSupport>)object
128{
129 if ((self = [super init]))
130 {
131 _key = [[NSValue valueWithNonretainedObject:object] retain];
132 _object = [object weakRetain];
133
134 [NSBundle loadNibNamed:@"OODebugInspector" owner:self];
135 [self update];
136 _timer = [NSTimer scheduledTimerWithTimeInterval:0.1
137 target:self
138 selector:@selector(updateTick:)
139 userInfo:nil
140 repeats:YES];
141
142 _modules = [[(id)object debugInspectorModules] retain];
143 [self placeModules];
144
145 if (sActiveInspectors == nil) sActiveInspectors = [[NSMutableDictionary alloc] init];
146 [sActiveInspectors setObject:self forKey:_key];
147 }
148
149 return self;
150}
151
152
153- (void) placeModules
154{
155 // Lay out modules vertically in panel.
156 CGFloat totalHeight = 4; // Margin at bottom
157 NSRect frame;
158 NSView *contentView = nil, *moduleView = nil;
159 NSSize size;
160
161 // Sum heights of modules.
162 for (OODebugInspectorModule *module in _modules)
163 {
164 totalHeight += [[module rootView] frame].size.height;
165 }
166
167 // Resize panel appropriately.
168 frame = [_panel contentRectForFrameRect:[_panel frame]];
169 frame.size.height = totalHeight + 4; // Margin at top
170 [_panel setFrame:[_panel frameRectForContentRect:frame] display:NO];
171
172 size = [_panel contentMinSize];
173 size.height = frame.size.height;
174 [_panel setContentMinSize:size];
175
176 size = [_panel contentMaxSize];
177 size.height = frame.size.height;
178 [_panel setContentMaxSize:size];
179
180 // Position each module.
181 contentView = [_panel contentView];
182 for (OODebugInspectorModule *module in _modules)
183 {
184 moduleView = [module rootView];
185 frame = [moduleView frame];
186 totalHeight -= frame.size.height;
187 frame.origin.y = totalHeight;
188 [moduleView setFrame:frame];
189 [contentView addSubview:moduleView];
190 }
191
192 [self update];
193}
194
195
196- (void) update
197{
198 [_modules makeObjectsPerformSelector:@selector(update)];
199}
200
201
202- (void) updateTick:(NSTimer *)timer
203{
204 if ([_panel isVisible]) [self update];
205}
206
207
208- (void)windowWillClose:(NSNotification *)notification
209{
210 _panel = nil;
211 NSValue *key = _key;
212 _key = nil;
213 if (key != nil) [sActiveInspectors removeObjectForKey:key];
214 [key release];
215}
216
217
218- (void) cleanSelfUp
219{
220 if ([self object] == nil) [_panel close];
221}
222
223@end
static NSMutableDictionary * sActiveInspectors
return nil
OOWeakReference * _object
id< OOWeakReferenceSupport > object()
IBOutlet NSPanel * _panel
voidpf void uLong size
Definition ioapi.h:134