home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-07-16 | 11.8 KB | 466 lines | [TEXT/CWIE] |
- // ===========================================================================
- // CGraphGADoc.cp ©1995-97 Timo Eloranta All rights reserved.
- // ===========================================================================
- // The application class - subclassed from LDocument.
-
- #include "CGraphGADoc.h"
- #include "CGraphGAApp.h"
- #include "CGraphPane.h"
- #include "CGraphWindow.h"
- #include "CMyFileStream.h"
- #include "CProbDialog.h"
- #include "CSelectionDialog.h"
- #include "CTerminationDialog.h"
- #include "CGeneralDialog.h"
- #include "CEvalDialog.h"
- #include "MyUtils.h"
- #include "LAnimateCursor.h"
-
- #include <LApplication.h>
- #include <LWindow.h>
- #include <LFile.h>
- #include <UDesktop.h>
- #include <UMemoryMgr.h>
- #include <UWindows.h>
- #include <PP_Messages.h>
- #include <LString.h>
-
- #include "GraphGA_PaneIDs.h"
-
- #define APP ((CGraphGAApp *) mSuperCommander)
- #define COMMANDER ((LApplication*) mSuperCommander)
-
- // ---------------------------------------------------------------------------
- // • GridSizeOK
- //
- // Called by: CGraphGADoc::CGraphGADoc
- // CGraphGAApp::AskNewGraphSize
- // ---------------------------------------------------------------------------
-
- Boolean
- GridSizeOK( Int16 inGridSize, Int16 inNodes )
- {
- // We want our grid to have at least one empty square
- Int32 theMaxNodes = (inGridSize * inGridSize) - 1;
-
- if ( inNodes > theMaxNodes ) {
- LStr255 theParam0( (Int32) inNodes );
- LStr255 theParam1( (Int32) inGridSize );
- LStr255 theParam2( theMaxNodes );
- UDesktop::Deactivate();
- ::ParamText( theParam0, theParam1, theParam2, "\p");
- ::StopAlert( ALRT_TooManyNodes, nil );
- UDesktop::Activate();
-
- return false;
- } else
- return true;
- }
-
- // ---------------------------------------------------------------------------
- // • CGraphGADoc( LCommander*, FSSpec*)
- // ---------------------------------------------------------------------------
- // Construct a GraphGADoc associated with the specified file
- //
- // If inFileSpec is nil, then create an empty, untitled document
-
- CGraphGADoc::CGraphGADoc(
- LCommander *inSuper,
- FSSpec *inFileSpec)
- : LDocument(inSuper)
- {
- mMyFile = nil;
- mWindow = APP -> GetGraphWindow();
- mGraphPane = mWindow -> GetGraphPane();
-
- Int16 theGridSize = APP -> mGeneral.sizeGrid;
-
- // Initialize the population
- mPopulation.SetSizes( theGridSize, APP -> mGeneral.sizePop );
-
- if (inFileSpec == nil) {
- // mRandomGraph = true;
- NameNewDoc(); // Set name of untitled window
-
- mGraphSize.nodes = APP -> mNewGraphNodes;
- mGraphSize.edges = APP -> mNewGraphEdges;
-
- mPopulation.Initialize( true, &mGraphSize );
-
- } else {
-
- // Read in the graph file and check the size of it...
- if ( OpenFile(*inFileSpec) &&
- GridSizeOK( theGridSize, mGraphSize.nodes )) {
-
- // mRandomGraph = false;
- mPopulation.Initialize( true, &mGraphSize, &mEdgeArray );
- } else {
- APP -> SetDocToBeShot( true );
- return;
- }
- }
-
- // Selection
- mPopulation.SetSelection( APP -> mSelection );
- // Recombination
- mPopulation.SetProbabilities( APP -> mCrossoverProb,
- APP -> mMutationProb );
- // Termination
- mPopulation.SetTermination( APP -> mTermination );
-
- // General stuff (speed)
- mMaxSpendTime = APP -> mGeneral.spendTime;
-
- mWindow -> LCommander::SetSuperCommander( this );
- PrepareToIterate( false );
- }
-
- // ---------------------------------------------------------------------------
- // • SetIterState (PRIVATE)
- //
- // Called by: CGraphGADoc::PrepareToIterate
- // CGraphGADoc::ObeyCommand
- // ---------------------------------------------------------------------------
-
- void
- CGraphGADoc::SetIterState( EIterState inIterState)
- {
- mIterState = inIterState;
- mWindow -> UpdateIterStateInfo( mIterState );
- }
-
- // ---------------------------------------------------------------------------
- // • PrepareToIterate (PRIVATE)
- //
- // Called by: CGraphGADoc::CGraphGADoc
- // CGraphGADoc::ObeyCommand
- // ---------------------------------------------------------------------------
- // Call this after the population (mPopulation) has been initialized.
-
- void
- CGraphGADoc::PrepareToIterate( Boolean inDrawGraphNow )
- {
- mGraphPane -> SetGraph( mPopulation.GetBestEver());
-
- SetIterState( iter_ReadyToGo ); // We are ready to go...
-
- mWindow -> UpdateGraphInfo( &mPopulation );
- mWindow -> UpdatePopInfo( true, &mPopulation );
- mWindow -> UpdateBestInfo( true, &mPopulation );
-
- ToggleMenuItem( cmd_IterStart, str_Start);
-
- if ( inDrawGraphNow )
- mGraphPane -> InvalidateDrawing( true );
- }
-
- // ---------------------------------------------------------------------------
- // • ObeyCommand
- //
- // Called by: LCommander::ProcessCommand
- // ---------------------------------------------------------------------------
- // Respond to commands
-
- Boolean
- CGraphGADoc::ObeyCommand(
- CommandT inCommand,
- void *ioParam)
- {
- Boolean cmdHandled = true;
- static Int16 sMaxSpendTimeMemory = 20L;
-
- switch (inCommand) {
-
- case cmd_IterStart:
- if ( mIterState == iter_ReadyToGo )
- ToggleMenuItem( cmd_IterStart, str_Continue );
- SetIterState( iter_Running );
- StartIdling();
- break;
-
- case cmd_IterPause:
- SetIterState( iter_Paused);
- StopIdling();
- break;
-
- case cmd_IterSuspend:
- if ( mIterState == iter_Running ) {
- SetIterState( iter_Walking);
- COMMANDER -> SetSleepTime( kSleepTimeBG );
- sMaxSpendTimeMemory = mMaxSpendTime;
- mMaxSpendTime = kBG_MaxSpendTime;
- }
- break;
-
- case cmd_IterResume:
- if ( mIterState == iter_Walking ) {
- SetIterState( iter_Running);
- COMMANDER -> SetSleepTime( kSleepTimeFG );
- mMaxSpendTime = sMaxSpendTimeMemory;
- }
- break;
-
- case cmd_IterReinitialize:
- mPopulation.Initialize( false );
- PrepareToIterate( true );
- break;
- /*
- case cmd_General:
- CGeneralDialog *theGDialog =
- (CGeneralDialog *) LWindow::CreateWindow( WIND_General, this);
-
- theGDialog -> InitDialog();
- theGDialog -> SetValues( APP -> mGeneral );
- theGDialog -> Show();
- break;
-
- case cmd_SetGeneral:
- if (APP -> SetGeneralFromDialog( (SLGADialogResponse *) ioParam,
- mGraphSize.nodes)) {
- mPopulation.SetSizes(
- APP -> GetGridSize(),
- APP -> mGeneral.sizePop );
-
- mPopulation.JunkGraphs();
- if ( mRandomGraph )
- mPopulation.Initialize( true, &mGraphSize );
- else
- mPopulation.Initialize( true, &mGraphSize, &mEdgeArray );
-
- PrepareToIterate( true );
- }
-
- mMaxSpendTime = APP -> mGeneral.spendTime;
- break;
- */
-
- case cmd_Selection:
- CSelectionDialog *theSDialog =
- (CSelectionDialog *) LWindow::CreateWindow( WIND_Select, this);
-
- theSDialog -> InitDialog();
- theSDialog -> SetValues( APP -> mSelection,
- APP -> mGeneral.sizePop );
- theSDialog -> Show();
- break;
-
- case cmd_SetSelection:
- APP -> SetSelFromDialog( (SLGADialogResponse *) ioParam);
-
- mPopulation.SetSelection( APP -> mSelection );
- break;
-
- default:
- cmdHandled = LDocument::ObeyCommand(inCommand, ioParam);
- break;
- }
-
- return cmdHandled;
- }
-
- // ---------------------------------------------------------------------------
- // • FindCommandStatus
- //
- // Called by: LCommander::ProcessCommandStatus
- // ---------------------------------------------------------------------------
- // Pass back whether a Command is enabled and/or marked (in a Menu)
-
- void
- CGraphGADoc::FindCommandStatus(
- CommandT inCommand,
- Boolean &outEnabled,
- Boolean &outUsesMark,
- Char16 &outMark,
- Str255 outName)
- {
- outUsesMark = false;
-
- switch (inCommand) {
-
- case cmd_Open:
- case cmd_New:
- case cmd_IterStart:
- outEnabled = ( mIterState == iter_ReadyToGo ||
- mIterState == iter_Paused ||
- mIterState == iter_Finished );
- break;
-
- case cmd_CloseGraph:
- outEnabled = true;
- break;
-
- case cmd_IterPause:
- outEnabled = ( mIterState == iter_Running);
- break;
-
- case cmd_IterReinitialize:
- outEnabled = ( mIterState != iter_Running &&
- mIterState != iter_NoGraph );
- break;
-
- case cmd_General:
- // outEnabled = ( mIterState == iter_ReadyToGo );
- outEnabled = false;
- break;
-
- case cmd_Selection:
- case cmd_Recombination:
- case cmd_Termination:
- case cmd_Evaluation:
- outEnabled = ( mIterState != iter_Running );
- break;
-
- default:
- LDocument::FindCommandStatus(inCommand, outEnabled, outUsesMark, outMark, outName);
- break;
- }
- }
-
- // ---------------------------------------------------------------------------
- // • SpendTime
- //
- // Called by: LPeriodical::DevoteTimeToIdlers
- // ---------------------------------------------------------------------------
-
- void
- CGraphGADoc::SpendTime(
- const EventRecord & /*inMacEvent*/ )
- {
- Boolean theIterationHasEnded = false,
- theBestHasChanged = false;
-
- mPopulation.DoIterate( theIterationHasEnded,
- theBestHasChanged,
- mMaxSpendTime );
-
- if ( theIterationHasEnded ) {
- SetIterState( iter_Finished );
- StopIdling();
- LCommander::SetUpdateCommandStatus( true ); // Force menus to update
-
- PlayOneSnd( snd_Done, true );
- }
-
- if ( theBestHasChanged )
- mGraphPane -> InvalidateDrawing( true );
-
- mWindow -> UpdatePopInfo( false, &mPopulation );
-
- // Even if the best ever hasn't changed, we'll want to update
- // the fields that tell about the generations/time without any
- // change (= improvement, as best ever never gets worse...).
-
- mWindow -> UpdateBestInfo( theBestHasChanged, &mPopulation );
- }
-
- // ---------------------------------------------------------------------------
- // • NameNewDoc
- //
- // Called by: CGraphGADoc::CGraphGADoc
- // ---------------------------------------------------------------------------
- // Name a new, untitled document window
-
- void
- CGraphGADoc::NameNewDoc()
- {
- LStr255 theName( STRx_Untitled, 1 );
-
- mWindow -> LWindow::SetDescriptor( theName ); // Set window title
- }
-
-
- // ---------------------------------------------------------------------------
- // • OpenFile
- //
- // Called by: CGraphGADoc::CGraphGADoc
- // ---------------------------------------------------------------------------
- // Open a new document for the specified File
-
- Boolean
- CGraphGADoc::OpenFile(
- FSSpec &inFileSpec)
- {
- Int16 theCount;
-
- mGraphSize.nodes = 0;
- mGraphSize.edges = 0;
-
- // Use "spin cursor" since this can take a while...
- LAnimateCursor theSpinCursor( curs_First, curs_Qty );
-
- // Create a new CMyFileStream object, read the contents into
- // appropriate variables, close the file, and set the Window
- // title to the name of the file.
-
- Try_ {
- mMyFile = new CMyFileStream( inFileSpec );
-
- if ( mMyFile )
- mMyFile -> OpenDataFork( fsRdPerm );
-
- // Read the number of nodes and edges in the graph
-
- if ( mMyFile ) {
- if (! mMyFile -> ReadInt( mGraphSize.nodes ) ) Throw_( ioErr );
- if (! mMyFile -> ReadInt( mGraphSize.edges ) ) Throw_( ioErr );
- }
-
- theSpinCursor.Set();
-
- mEdgeArray.reserve( mGraphSize.edges + 1 );
-
- // Read in the edges, which are stored as pairs of node numbers
-
- for ( theCount = 1; theCount <= mGraphSize.edges; ++theCount ) {
- if (! mMyFile -> ReadInt( mEdgeArray[ theCount ].nodeNbr1 ) )
- Throw_( ioErr );
- if (! mMyFile -> ReadInt( mEdgeArray[ theCount ].nodeNbr2 ) )
- Throw_( ioErr );
-
- theSpinCursor.Set();
- }
-
- if ( mMyFile )
- mMyFile -> CloseDataFork();
-
- mWindow -> LWindow::SetDescriptor( inFileSpec.name );
- mIsSpecified = false;
-
- if ( mMyFile ) {
- delete mMyFile; // We don't need it anymore!
- mMyFile = nil;
- }
-
- return true; // All went fine
- }
-
- Catch_(inErr) {
- delete this;
- Throw_(inErr);
- return false;
-
- } EndCatch_
- }
-
- // ---------------------------------------------------------------------------
- // • GetDescriptor
- //
- // Called by: LDocument::<various>
- // ---------------------------------------------------------------------------
- // Pass back the name of a Document
-
- StringPtr
- CGraphGADoc::GetDescriptor(
- Str255 outDescriptor) const
- {
- if ( mWindow != nil ) { // No File, use name of its Window
- mWindow -> GetDescriptor( outDescriptor );
-
- } else { // No File and No Window
- outDescriptor[0] = 0; // Document name is empty string
- }
-
- return outDescriptor;
- }
-