home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C ++ / Applications / TimGA 1.2.1 / .cp / CGraphGADoc.cp < prev    next >
Encoding:
Text File  |  1997-07-16  |  11.8 KB  |  466 lines  |  [TEXT/CWIE]

  1. // ===========================================================================
  2. //    CGraphGADoc.cp        ©1995-97 Timo Eloranta        All rights reserved.
  3. // ===========================================================================
  4. //    The application class - subclassed from LDocument.
  5.  
  6. #include "CGraphGADoc.h"
  7. #include "CGraphGAApp.h"
  8. #include "CGraphPane.h"
  9. #include "CGraphWindow.h"
  10. #include "CMyFileStream.h"
  11. #include "CProbDialog.h"
  12. #include "CSelectionDialog.h"
  13. #include "CTerminationDialog.h"
  14. #include "CGeneralDialog.h"
  15. #include "CEvalDialog.h"
  16. #include "MyUtils.h"
  17. #include "LAnimateCursor.h"
  18.  
  19. #include <LApplication.h>
  20. #include <LWindow.h>
  21. #include <LFile.h>
  22. #include <UDesktop.h>
  23. #include <UMemoryMgr.h>
  24. #include <UWindows.h>
  25. #include <PP_Messages.h>
  26. #include <LString.h>
  27.  
  28. #include "GraphGA_PaneIDs.h"
  29.  
  30. #define APP            ((CGraphGAApp *) mSuperCommander)
  31. #define COMMANDER    ((LApplication*) mSuperCommander)
  32.  
  33. // ---------------------------------------------------------------------------
  34. //        • GridSizeOK
  35. //
  36. //          Called by:    CGraphGADoc::CGraphGADoc
  37. //                        CGraphGAApp::AskNewGraphSize
  38. // ---------------------------------------------------------------------------
  39.  
  40. Boolean
  41. GridSizeOK( Int16 inGridSize, Int16 inNodes )
  42. {
  43.     // We want our grid to have at least one empty square 
  44.     Int32    theMaxNodes = (inGridSize * inGridSize) - 1;
  45.     
  46.     if ( inNodes > theMaxNodes ) {
  47.         LStr255    theParam0( (Int32) inNodes );
  48.         LStr255 theParam1( (Int32) inGridSize );
  49.         LStr255 theParam2( theMaxNodes );
  50.         UDesktop::Deactivate();
  51.         ::ParamText( theParam0, theParam1, theParam2, "\p");
  52.         ::StopAlert( ALRT_TooManyNodes, nil );
  53.         UDesktop::Activate();
  54.     
  55.         return false;
  56.     } else
  57.         return true;
  58. }
  59.  
  60. // ---------------------------------------------------------------------------
  61. //        • CGraphGADoc( LCommander*, FSSpec*)
  62. // ---------------------------------------------------------------------------
  63. //    Construct a GraphGADoc associated with the specified file
  64. //
  65. //    If inFileSpec is nil, then create an empty, untitled document
  66.  
  67. CGraphGADoc::CGraphGADoc(
  68.     LCommander    *inSuper,
  69.     FSSpec        *inFileSpec)
  70.         : LDocument(inSuper)
  71. {
  72.     mMyFile        =    nil;
  73.     mWindow        =     APP -> GetGraphWindow();
  74.     mGraphPane     =     mWindow -> GetGraphPane();
  75.  
  76.     Int16    theGridSize = APP -> mGeneral.sizeGrid;
  77.     
  78.     // Initialize the population
  79.     mPopulation.SetSizes( theGridSize, APP -> mGeneral.sizePop );
  80.     
  81.     if (inFileSpec == nil) {
  82. //        mRandomGraph = true;
  83.         NameNewDoc();                // Set name of untitled window
  84.  
  85.         mGraphSize.nodes = APP -> mNewGraphNodes;
  86.         mGraphSize.edges = APP -> mNewGraphEdges;
  87.  
  88.         mPopulation.Initialize( true, &mGraphSize );
  89.         
  90.     } else {
  91.         
  92.         // Read in the graph file and check the size of it...
  93.         if ( OpenFile(*inFileSpec) && 
  94.              GridSizeOK( theGridSize, mGraphSize.nodes )) {
  95.  
  96.             //    mRandomGraph = false;
  97.                 mPopulation.Initialize( true, &mGraphSize, &mEdgeArray );
  98.         } else {
  99.             APP -> SetDocToBeShot( true );
  100.             return;
  101.         }
  102.     }
  103.  
  104.     // Selection    
  105.     mPopulation.SetSelection(        APP -> mSelection );
  106.     // Recombination
  107.     mPopulation.SetProbabilities(    APP -> mCrossoverProb,
  108.                                     APP -> mMutationProb );
  109.     // Termination    
  110.     mPopulation.SetTermination(        APP -> mTermination );
  111.  
  112.     // General stuff (speed)
  113.     mMaxSpendTime        =             APP -> mGeneral.spendTime;
  114.  
  115.     mWindow -> LCommander::SetSuperCommander( this );
  116.     PrepareToIterate( false );
  117. }
  118.  
  119. // ---------------------------------------------------------------------------
  120. //        • SetIterState    (PRIVATE)
  121. //
  122. //          Called by:    CGraphGADoc::PrepareToIterate
  123. //                        CGraphGADoc::ObeyCommand
  124. // ---------------------------------------------------------------------------
  125.  
  126. void
  127. CGraphGADoc::SetIterState( EIterState inIterState)
  128. {
  129.     mIterState = inIterState;
  130.     mWindow -> UpdateIterStateInfo( mIterState );
  131. }
  132.  
  133. // ---------------------------------------------------------------------------
  134. //        • PrepareToIterate        (PRIVATE)
  135. //
  136. //          Called by:    CGraphGADoc::CGraphGADoc
  137. //                        CGraphGADoc::ObeyCommand
  138. // ---------------------------------------------------------------------------
  139. //  Call this after the population (mPopulation) has been initialized.
  140.  
  141. void
  142. CGraphGADoc::PrepareToIterate( Boolean inDrawGraphNow )
  143. {
  144.     mGraphPane -> SetGraph( mPopulation.GetBestEver());
  145.     
  146.     SetIterState( iter_ReadyToGo );        // We are ready to go...
  147.     
  148.     mWindow -> UpdateGraphInfo( &mPopulation );
  149.     mWindow -> UpdatePopInfo( true, &mPopulation );
  150.     mWindow -> UpdateBestInfo( true, &mPopulation );
  151.     
  152.     ToggleMenuItem( cmd_IterStart, str_Start);
  153.     
  154.     if ( inDrawGraphNow )
  155.         mGraphPane -> InvalidateDrawing( true );
  156. }
  157.  
  158. // ---------------------------------------------------------------------------
  159. //        • ObeyCommand
  160. //
  161. //          Called by:    LCommander::ProcessCommand
  162. // ---------------------------------------------------------------------------
  163. //    Respond to commands
  164.  
  165. Boolean
  166. CGraphGADoc::ObeyCommand(
  167.     CommandT    inCommand,
  168.     void        *ioParam)
  169. {
  170.     Boolean            cmdHandled = true;
  171.     static    Int16    sMaxSpendTimeMemory = 20L;
  172.  
  173.     switch (inCommand) {
  174.     
  175.         case cmd_IterStart:
  176.             if ( mIterState == iter_ReadyToGo )
  177.                 ToggleMenuItem( cmd_IterStart, str_Continue );
  178.             SetIterState( iter_Running );
  179.             StartIdling();
  180.             break;
  181.  
  182.         case cmd_IterPause:
  183.             SetIterState( iter_Paused);
  184.             StopIdling();
  185.             break;
  186.  
  187.         case cmd_IterSuspend:
  188.             if ( mIterState == iter_Running ) {
  189.                 SetIterState( iter_Walking);
  190.                 COMMANDER -> SetSleepTime( kSleepTimeBG );
  191.                 sMaxSpendTimeMemory = mMaxSpendTime;
  192.                 mMaxSpendTime = kBG_MaxSpendTime;
  193.             }
  194.             break;
  195.  
  196.         case cmd_IterResume:
  197.             if ( mIterState == iter_Walking ) {
  198.                 SetIterState( iter_Running);
  199.                 COMMANDER -> SetSleepTime( kSleepTimeFG );
  200.                 mMaxSpendTime = sMaxSpendTimeMemory;
  201.             }
  202.             break;
  203.  
  204.         case cmd_IterReinitialize:
  205.             mPopulation.Initialize( false );
  206.             PrepareToIterate( true );
  207.             break;
  208. /*
  209.         case cmd_General:
  210.             CGeneralDialog *theGDialog = 
  211.                 (CGeneralDialog *) LWindow::CreateWindow( WIND_General, this);
  212.                 
  213.             theGDialog -> InitDialog();
  214.             theGDialog -> SetValues( APP -> mGeneral );
  215.             theGDialog -> Show();
  216.             break;
  217.  
  218.         case cmd_SetGeneral:
  219.             if (APP -> SetGeneralFromDialog( (SLGADialogResponse *) ioParam, 
  220.                                                 mGraphSize.nodes)) {
  221.                 mPopulation.SetSizes(
  222.                     APP -> GetGridSize(),
  223.                     APP -> mGeneral.sizePop );
  224.                 
  225.                 mPopulation.JunkGraphs();
  226.                 if ( mRandomGraph )
  227.                     mPopulation.Initialize( true, &mGraphSize );
  228.                 else    
  229.                     mPopulation.Initialize( true, &mGraphSize, &mEdgeArray );
  230.                     
  231.                 PrepareToIterate( true );
  232.             }
  233.             
  234.             mMaxSpendTime        = APP -> mGeneral.spendTime;
  235.             break;
  236. */
  237.  
  238.         case cmd_Selection:
  239.             CSelectionDialog *theSDialog = 
  240.                 (CSelectionDialog *) LWindow::CreateWindow( WIND_Select, this);
  241.                 
  242.             theSDialog -> InitDialog();
  243.             theSDialog -> SetValues(    APP -> mSelection,
  244.                                         APP -> mGeneral.sizePop );
  245.             theSDialog -> Show();
  246.             break;
  247.  
  248.         case cmd_SetSelection:
  249.             APP -> SetSelFromDialog( (SLGADialogResponse *) ioParam);
  250.                 
  251.             mPopulation.SetSelection(    APP -> mSelection );
  252.             break;
  253.  
  254.         default:
  255.             cmdHandled = LDocument::ObeyCommand(inCommand, ioParam);
  256.             break;
  257.     }
  258.     
  259.     return cmdHandled;
  260. }
  261.  
  262. // ---------------------------------------------------------------------------
  263. //        • FindCommandStatus
  264. //
  265. //          Called by:    LCommander::ProcessCommandStatus
  266. // ---------------------------------------------------------------------------
  267. //    Pass back whether a Command is enabled and/or marked (in a Menu)
  268.  
  269. void
  270. CGraphGADoc::FindCommandStatus(
  271.     CommandT    inCommand,
  272.     Boolean        &outEnabled,
  273.     Boolean        &outUsesMark,
  274.     Char16        &outMark,
  275.     Str255        outName)
  276. {
  277.     outUsesMark = false;
  278.  
  279.     switch (inCommand) {
  280.  
  281.         case cmd_Open:
  282.         case cmd_New:
  283.         case cmd_IterStart:
  284.             outEnabled = (     mIterState == iter_ReadyToGo ||
  285.                             mIterState == iter_Paused ||
  286.                             mIterState == iter_Finished );
  287.             break;
  288.  
  289.         case cmd_CloseGraph:
  290.             outEnabled = true;
  291.             break;
  292.  
  293.         case cmd_IterPause:
  294.             outEnabled = (     mIterState == iter_Running);
  295.             break;
  296.  
  297.         case cmd_IterReinitialize:
  298.             outEnabled = (  mIterState != iter_Running &&
  299.                             mIterState != iter_NoGraph );
  300.             break;
  301.  
  302.         case cmd_General:
  303. //            outEnabled = (    mIterState == iter_ReadyToGo );
  304.             outEnabled = false;
  305.             break;
  306.  
  307.         case cmd_Selection:
  308.         case cmd_Recombination:
  309.         case cmd_Termination:
  310.         case cmd_Evaluation:
  311.             outEnabled = (     mIterState != iter_Running );
  312.             break;
  313.  
  314.         default:
  315.             LDocument::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
  316.             break;
  317.     }
  318. }
  319.  
  320. // ---------------------------------------------------------------------------
  321. //        • SpendTime
  322. //
  323. //          Called by:    LPeriodical::DevoteTimeToIdlers
  324. // ---------------------------------------------------------------------------
  325.  
  326. void
  327. CGraphGADoc::SpendTime( 
  328.     const EventRecord & /*inMacEvent*/ )
  329. {
  330.     Boolean        theIterationHasEnded    = false,
  331.                 theBestHasChanged        = false;
  332.  
  333.     mPopulation.DoIterate(     theIterationHasEnded, 
  334.                             theBestHasChanged,
  335.                             mMaxSpendTime      );
  336.     
  337.     if ( theIterationHasEnded ) {
  338.         SetIterState( iter_Finished );
  339.         StopIdling();
  340.         LCommander::SetUpdateCommandStatus( true );        // Force menus to update
  341.         
  342.         PlayOneSnd( snd_Done, true );
  343.     }
  344.  
  345.     if ( theBestHasChanged )
  346.         mGraphPane -> InvalidateDrawing( true );
  347.     
  348.     mWindow -> UpdatePopInfo( false, &mPopulation );
  349.     
  350.     // Even if the best ever hasn't changed, we'll want to update
  351.     // the fields that tell about the generations/time without any
  352.     // change (= improvement, as best ever never gets worse...).
  353.     
  354.     mWindow -> UpdateBestInfo( theBestHasChanged, &mPopulation );
  355. }
  356.  
  357. // ---------------------------------------------------------------------------
  358. //        • NameNewDoc
  359. //
  360. //          Called by:    CGraphGADoc::CGraphGADoc
  361. // ---------------------------------------------------------------------------
  362. //    Name a new, untitled document window
  363.  
  364. void
  365. CGraphGADoc::NameNewDoc()
  366. {
  367.     LStr255    theName( STRx_Untitled, 1 );
  368.     
  369.     mWindow -> LWindow::SetDescriptor( theName );    // Set window title
  370. }
  371.  
  372.  
  373. // ---------------------------------------------------------------------------
  374. //        • OpenFile
  375. //
  376. //          Called by:    CGraphGADoc::CGraphGADoc
  377. // ---------------------------------------------------------------------------
  378. //    Open a new document for the specified File
  379.  
  380. Boolean
  381. CGraphGADoc::OpenFile(
  382.     FSSpec    &inFileSpec)
  383. {
  384.     Int16    theCount;
  385.     
  386.     mGraphSize.nodes = 0;
  387.     mGraphSize.edges = 0;
  388.  
  389.     // Use "spin cursor" since this can take a while...
  390.     LAnimateCursor    theSpinCursor( curs_First, curs_Qty );
  391.  
  392.     // Create a new CMyFileStream object, read the contents into
  393.     // appropriate variables, close the file, and set the Window
  394.     // title to the name of the file.
  395.         
  396.     Try_ {
  397.         mMyFile = new CMyFileStream( inFileSpec );
  398.         
  399.         if ( mMyFile )
  400.             mMyFile -> OpenDataFork( fsRdPerm );
  401.  
  402.         // Read the number of nodes and edges in the graph
  403.  
  404.         if ( mMyFile ) {
  405.             if (! mMyFile -> ReadInt( mGraphSize.nodes ) ) Throw_( ioErr );
  406.             if (! mMyFile -> ReadInt( mGraphSize.edges ) ) Throw_( ioErr );
  407.         }
  408.  
  409.         theSpinCursor.Set();
  410.         
  411.         mEdgeArray.reserve( mGraphSize.edges + 1 );
  412.  
  413.         // Read in the edges, which are stored as pairs of node numbers
  414.         
  415.         for ( theCount = 1; theCount <= mGraphSize.edges; ++theCount ) {
  416.             if (! mMyFile -> ReadInt( mEdgeArray[ theCount ].nodeNbr1 ) )
  417.                 Throw_( ioErr );
  418.             if (! mMyFile -> ReadInt( mEdgeArray[ theCount ].nodeNbr2 ) )
  419.                 Throw_( ioErr );
  420.                 
  421.             theSpinCursor.Set();
  422.         }
  423.  
  424.         if ( mMyFile )
  425.             mMyFile -> CloseDataFork();
  426.         
  427.         mWindow -> LWindow::SetDescriptor( inFileSpec.name );
  428.         mIsSpecified = false;
  429.  
  430.         if ( mMyFile ) {
  431.             delete mMyFile;        // We don't need it anymore!
  432.             mMyFile = nil;
  433.         }
  434.         
  435.         return true;            // All went fine
  436.     }
  437.     
  438.     Catch_(inErr) {
  439.         delete this;
  440.         Throw_(inErr);
  441.         return false;
  442.     
  443.     } EndCatch_
  444. }
  445.  
  446. // ---------------------------------------------------------------------------
  447. //        • GetDescriptor
  448. //
  449. //          Called by:    LDocument::<various>
  450. // ---------------------------------------------------------------------------
  451. //    Pass back the name of a Document
  452.  
  453. StringPtr
  454. CGraphGADoc::GetDescriptor(
  455.     Str255    outDescriptor) const
  456. {
  457.     if ( mWindow != nil ) {            // No File, use name of its Window
  458.         mWindow -> GetDescriptor( outDescriptor );
  459.     
  460.     } else {                        // No File and No Window
  461.         outDescriptor[0] = 0;        //   Document name is empty string
  462.     }
  463.     
  464.     return outDescriptor;
  465. }
  466.