Advertise Books Events Forum News Social Networking Support Us

sdkIQ for iPhone
($4.99)

Shape Up
($0.99)

Your First iPhone App
($1.99)

iVidCam Free
(free)

Kid Art
($0.99)

iPUBQUIZ
(£1.19)

ArtStudio
($3.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development > iPhone SDK Development - Advanced Discussion

Reply
 
LinkBack Thread Tools Display Modes
Old 06-26-2009, 01:52 PM   #1 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default How to simplify this code block?

I'm looking for a way to simplify some of my code so it doesn't take up 18,000 lines. Basically the code is the same code inside 12 switches.
Code:
Switch (1stage){
     case 0:
     1.animationimages = empty; // this is an array of image filenames, works fine
     break;
     case 1:
     if (1stuff >= 3){
          if (1otherstuff >= 3{
               1stage++; 
               1stuff = 0;
               1otherstuff = 0;
               1.animationimages = newstageimage; // this is an array of image filenames, works fine
          }
     }
And so on for 112 stages
What I'm having trouble finding how to do is creating an array of each of the 12 items and a forLoop that makes the changes for each of the items in the array. Thus reducing my 18,000 lines of code to only 1700ish.
Any suggestions?
__________________
Apps I've coded:
Greeble
Cat Juggling
Garden 2 Go

Last edited by ataranlen; 06-30-2009 at 11:53 AM.
ataranlen is offline   Reply With Quote
Old 06-26-2009, 03:31 PM   #2 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
Default

You almost certainly want to use an NSArray or NSMutableArray of items instead of 12 separate variables, and you probably want a custom class too. Your variable names are all too generic to tell what's going on, but you want to write something like this:

Code:
for ( (StageClass )*stage in stageArray){
     stage.count++;
     stage.stuff=0;
     stage.otherStuff=0;
     stage.animationImages = newStageImage
}
This is going to require writing your own class call StageClass, and setting up stuff and otherStuff as "properties." It's also possible to do it without your own class, with multiple arrays like stuffArray and otherStuffArray, but it's bad design and it will be difficult to maintain.

Better yet, you may be able to put the operation inside a method in StageClass, and just run that method on every object. This would cause every object in the array to call [self myMethod] .

Code:
[stageArray makeObjectsPerformSelector:@selector(myMethod)];
I know this sounds like a lot to learn, but it will really make this code simple and easier to debug.
__________________
smasher is offline   Reply With Quote
Old 06-26-2009, 03:47 PM   #3 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default

Code:
switch (plant1stage) {
		case 0:
			plant1water = 0;
			plant1fertilizer = 0;
			[plant1 stopAnimating];
			plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
			plant1.animationImages = empty_plot;
			[plant1 startAnimating];
			plant1stage = 0;
			break;
		case 1:
			if (plant1fertilizer >= required_fert_tree) {
				if (plant1water >= required_water_tree) {
					plant1water = 0;
					plant1fertilizer = 0;
					[plant1 stopAnimating];
					plant1.frame = CGRectMake(50, plant1.center.y-160, 320, 350);
					plant1.animationImages = apple_stage_1;
					[plant1 startAnimating];
					plant1stage = 2;
				} else {
					[plant1 stopAnimating];
					plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
					plant1.animationImages = empty_plot;
					[plant1 startAnimating];
					plant1stage = 0;
				}
			} else {
				[plant1 stopAnimating];
				plant1.frame = CGRectMake(50, plant1.center.y-25, 50, 50);
				plant1.animationImages = empty_plot;
				[plant1 startAnimating];
				plant1stage = 0;
			}
			break;
		case 2:
Thats the gist of my code, there are a total of 12 plants, each one has its one Water, Fertilizer, stage and image. The switch is designed to be the end of a day cycle that causes the plants to grow. They grow only if they have enough water and fertilizer.
ataranlen is offline   Reply With Quote
Old 06-26-2009, 04:15 PM   #4 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
Default

Then you definitely want to create a Plant class, with a dayCycle method. Then when the sun goes down, you can call this code to to update every plant in the array. Search this board for NSMutableArray if you need help creating the array.
Code:
[plantArray makeObjectsPerformSelector:@selector(dayCycle)];
Inside your plant class, you'll have an "init" method that sets up all of the variables, and the "dayCycle" method that updates all of the variables for this *ONE* plant. dayCycle will look something like this:
Code:
-(void) dayCycle{

     switch (stage) {
		case 0:
			water = 0;
			fertilizer = 0;
			[imageView stopAnimating];
			imageView.frame = CGRectMake(50, frame.center.y-25, 50, 50);
			imageView.animationImages = empty_plot;
			[imageView startAnimating];
			stage = 0;
			break;
		case 1:
//etc...
}
__________________
smasher is offline   Reply With Quote
Old 06-27-2009, 01:23 AM   #5 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default

Alright, I am having alot of issues with creating my own class called StageClass. Do you know of any tutorial on how to create a custom class? Every google search turns up junk about how the iphone is world class ect. I'll keep looking though.

Edit: So I finally found some tutorials, and here's what I'm up to:

The only problem is, I can't get the image to show up at all.

Code:
//
//  StageClass.h
//

#import <Foundation/Foundation.h>

@interface StageClass : NSObject
{
	// Initialization of the properties
	int plantState;
	int water;
	int harvest;
	int harvestCounter;
	int fertilizer;
	UIImageView *imageView;
	
}

@property(assign, readwrite) int plantState;
@property(assign, readwrite) int water;
@property(assign, readwrite) int harvest;
@property(assign, readwrite) int harvestCounter;
@property(assign, readwrite) int fertilizer;
@property(retain, readwrite) UIImageView *imageView;


@end
Code:
//  StageClass.m

#import "StageClass.h"

@implementation StageClass
@synthesize plantState = _plantState;
@synthesize water = _water;
@synthesize fertilizer = _fertilizer;
@synthesize harvest = _harvest;
@synthesize harvestCounter = _harvestCounter;
@synthesize imageView = _imageView;

- (void)endDayCycle{
	switch (plantState) {
		case 0:
			water = 0;
			fertilizer = 0;
			[imageView stopAnimating];
			imageView.userInteractionEnabled = YES;
			imageView.frame = CGRectMake(50, 430, 320, 350);
			imageView.animationImages = [[NSArray alloc] initWithObjects:    
										 [UIImage imageNamed:@"empty_plot_filler.png"],nil] ;
			[imageView startAnimating];
			
			plantState = 0;
			break;
		case 1:
			if (fertilizer >= 3) {
				if (water >= 3) {
					water = 0;
					fertilizer = 0;
					[imageView stopAnimating];
					imageView.animationImages = [[NSArray alloc] initWithObjects:    
												 [UIImage imageNamed:@"001.png"],
												 [UIImage imageNamed:@"001.png"],nil] ;;
					[imageView startAnimating];
					plantState = 2;
				} else {
					[imageView stopAnimating];
					imageView.animationImages = [[NSArray alloc] initWithObjects:    
												 [UIImage imageNamed:@"empty_plot_filler.png"],nil] ;;
					[imageView startAnimating];
					plantState = 0;
				}
			} else {
				[imageView stopAnimating];
				imageView.animationImages = [[NSArray alloc] initWithObjects:    
											 [UIImage imageNamed:@"empty_plot_filler.png"],nil] ;;
				[imageView startAnimating];
				plantState = 0;
			}
			break;
			
	}
}
-(void) dealloc
{
	[imageView release];
	[super dealloc];
}

@end
Code:
//exerpt from ViewController.h:
IBOutlet StageClass *plant1;
}
@property(nonatomic,retain) StageClass *plant1;
Code:
//exerpt from -(void)viewdidload from ViewController.m:
	plant1.imageView = [[UIImageView alloc] initWithFrame:self.view.frame];
	plant1.imageView.userInteractionEnabled = YES;
	plant1.imageView.frame = CGRectMake(50, 0, 320, 350);
	plant1.imageView.animationImages = empty_plot;
	plant1.imageView.animationDuration = 0.5;
	plant1.imageView.animationRepeatCount = 0;
	[plant1.imageView startAnimating];

Last edited by ataranlen; 06-27-2009 at 02:54 AM.
ataranlen is offline   Reply With Quote
Old 06-27-2009, 11:12 AM   #6 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
Default

You've done very well! Only a few things I see missing. You don't need plant1 to be an IBOutlet; it's easier to create it in code than in interface builder. To create the plant object, you do this:

Code:
//in (void)viewdidload from ViewController.m:
plant1 = [[StageClass alloc] init];
Also replace your @synthesize lines to just this one:
Code:
@synthesize plantState, water, fertilizer, harvest, harvestCounter, imageView;
You don't need water = _water, becuase you don't have variable named _water. The properties already match the variable names.
__________________
smasher is offline   Reply With Quote
Old 06-27-2009, 11:37 AM   #7 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default

So when you say I do not need an IBOutlet, I run into problems with that, I use plant1 in more places than just viewdidload. If I only init it in viewdidload, it shows as not found.
Am I supposed to remove it from viewcontroller.h? or just take out the IBOutlet? OR take out the entire IBOutlet line?

Experimentation tells me I just take out the IBOutlet part of the line and it works fine now! Wow, I never thought I would figure out classes!
ataranlen is offline   Reply With Quote
Old 06-27-2009, 02:57 PM   #8 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
Default

Quote:
Originally Posted by ataranlen View Post
So when you say I do not need an IBOutlet, I run into problems with that, I use plant1 in more places than just viewdidload. If I only init it in viewdidload, it shows as not found.
Am I supposed to remove it from viewcontroller.h? or just take out the IBOutlet? OR take out the entire IBOutlet line?

Experimentation tells me I just take out the IBOutlet part of the line and it works fine now! Wow, I never thought I would figure out classes!
Success! I was afraid that learning to create classes would be intimidating, but it's necessary in the long run. May as well do it now.
__________________
smasher is offline   Reply With Quote
Old 06-27-2009, 03:11 PM   #9 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default

Alright, So remember How I had those arrays that I would use to set the animationImages?
They are set in the Viewcontroller. How would I go about using them in the Class in the endDayCycle?
ataranlen is offline   Reply With Quote
Old 06-27-2009, 06:00 PM   #10 (permalink)
Senior Member
iPhone Dev SDK Supporter
 
smasher's Avatar
 
Join Date: Jul 2008
Location: San Mateo, CA (San Fran)
Posts: 2,575
Post

Quote:
Originally Posted by ataranlen View Post
Alright, So remember How I had those arrays that I would use to set the animationImages?
They are set in the Viewcontroller. How would I go about using them in the Class in the endDayCycle?
Many options; you could make them properties of the viewController, and pass the whole viweController into the endDayCycle method. If you did that, then endDayCycle would look like this:

Code:
-(void) endDayCycle: (ViewController*) controller{
     self.imageView.animationImages = controller.newstageimage;

//other stuff I assume
}
Another method would be to put them in the application delegate, which you can get to from anywhere in your program with [[UIApplication sharedApplication] delegate] , or you could put them in a C global variable.
__________________
smasher is offline   Reply With Quote
Old 06-28-2009, 12:28 AM   #11 (permalink)
Registered Member
 
ataranlen's Avatar
 
Join Date: Jun 2009
Location: Flower Mound, Texas
Age: 20
Posts: 34
Default

So basicly just use them as if the viewController as a class itself and use the objects in it? Sounds like a very simple solution! I'll have to try it out when I go back to work on Monday.

EDIT: When i try and set it up like this:
-(void) endDayCycle: (ProjectViewController*) controller{

It says error: expected ')' before 'ProjectViewController'
__________________
Apps I've coded:
Greeble
Cat Juggling
Garden 2 Go

Last edited by ataranlen; 06-30-2009 at 11:53 AM.
ataranlen is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Enter the iPhone App Challenge!  Win $500!
» Advertisements
» Stats
Members: 24,291
Threads: 39,080
Posts: 171,361
Top Poster: smasher (2,575)
Welcome to our newest member, tyro
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 09:31 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2010, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0