Controller Example

 


Here is an example ORCA controller object with commentary. It is a part of the CAMAC 811 ADC object. Note that not all of the object code is included here.


/*

*  ORAD811ModelController.cpp

*  Orca

*

*  Created by Mark Howe on Jun 15 2005.

*  Copyright (c) 2002 CENPA, University of Washington. for the Regents of the

*

*/



#pragma mark •••Imported Files

#import "ORAD811Controller.h"

#import "StatusLog.h"

#import "ORDefaults.h"

#import "ORGlobal.h"

#import "ORCamacExceptions.h"

#import "ORCamacExceptions.h"


@implementation ORAD811Controller


#pragma mark •••Initialization

-(id)init

{

    self = [super initWithWindowNibName:@"AD811"]; //AD811 is the name of the .nib file this controller

    return self;                                   //will load.

}


#pragma mark •••Notifications


//Models post notifications when variables change. Here is where we register for the various

//Notifications that this controller will handle.


- (void) registerNotificationObservers

{

    NSNotificationCenter* notifyCenter = [NSNotificationCenter defaultCenter];

   

    [super registerNotificationObservers];

   

    [notifyCenter addObserver : self

                     selector : @selector(slotChanged:)

                         name : ORCamacCardSlotChangedNotification

                       object : model];


   [notifyCenter addObserver : self

        selector : @selector(settingsLockChanged:)

            name : ORRunStatusChangedNotification

          object : nil];


   [notifyCenter addObserver : self

          selector : @selector(settingsLockChanged:)

              name : ORAD811SettingsLock

             object: nil];


   [notifyCenter addObserver : self

selector : @selector(onlineMaskChanged:)

     name : ORAD811OnlineMaskChangedNotification

   object : model];


...

...

...


}


#pragma mark •••Interface Management


//UpdateWindow is called after the .nib file is loaded and is one of the oppertunities for us to

//load our dialog elements for the first time. After this, generally the dialog elements will only

//be updated when a particular notification is delivered about a variable change.

- (void) updateWindow

{

    [super updateWindow];

    [self slotChanged:nil];

    [self onlineMaskChanged:nil];

    [self settingsLockChanged:nil];

}



//Many of the dialogs have sercutiy locks. This method is called set the initial state of the system

//system.

- (void) checkGlobalSecurity

{

    BOOL secure = [[[NSUserDefaults standardUserDefaults] objectForKey:OROrcaSecurityEnabled] boolValue];

    [gSecurity setLock:ORAD811SettingsLock to:secure];

    [settingLockButton setEnabled:secure];

}



//When the lock is clicked, here is the place to enable/disable various controls based on the lock state

//and/or the run state.

- (void) settingsLockChanged:(NSNotification*)aNotification

{


    BOOL runInProgress = [gOrcaGlobals runInProgress];

    BOOL lockedOrRunningMaintenance = [gSecurity runInProgressButNotType:eMaintenanceRunType orIsLocked:ORAD811SettingsLock];

    BOOL locked = [gSecurity isLocked:ORAD811SettingsLock];


    [settingLockButton setState: locked];

    [onlineMaskMatrix setEnabled:!lockedOrRunningMaintenance];


...

...

...


    NSString* s = @"";

    if(lockedOrRunningMaintenance){

        if(runInProgress && ![gSecurity isLocked:ORAD811SettingsLock])s = @"Not in Maintenance Run.";

    }

    [settingLockDocField setStringValue:s];


}



//Example of how to handle a notification. This particular notification has told us that this object's

//crate slot has changed. In response the title of the window is changed.

- (void) slotChanged:(NSNotification*)aNotification

{

[[self window] setTitle:[NSString stringWithFormat:@"AD811 (Station %d)",[model stationNumber]]];

}


- (void) onlineMaskChanged:(NSNotification*)aNotification

{

short i;

unsigned char theMask = [model onlineMask];

for(i=0;i<8;i++){

BOOL bitSet = (theMask&(1<<i))>0;

if(bitSet != [[onlineMaskMatrix cellWithTag:i] intValue]){

[[onlineMaskMatrix cellWithTag:i] setState:bitSet];

}

}

}


#pragma mark •••Actions

//Button actions are linked to this action methods via Interface Builder. Here are a couple of

//examples handling button actions

- (IBAction) settingLockAction:(id) sender

{

    [gSecurity tryToSetLock:ORAD811SettingsLock to:[sender intValue] forWindow:[self window]];

}


- (IBAction) onlineAction:(id)sender

{

if([sender intValue] != [model onlineMaskBit:[[sender selectedCell] tag]]){

[[self undoManager] setActionName: @"Set Online Mask"];

[model setOnlineMaskBit:[[sender selectedCell] tag] withValue:[sender intValue]];

}

}


- (IBAction) readNoResetAction:(id)sender

{

    NS_DURING

        [model checkCratePower];

        [model readNoReset];

    NS_HANDLER

        [self showError:localException name:@"Read/No Reset" fCode:0];

    NS_ENDHANDLER

}

...

...

...


//Here is the central place where this controller handles exception.

- (void) showError:(NSException*)anException name:(NSString*)name fCode:(int)i

{

    NSLog(@"Failed Cmd: %@ (F%d)\n",name,i);

    if([[anException name] isEqualToString: OExceptionNoCamacCratePower]) {

        [[model crate]  doNoPowerAlert:anException action:[NSString stringWithFormat:@"%@ (F%d)",name,i]];

    }

    else {

        NSRunAlertPanel([anException name], @"%@\n%@ (F%d)", @"OK", nil, nil,

                        [anException name],name,i);

    }

}

@end