This is EmpireImageVendor.m in view mode; [Download] [Up]
// // $Id: EmpireImageVendor.m,v 1.11 1997/10/31 04:51:48 nygard Exp $ // // // This file is a part of Empire, a game of exploration and conquest. // Copyright (C) 1996 Steve Nygard // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // // You may contact the author by: // e-mail: nygard@telusplanet.net // #import "Empire.h" RCSID ("$Id: EmpireImageVendor.m,v 1.11 1997/10/31 04:51:48 nygard Exp $"); #import "EmpireImageVendor.h" #import "Token.h" static EmpireImageVendor *_instance = nil; // Common images static NSImage *default_cursor; static NSImage *direction_cursor; static NSImage *explosion; struct image_names { NSString *i_name; NSImage **i_image; }; static struct image_names class_images[] = { { @"cursor.tiff", &default_cursor }, { @"direction_cursor.tiff", &direction_cursor }, { @"explosion.tiff", &explosion }, }; //====================================================================== // This provides access to many of the images required by Empire, // especially since most of them are dynamically generated. It also // provides notification to observers when any of the player colors // change, so that views that use these images can be updated with the // new colors. //====================================================================== #define EmpireImageVendor_VERSION 1 @implementation EmpireImageVendor + (void) initialize { if (self == [EmpireImageVendor class]) { [self setVersion:EmpireImageVendor_VERSION]; // It appears that there is no guarantee that we can get the bundle // in this method, so we have to work around this. if ([NSBundle bundleForClass:self] == nil) { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector (loadClassImages) name:NSApplicationDidFinishLaunchingNotification object:NSApp]; } else { [self loadClassImages]; } } } //---------------------------------------------------------------------- + (void) loadClassImages { int l; NSBundle *thisBundle; NSString *imagePath; if (self == [EmpireImageVendor class]) { thisBundle = [NSBundle bundleForClass:self]; NSAssert (thisBundle != nil, @"Could not get bundle."); // load class images for (l = 0; l < sizeof (class_images) / sizeof (struct image_names); l++) { imagePath = [thisBundle pathForImageResource:class_images[l].i_name]; NSAssert1 (imagePath != nil, @"Could not find image: '%@'", class_images[l].i_name); *(class_images[l].i_image) = [[NSImage alloc] initByReferencingFile:imagePath]; NSAssert1 (*(class_images[l].i_image) != nil, @"Couldn't load image: '%@'\n", class_images[l].i_name); } } [[NSNotificationCenter defaultCenter] removeObserver:self]; } //---------------------------------------------------------------------- + instance { // Might want to grab colors from defaults. if (_instance == nil) { NSColor *player1 = [NSColor colorWithCalibratedRed:34 / 255.0 green:255 / 255.0 blue:248 / 255.0 alpha:1.0]; NSColor *player2 = [NSColor colorWithCalibratedRed:255 / 255.0 green:26 / 255.0 blue:6 / 255.0 alpha:1.0]; NSColor *player3 = [NSColor colorWithCalibratedRed:243 / 255.0 green:255 / 255.0 blue:0 / 255.0 alpha:1.0]; _instance = [[EmpireImageVendor alloc] initWithColors:player1:player2:player3]; } return _instance; } //---------------------------------------------------------------------- - initWithColors:(NSColor *)color1:(NSColor *)color2:(NSColor *)color3 { Icon loop_to_land[] = {i_army, i_sentry, i_fighter, i_hovercraft}; Icon loop_to_water[] = {i_fighter, i_unloaded_transport, i_loaded_transport, i_submarine, i_destroyer, i_cruiser, i_unloaded_carrier, i_loaded_carrier, i_battleship, i_hovercraft}; Player p; int l; [super init]; for (p = p_neutral; p <= p_player3; p++) { cityTokens[p] = [[Token alloc] initIcon:i_none onTerrain:t_city forPlayer:p]; cityImages[p] = [cityTokens[p] tokenImage]; } for (p = p_neutral; p <= p_player3; p++) { for (l = 0; l < 4; l++) { onLandTokens[p][l] = [[Token alloc] initIcon:loop_to_land[l] onTerrain:t_land forPlayer:p]; onLandImages[p][l] = [onLandTokens[p][l] tokenImage]; } for (l = 0; l < 10; l++) { onWaterTokens[p][l] = [[Token alloc] initIcon:loop_to_water[l] onTerrain:t_water forPlayer:p]; onWaterImages[p][l] = [onWaterTokens[p][l] tokenImage]; } for (l = 0; l < 12; l++) { onCityTokens[p][l] = [[Token alloc] initIcon:i_army + l onTerrain:t_city forPlayer:p]; onCityImages[p][l] = [onCityTokens[p][l] tokenImage]; } } unknown = [[Token alloc] initIcon:i_none onTerrain:t_unknown forPlayer:p_neutral]; land = [[Token alloc] initIcon:i_none onTerrain:t_land forPlayer:p_neutral]; water = [[Token alloc] initIcon:i_none onTerrain:t_water forPlayer:p_neutral]; [self setColor:[NSColor lightGrayColor] forPlayer:p_neutral]; [self setColor:color1 forPlayer:p_player1]; [self setColor:color2 forPlayer:p_player2]; [self setColor:color3 forPlayer:p_player3]; observers = [[NSMutableArray array] retain]; return self; } //---------------------------------------------------------------------- - (void) dealloc { int l; Player p; for (p = p_neutral; p <= p_player3; p++) { SNRelease (cityTokens[p]); for (l = 0; l < 4; l++) SNRelease (onLandTokens[p][l]); for (l = 0; l < 10; l++) SNRelease (onWaterTokens[p][l]); for (l = 0; l < 12; l++) SNRelease (onCityTokens[p][l]); } // Notify things using this? Observer pattern? SNRelease (observers); [super dealloc]; } //---------------------------------------------------------------------- - (NSColor *) colorForPlayer:(Player)p { return [Token colorForPlayer:p]; } //---------------------------------------------------------------------- - (void) setColor:(NSColor *)aColor forPlayer:(Player)p { [Token setColor:aColor forPlayer:p]; [self recacheImagesForPlayer:p]; [self notify:(p == p_player1):(p == p_player2):(p == p_player3):(p == p_neutral)]; } //---------------------------------------------------------------------- - (void) recacheImagesForPlayer:(Player)p { int l; [cityImages[p] recache]; for (l = 0; l < 4; l++) [onLandImages[p][l] recache]; for (l = 0; l < 10; l++) [onWaterImages[p][l] recache]; for (l = 0; l < 12; l++) [onCityImages[p][l] recache]; } //---------------------------------------------------------------------- - (NSImage *) cursor { return default_cursor; } //---------------------------------------------------------------------- - (NSImage *) directionCursor { return direction_cursor; } //---------------------------------------------------------------------- - (NSImage *) unknown { return [unknown tokenImage]; } //---------------------------------------------------------------------- - (NSImage *) land { return [land tokenImage]; } //---------------------------------------------------------------------- - (NSImage *) water { return [water tokenImage]; } //---------------------------------------------------------------------- - (NSImage *) explosion { return explosion; } //---------------------------------------------------------------------- - (NSImage *) neutralCity { return cityImages[p_neutral]; } //---------------------------------------------------------------------- - (void) player:(Player)aPlayer:(NSImage **)city:(NSImage ***)onLand:(NSImage ***)onWater:(NSImage ***)onCity:(NSImage ***)odd { if (city != NULL) *city = cityImages[aPlayer]; if (onLand != NULL) *onLand = onLandImages[aPlayer]; if (onWater != NULL) *onWater = onWaterImages[aPlayer]; if (onCity != NULL) *onCity = onCityImages[aPlayer]; if (odd != NULL) *odd = [Token oddballsForPlayer:aPlayer]; } @end //====================================================================== @implementation EmpireImageVendor (ObserverPattern) - (void) attach:observer { // What if same observer attached twice, detached once? [observers addObject:observer]; } //---------------------------------------------------------------------- - (void) detach:observer { [observers removeObject:observer]; } //---------------------------------------------------------------------- - (void) notify:(BOOL)player1:(BOOL)player2:(BOOL)player3:(BOOL)other { NSEnumerator *observerEnumerator = [observers objectEnumerator]; id tmp; while (tmp = [observerEnumerator nextObject]) { if ([tmp respondsToSelector:@selector (vendorImagesUpdated::::)] == YES) { [tmp vendorImagesUpdated:player1:player2:player3:other]; } } } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.