EclipseFinderController.mm
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:10k
源码类别:

OpenGL

开发平台:

Visual C++

  1. //
  2. //  EclipseFinderController.mm
  3. //  celestia
  4. //
  5. //  Created by Da Woon Jung on 2007-05-07.
  6. //  Copyright 2007 Da Woon Jung. All rights reserved.
  7. //
  8. #import "EclipseFinderController.h"
  9. #import "CelestiaAppCore.h"
  10. #import "NSString_ObjCPlusPlus.h"
  11. #import "CelestiaBody_PrivateAPI.h"
  12. #import "eclipsefinder.h"
  13. @interface EclipseFinderController(Private)
  14. - (void)getEclipses: (id)aObject;
  15. - (void)getEclipsesDone: (id)aObject;
  16. @end
  17. @implementation EclipseFinderController
  18. static NSMutableArray *eclipses;
  19. static NSCalendarDate *startDate;
  20. static NSCalendarDate *midDate;
  21. static NSCalendarDate *endDate;
  22. static string receiverName;
  23. static Eclipse::Type eclipseType;
  24. static CelestiaBody *eclipseBody;
  25. - (id)init
  26. {
  27.     self = [super initWithWindowNibName: @"EclipseFinder"];
  28.     if (self)
  29.     {
  30.         eclipses = [[NSMutableArray alloc] init];
  31.     }
  32.     return self;
  33. }
  34. - (void)windowDidLoad
  35. {
  36.     [eclipseList setDoubleAction: @selector(go:)];
  37. }
  38. - (void)windowWillClose:(NSNotification *)aNotification
  39. {
  40.     if ([self window] == [aNotification object])
  41.     {
  42.         keepGoing = NO;
  43.     }
  44. }
  45. - (void)dealloc
  46. {
  47.     [eclipses release];
  48.     [super dealloc];
  49. }
  50. - (void)controlTextDidEndEditing:(NSNotification *)aNotification
  51. {
  52.     NSDictionary *userInfo = [aNotification userInfo];
  53.     if (userInfo && NSReturnTextMovement == [[userInfo objectForKey: @"NSTextMovement"] intValue])
  54.     {
  55.         [self find: self];
  56.     }
  57. }
  58. - (IBAction)find: (id)sender
  59. {
  60.     CelestiaSimulation *sim;
  61.     CelestiaSelection *sel;
  62.     Body *body;
  63.     id startDateObj       = [eclipseFindStart objectValue];
  64.     id endDateObj         = [eclipseFindEnd   objectValue];
  65.     NSString *receiverStr = [eclipseReceiver  stringValue];
  66.     keepGoing = YES;
  67.     if (0 == [receiverStr length])
  68.     {
  69.         NSRunAlertPanel(NSLocalizedString(@"No Object Name Entered",@""),
  70.                         NSLocalizedString(@"Please enter an object name.",@""),
  71.                         nil,nil,nil);
  72.         return;
  73.     }
  74.     if (nil == startDateObj || nil == endDateObj)
  75.     {
  76.         NSRunAlertPanel(NSLocalizedString(@"No Starting or Ending Date Entered",@""),
  77.                         NSLocalizedString(@"Please enter starting and ending dates.",@""),
  78.                         nil,nil,nil);
  79.         return;
  80.     }
  81.     sim = [[CelestiaAppCore sharedAppCore] simulation];
  82.     sel = [sim findObjectFromPath: receiverStr];
  83.     if (nil == sel || [sel isEmpty])
  84.     {
  85.         NSRunAlertPanel(NSLocalizedString(@"Object Not Found",@""),
  86.                         NSLocalizedString(@"Please check that the object name is correct.",@""),
  87.                         nil,nil,nil);
  88.         return;
  89.     }
  90.     eclipseBody = [[sel body] retain];
  91.     body = [eclipseBody body];
  92.     if (nil == body || nil == body->getSystem())
  93.     {
  94.         NSRunAlertPanel(NSLocalizedString(@"Object Not Found",@""),
  95.                         NSLocalizedString(@"Please check that the object name is correct.",@""),
  96.                         nil,nil,nil);
  97.         return;
  98.     }
  99.     if (body->getSystem()->getPrimaryBody())
  100.     {
  101.         // Eclipse receiver is a moon -> find lunar eclipses
  102.         eclipseType = Eclipse::Moon;
  103.         PlanetarySystem *system = body->getSystem();
  104.         if (system)
  105.         {
  106.             Body *parent = system->getPrimaryBody();
  107.             if (NULL == parent)
  108.             {
  109.                 [eclipseBody release];
  110.                 return;
  111.             }
  112.             receiverName = parent->getName();
  113.         }
  114.     }
  115.     else
  116.     {
  117.         eclipseType = Eclipse::Solar;
  118.         receiverName = body->getName();
  119.         // EclipseFinder class expects unlocalized names
  120.     }
  121.     
  122.     startDate = (NSCalendarDate *)[startDateObj retain];
  123.     endDate = (NSCalendarDate *)[endDateObj retain];
  124.     midDate = [[startDate dateByAddingYears: 0
  125.                                      months: 0
  126.                                        days: 15
  127.                                       hours: 0
  128.                                     minutes: 0
  129.                                     seconds: 0] retain];
  130.     // Find eclipses in small timeslices, to give the user
  131.     // a chance to abort with the stop button
  132.     [findButton setEnabled: NO];
  133.     [eclipses release];
  134.     eclipses = [[NSMutableArray alloc] init];
  135.     [eclipseProgress startAnimation: self];
  136.     [NSThread detachNewThreadSelector: @selector(getEclipses:)
  137.                              toTarget: self withObject: nil];
  138. }
  139. /* Go code borrowed from Windows version */
  140. - (IBAction)go: (id)sender
  141. {
  142.     int rowIndex = [eclipseList selectedRow];
  143.     if (rowIndex < 0) return;
  144.     CelestiaCore *appCore = (CelestiaCore*) [[CelestiaAppCore sharedAppCore] appCore];
  145.     NSDictionary *eclipse = [eclipses objectAtIndex: rowIndex];
  146.     Body *body = [(CelestiaBody *)[eclipse objectForKey: @"body"] body];
  147.     double startTime = [[eclipse objectForKey: @"start"] doubleValue];
  148.     Simulation *sim = appCore->getSimulation();
  149.     sim->setTime(startTime);
  150.     Selection target(body);
  151.     Selection ref(body->getSystem()->getStar());
  152.     sim->setFrame(ObserverFrame::PhaseLock, target, ref);
  153.     sim->update(0.0);
  154.     double distance = astro::kilometersToMicroLightYears(target.radius() * 4.0);
  155.     sim->setSelection(target);
  156.     sim->gotoLocation(Point3d(distance, 0, 0),
  157.                       Quatd::yrotation(-0.5*PI)*Quatd::xrotation(-0.5*PI),
  158.                       5.0);
  159. }
  160. - (IBAction)stopFind: (id)sender
  161. {
  162.     keepGoing = NO;
  163. }
  164. - (void)getEclipses: (id)aObject
  165. {
  166.     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
  167.     CelestiaCore *appCore = (CelestiaCore*) [[CelestiaAppCore sharedAppCore] appCore];
  168.     EclipseFinder *eclipseFinder;
  169.     const Eclipse *eclipse;
  170.     double jd;
  171.     double hours, minutes;
  172.     NSString *eclipseName;
  173.     NSString *duration;
  174.     NSCalendarDate *eclipseDate;
  175.     vector<Eclipse>::const_iterator iter;
  176.     while (keepGoing)
  177.     {
  178.         if (NSOrderedDescending == [midDate compare: endDate])
  179.         {
  180.             if (NSOrderedAscending == [startDate compare: endDate])
  181.             {
  182.                 [midDate release];
  183.                 midDate = [endDate retain];
  184.             }
  185.             else
  186.             {
  187.                 break;
  188.             }
  189.         }
  190.         eclipseFinder =
  191.             new EclipseFinder(appCore,
  192.                               receiverName,
  193.                               eclipseType,
  194.                               (double)astro::Date(astro::secondsToJulianDate([startDate timeIntervalSince1970])) + (double)astro::Date(1970,1,1),
  195.                               (double)astro::Date(astro::secondsToJulianDate([midDate timeIntervalSince1970])) + (double)astro::Date(1970,1,1)
  196.                               );
  197.         const vector<Eclipse> &freshEclipses = eclipseFinder->getEclipses();
  198.         for (iter  = freshEclipses.begin();
  199.              iter != freshEclipses.end() && keepGoing;
  200.              ++iter)
  201.         {
  202.             eclipse = &(*iter);
  203.             jd = astro::julianDateToSeconds((double)(*eclipse->date));
  204.             if (0 == jd && eclipse->planete == "None")
  205.                 continue;
  206.             if (eclipse->body != [(CelestiaBody *)eclipseBody body])
  207.                 continue;
  208.             eclipseName = [NSString stringWithStdString: (eclipseType == Eclipse::Moon ? eclipse->planete : eclipse->sattelite)];
  209.             eclipseDate = [NSCalendarDate dateWithTimeIntervalSince1970: (jd - astro::julianDateToSeconds((double)astro::Date(1970,1,1)))];
  210.             hours = astro::julianDateToSeconds(eclipse->endTime - eclipse->startTime)/3600.0;
  211.             minutes = 60.0*(hours - (int)hours);
  212.             duration = [NSString stringWithFormat: @"%02d:%02d", (int)hours, (int)minutes];
  213.             [eclipses addObject:
  214.                 [NSDictionary dictionaryWithObjectsAndKeys:
  215.                     NSLocalizedStringFromTable(eclipseName,@"po",@""), @"caster",
  216.                     eclipseDate, @"date",
  217.                     [[[CelestiaBody alloc] initWithBody: eclipse->body] autorelease], @"body",
  218.                     [NSNumber numberWithDouble: eclipse->startTime], @"start",
  219.                     duration, @"duration",                
  220.                     nil]
  221.             ];
  222.         }
  223.         delete eclipseFinder;
  224.         [startDate release];
  225.         startDate = [midDate retain];
  226.         [midDate release];
  227.         midDate = [[startDate dateByAddingYears: 0
  228.                                          months: 0
  229.                                            days: 15
  230.                                           hours: 0
  231.                                         minutes: 0
  232.                                         seconds: 0] retain];
  233.     }
  234.     [self performSelectorOnMainThread: @selector(getEclipsesDone:)
  235.                            withObject: nil
  236.                         waitUntilDone: NO];
  237.     [pool release];
  238. }
  239. - (void)getEclipsesDone: (id)aObject
  240. {
  241.     [startDate release];   startDate = nil;
  242.     [midDate release];     midDate = nil;
  243.     [endDate release];     endDate = nil;
  244.     [eclipseBody release]; eclipseBody = nil;
  245.     [eclipseProgress stopAnimation: self];
  246.     [findButton setEnabled: YES];
  247.     [eclipseList reloadData];    
  248. }
  249. - (int)numberOfRowsInTableView: (NSTableView *)aTableView
  250. {
  251.     return [eclipses count];
  252. }
  253. - (id)tableView: (NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(int)rowIndex
  254. {
  255.     id result = nil;
  256.     NSDictionary *eclipse = nil;
  257.     if ([eclipses count] > 0)
  258.     {
  259.         eclipse = [eclipses objectAtIndex: rowIndex];
  260.         if ([[aTableColumn identifier] isEqualToString: @"begin"])
  261.         {
  262.             result = [NSCalendarDate dateWithTimeIntervalSince1970: astro::julianDateToSeconds([[eclipse objectForKey: @"start"] doubleValue] - (double)astro::Date(1970,1,1))];
  263.         }
  264.         else
  265.         {
  266.             result = [eclipse objectForKey: [aTableColumn identifier]];
  267.         }
  268.     }
  269.     return result;
  270. }
  271. @end