Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OODebugController.m
Go to the documentation of this file.
1/*
2
3OODebugController.m
4
5
6Oolite Debug Bundle
7
8Copyright (C) 2007-2010 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 "OODebugController.h"
31#import "OODebugMonitor.h"
32#import "OOMacDebugger.h"
33
34#import "ResourceManager.h"
35
37#import "OOTexture.h"
38#import "OOLoggingExtended.h"
39#import "Universe.h"
40#import "OOOpenGL.h"
41#import "OOCacheManager.h"
42#import "PlayerEntity.h"
46#import "OODebugInspector.h"
48#import "OOConstToString.h"
49#import "OODebugFlags.h"
51#import "OOConstToString.h"
52
53
55
56
57@interface OODebugController ()
58
59- (void)insertDebugMenu;
61
62@end
63
64
65@implementation OODebugController
66
67- (id <OODebuggerInterface>) setUpDebugger
68{
69 return [[[OOMacDebugger alloc] initWithController:jsConsoleController] autorelease];
70}
71
72
73- (id)init
74{
75 NSString *nibPath = nil;
76
77 self = [super init];
78 if (self != nil)
79 {
80 _bundle = [[NSBundle bundleForClass:[self class]] retain];
81
82 nibPath = [self pathForResource:@"OODebugController" ofType:@"nib"];
83 if (nibPath == nil)
84 {
85 OOLog(@"debugSupport.load.failed", @"Could not find OODebugController.nib.");
86 [self release];
87 self = nil;
88 }
89 else
90 {
91 [NSBundle loadNibFile:nibPath externalNameTable:[NSDictionary dictionaryWithObject:self forKey:@"NSOwner"] withZone:NULL];
92
93 [self insertDebugMenu];
94 [self setUpLogMessageClassMenu];
95 OOLog(@"debugSupport.load.success", @"Debug Bundle loaded successfully.");
96 }
97 }
98
99 return self;
100}
101
102
103- (void)dealloc
104{
105 if (sSingleton == self) sSingleton = nil;
106
107 [menu release];
108 [logMessageClassPanel release];
109 [logPrefsWindow release];
110 [createShipPanel release];
111 [jsConsoleController release];
112
113 [_bundle release];
114
115 [super dealloc];
116}
117
118
120{
121 // NOTE: assumes single-threaded first access. See header.
122 if (sSingleton == nil) sSingleton = [[self alloc] init];
123 return sSingleton;
124}
125
126
127- (NSBundle *)bundle
128{
129 return _bundle;
130}
131
132
133- (NSString *)pathForResource:(NSString *)name ofType:(NSString *)type
134{
135 return [[self bundle] pathForResource:name ofType:type];
136}
137
138
139- (void)awakeFromNib
140{
141 [logPrefsWindow center];
142}
143
144
145#pragma mark -
146
147- (IBAction)showLogAction:sender
148{
149 [[NSWorkspace sharedWorkspace] openFile:OOLogHandlerGetLogPath()];
150}
151
152
153- (IBAction)graphicsResetAction:sender
154{
156}
157
158
159- (IBAction)clearTextureCacheAction:sender
160{
162}
163
164
165- (IBAction)resetAndClearAction:sender
166{
169}
170
171
172- (IBAction)dumpEntityListAction:sender
173{
174 BOOL wasEnabled;
175
176 wasEnabled = OOLogWillDisplayMessagesInClass(@"universe.objectDump");
177 OOLogSetDisplayMessagesInClass(@"universe.objectDump", YES);
178
179 [UNIVERSE debugDumpEntities];
180
181 OOLogSetDisplayMessagesInClass(@"universe.objectDump", wasEnabled);
182}
183
184
185- (IBAction)dumpPlayerStateAction:sender
186{
188}
189
190
191- (IBAction)createShipAction:sender
192{
193 NSString *role = nil;
194
195 role = [[NSUserDefaults standardUserDefaults] stringForKey:@"debug-create-ship-panel-last-role"];
196 if (role != nil)
197 {
198 [createShipPanelTextField setStringValue:role];
199 }
200
201 [NSApp runModalForWindow:createShipPanel];
202 [createShipPanel orderOut:self];
203}
204
205
206- (IBAction)clearAllCachesAction:sender
207{
209}
210
211
212- (IBAction)toggleWireframeModeAction:sender
213{
214 [UNIVERSE setWireframeGraphics:![UNIVERSE wireframeGraphics]];
215}
216
217
218- (IBAction) hideShowHUD:sender
219{
220 BOOL hidden = [[[PlayerEntity sharedPlayer] hud] isHidden];
221 NSString *command = [NSString stringWithFormat:@"player.ship.hudHidden = %@", hidden ? @"false" : @"true"];
223}
224
225
226- (IBAction) inspectPlayer:sender
227{
228 // [[PlayerEntity sharedPlayer] inspect];
229 [[OODebugMonitor sharedDebugMonitor] performJSConsoleCommand:@"player.ship.inspect()"];
230}
231
232
233- (IBAction) inspectTarget:sender
234{
235 // [[[PlayerEntity sharedPlayer] primaryTarget] inspect];
236 [[OODebugMonitor sharedDebugMonitor] performJSConsoleCommand:@"player.ship.target.inspect()"];
237}
238
239
240- (IBAction) cleanUpInspectors:sender
241{
243}
244
245
246static void SetDisplayLogMessagesInClassThroughJS(NSString *msgClass, BOOL display)
247{
248 NSString *command = [NSString stringWithFormat:@"console.setDisplayMessagesInClass(\"%@\", %@)", [msgClass escapedForJavaScriptLiteral], display ? @"true" : @"false"];
250}
251
252
253- (IBAction)toggleThisLogMessageClassAction:sender
254{
255 NSString *msgClass = nil;
256
257 if ([sender respondsToSelector:@selector(representedObject)])
258 {
259 msgClass = [sender representedObject];
261 }
262}
263
264
265- (IBAction)otherLogMessageClassAction:sender
266{
267 [NSApp runModalForWindow:logMessageClassPanel];
268 [logMessageClassPanel orderOut:self];
269}
270
271
272- (IBAction)logMsgClassPanelEnableAction:sender
273{
274 NSString *msgClass = nil;
275
276 msgClass = [logMsgClassPanelTextField stringValue];
277 if ([msgClass length] != 0) SetDisplayLogMessagesInClassThroughJS(msgClass, YES);
278
279 [NSApp stopModal];
280}
281
282
283- (IBAction)logMsgClassPanelDisableAction:sender
284{
285 NSString *msgClass = nil;
286
287 msgClass = [logMsgClassPanelTextField stringValue];
288 if ([msgClass length] != 0) SetDisplayLogMessagesInClassThroughJS(msgClass, NO);
289
290 [NSApp stopModal];
291}
292
293
294- (IBAction)toggleThisDebugFlagAction:sender
295{
296 NSUInteger tag, bits;
297 NSString *command = nil;
298
299 tag = [sender tag];
300 bits = gDebugFlags & tag;
301
302 if (bits != tag)
303 {
304 // Flags are off or mixed.
305 command = [NSString stringWithFormat:@"console.debugFlags |= 0x%lX", tag];
306 }
307 else
308 {
309 // Flags are all on.
310 command = [NSString stringWithFormat:@"console.debugFlags &= ~0x%.lX", tag];
311 }
312
314}
315
316
317- (IBAction) setShaderModeToTag:(NSMenuItem *)sender
318{
319 OOGraphicsDetail detail = (OOGraphicsDetail)sender.tag;
320 NSString *detailString = [OOStringFromGraphicsDetail(detail) escapedForJavaScriptLiteral];
321 NSString *command = [NSString stringWithFormat:@"console.detailLevel = \"%@\"", detailString];
322
324}
325
326
327- (IBAction)showLogPreferencesAction:sender
328{
329 [logShowFunctionCheckBox setState:OOLogShowFunction()];
330 [logShowFileAndLineCheckBox setState:OOLogShowFileAndLine()];
331 [logShowMessageClassCheckBox setState:OOLogShowMessageClass()];
332 [logShowTimeStampCheckBox setState:OOLogShowTime()];
333
334 [logPrefsWindow makeKeyAndOrderFront:self];
335}
336
337
338- (IBAction)logSetShowFunctionAction:sender
339{
340 OOLogSetShowFunction([sender state]);
341}
342
343
344- (IBAction)logSetShowFileAndLineAction:sender
345{
346 OOLogSetShowFileAndLine([sender state]);
347}
348
349
350- (IBAction)logSetShowMessageClassAction:sender
351{
352 OOLogSetShowMessageClass([sender state]);
353}
354
355
356- (IBAction) logSetShowTimeStampAction:sender
357{
358 OOLogSetShowTime([sender state]);
359}
360
361
362- (IBAction)insertLogSeparatorAction:sender
363{
364 [[OODebugMonitor sharedDebugMonitor] performJSConsoleCommand:@"console.writeLogMarker()"];
365}
366
367
368- (IBAction)createShipPanelOKAction:sender
369{
370 NSString *shipRole = nil;
371
372 shipRole = [createShipPanelTextField stringValue];
373 if ([shipRole length] != 0)
374 {
375 [self performSelector:@selector(spawnShip:) withObject:shipRole afterDelay:0.1];
376 [[NSUserDefaults standardUserDefaults] setObject:shipRole forKey:@"debug-create-ship-panel-last-role"];
377 }
378
379 [NSApp stopModal];
380}
381
382
383- (void)spawnShip:(NSString *)shipRole
384{
385 NSString *command = nil;
386
387 if (shipRole == nil) return;
388
389 if ([[OODebugMonitor sharedDebugMonitor] debuggerConnected])
390 {
391 command = [NSString stringWithFormat:@"this.T = system.addShips('%@', 1, player.ship.position, 10000); if (this.T) this.T = this.T[0]; else consoleMessage('command-error', 'Could not spawn \"%@\".');", [shipRole escapedForJavaScriptLiteral], [shipRole escapedForJavaScriptLiteral]];
393 }
394 else
395 {
396 [UNIVERSE addShipWithRole:shipRole nearRouteOneAt:1.0];
397 }
398}
399
400
401- (IBAction)modalPanelCancelAction:sender
402{
403 [NSApp stopModal];
404}
405
406
407#pragma mark -
408
409- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
410{
411 SEL action = NULL;
412 NSString *msgClass = nil;
413 NSUInteger tag, bits;
414 int state;
415
416 action = [menuItem action];
417
418 if (action == @selector(toggleThisLogMessageClassAction:))
419 {
420 msgClass = [menuItem representedObject];
421 [menuItem setState:OOLogWillDisplayMessagesInClass(msgClass)];
422 return YES;
423 }
424 if (action == @selector(toggleThisDebugFlagAction:))
425 {
426 tag = [menuItem tag];
427 bits = gDebugFlags & tag;
428 if (bits == 0) state = NSOffState;
429 else if (bits == tag) state = NSOnState;
430 else state = NSMixedState;
431
432 [menuItem setState:state];
433 return YES;
434 }
435 if (action == @selector(toggleWireframeModeAction:))
436 {
437 [menuItem setState:!![UNIVERSE wireframeGraphics]];
438 return YES;
439 }
440 if (action == @selector(inspectTarget:))
441 {
443 }
444 if (action == @selector(hideShowHUD:))
445 {
446 BOOL hidden = [[[PlayerEntity sharedPlayer] hud] isHidden];
447 [menuItem setTitle:hidden ? @"Show HUD" : @"Hide HUD"];
448 return YES;
449 }
450 if (action == @selector(setShaderModeToTag:))
451 {
452 OOGraphicsDetail itemLevel = (OOGraphicsDetail)menuItem.tag;
453
454 menuItem.state = (UNIVERSE.detailLevel == itemLevel);
456 }
457
458 return [self respondsToSelector:action];
459}
460
461
462- (void)insertDebugMenu
463{
464 NSMenuItem *item = nil;
465 NSInteger index;
466
467 [menu setTitle:@"Debug"];
468 item = [[NSMenuItem alloc] initWithTitle:@"Debug" action:NULL keyEquivalent:@""];
469 [item setSubmenu:menu];
470 [[NSApp mainMenu] addItem:item];
471 [item release];
472
473 if (![[NSUserDefaults standardUserDefaults] boolForKey:@"debug-show-extra-menu-items"])
474 {
475 // Old school and not elegant, but it removes the compiler warning
476 // on possible misuse of comma operator [-Wcomma],
477 // produced by the following statement
478 // while (index = [menu indexOfItemWithTag:-42], index != -1)
479 // Bracketing the operands with parenthesis, doesn't help either.
480 index = [menu indexOfItemWithTag:-42];
481 while (index != -1)
482 {
483 [menu removeItemAtIndex:index];
484 index = [menu indexOfItemWithTag:-42];
485 }
486 }
487}
488
489
491{
492 NSArray *definitions = nil;
493 NSUInteger i, count, inserted = 0;
494 NSString *title = nil, *key = nil;
495 NSMenuItem *item = nil;
496
497 definitions = [ResourceManager arrayFromFilesNamed:@"debugLogMessageClassesMenu.plist" inFolder:@"Config" andMerge:YES];
498 count = [definitions count] / 2;
499
500 for (i = 0; i != count; ++i)
501 {
502 title = [definitions oo_stringAtIndex:i * 2];
503 key = [definitions oo_stringAtIndex:i * 2 + 1];
504 if (title == nil || key == nil) continue;
505
506 item = [[NSMenuItem alloc] initWithTitle:title
507 action:@selector(toggleThisLogMessageClassAction:)
508 keyEquivalent:@""];
509 [item setTarget:self];
510 [item setRepresentedObject:key];
511
512 [logMessageClassSubMenu insertItem:item atIndex:inserted++];
513 [item release];
514 }
515}
516
517@end
518
519
520@implementation OODebugController (Singleton)
521
522/* Canonical singleton boilerplate.
523 See Cocoa Fundamentals Guide: Creating a Singleton Instance.
524 See also +sharedDebugController above.
525*/
526
527+ (id)allocWithZone:(NSZone *)inZone
528{
529 if (sSingleton == nil)
530 {
531 sSingleton = [super allocWithZone:inZone];
532 return sSingleton;
533 }
534 return nil;
535}
536
537
538- (id)copyWithZone:(NSZone *)inZone
539{
540 return self;
541}
542
543
544- (id)retain
545{
546 return self;
547}
548
549
550- (NSUInteger)retainCount
551{
552 return UINT_MAX;
553}
554
555
556- (void)release
557{}
558
559
560- (id)autorelease
561{
562 return self;
563}
564
565@end
NSUInteger gDebugFlags
Definition main.m:7
static OODebugController * sSingleton
static OODebugMonitor * sSingleton
BOOL OOLogWillDisplayMessagesInClass(NSString *inMessageClass)
Definition OOLogging.m:144
#define OOLog(class, format,...)
Definition OOLogging.h:88
void OOLogSetShowFileAndLine(BOOL flag)
Definition OOLogging.m:531
void OOLogSetShowTime(BOOL flag)
Definition OOLogging.m:549
void OOLogSetShowFunction(BOOL flag)
Definition OOLogging.m:513
void OOLogSetDisplayMessagesInClass(NSString *inClass, BOOL inFlag)
Definition OOLogging.m:182
void OOLogSetShowMessageClass(BOOL flag)
Definition OOLogging.m:567
unsigned count
return nil
OOGraphicsDetail
Definition OOTypes.h:243
#define UNIVERSE
Definition Universe.h:833
void dumpState()
Definition Entity.m:996
OOCacheManager * sharedCache()
id< OODebuggerInterface > setUpDebugger()
static void SetDisplayLogMessagesInClassThroughJS(NSString *msgClass, BOOL display)
OODebugController * sharedDebugController()
oneway void performJSConsoleCommand:(in NSString *command)
OODebugMonitor * sharedDebugMonitor()
OOGraphicsResetManager * sharedManager()
OOOpenGLExtensionManager * sharedManager()
void clearCache()
Definition OOTexture.m:357
HeadUpDisplay * hud
PlayerEntity * sharedPlayer()
NSArray * arrayFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)