We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpSyntax Questions › boat has-a boatBrain AND boatBrain has-a boat
Page Index Toggle Pages: 1
boat has-a boatBrain AND boatBrain has-a boat? (Read 260 times)
boat has-a boatBrain AND boatBrain has-a boat?
Mar 6th, 2009, 9:13pm
 
Can this be done:

//start of sketch
Motor motor1 = new Motor();  Motor motor2 = new Motor();
PVector boatPos = new PVector(400,400);
Boat boat = new Boat();
BoatBrain boatBrain = new BoatBrain(motor1, motor2, boat);
//!! re-defining boat! hopefully 'boat' will still have the same address afterwards:
boat = new Boat(motor1, motor2, boatBrain, boatPos);

void setup() {
 size(800,800);
}

void draw() {
 boat.boatBrain.navigate();
}


My boat-class has two constructors:

Boat() {};  //simple constructor
Boat(Motor motor1, Motor motor2, BoatBrain boatBrain, PVector boatPos) { /*constructor stuff*/ }


Why would I want to make boat and boatBrain "have" each other? Well, just to see if it would work, and to tease the JVM (and now to irritate me). I can't see why it shouldn't work. It doesn't work though..: When running, it halts at void setup()  because it doesn't expect void to appear there ("unexpected token: void").
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #1 - Mar 6th, 2009, 9:16pm
 
If someone wants to see all the code, here it is:

 Motor motor1 = new Motor();  Motor motor2 = new Motor();
 PVector boatPos = new PVector(400,400);
 Boat boat = new Boat();
 BoatBrain boatBrain = new BoatBrain(motor1, motor2, boat);
 boat = new Boat(motor1, motor2, boatBrain, boatPos);

void setup() {
 size(800,800);
}
void draw() {
 boat.boatBrain.navigate();  //pure peacocking - not used until navigation algoritm is in place..
 
}

class Sea {}

class Boat {
 private Motor motor1, motor2;
 private BoatBrain boatBrain;
 private int movementState;
 private PVector position;
 Boat() {};  //simple constructor
 Boat(Motor motor1, Motor motor2, BoatBrain boatBrain, PVector boatPos) {
   this.motor1=motor1; this.motor2=motor2; this.boatBrain=boatBrain; this.movementState=0; this.position.x=boatPos.x; this.position.y=boatPos.y; }
 private void reactToAppliedForces() {}
 
}
class Motor {
 private boolean On;
 private boolean Forward;
 Motor() {this.On = false; this.Forward = false;}
 private void setOnOff() {this.On = !this.On;}
 private void setForwardBackward() {this.Forward = !this.Forward;}

}
class BoatBrain {
 private Motor motor1, motor2;
 private Boat boat;
 private boolean On;
 BoatBrain(Motor motor1, Motor motor2, Boat boat) {this.motor1=motor1; this.motor2=motor2; this.boat=boat; On=true; }
 public void navigate() {

 }
}

void keyPressed() {
 println("");
 println("a key got pressed");
 if(key=='0') { boat.motor1.setOnOff(); }
 if(key=='1') { boat.motor1.setForwardBackward(); }
 if(key=='2') { boat.motor2.setOnOff(); }
 if(key=='3') { boat.motor2.setForwardBackward(); }
}
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #2 - Mar 6th, 2009, 9:45pm
 
Here's an edited, working code.  You can't assign the variables outside of a method if you are using setup.  I've also fixed a problem with the initial values.

And yes, a pair of objects can have references to each other.

Quote:
Motor motor1;  
Motor motor2;
PVector boatPos;
Boat boat;
BoatBrain boatBrain;

void setup() {
  motor1 = new Motor();  
  motor2 = new Motor();
  boatPos = new PVector(400,400);
  //boat = new Boat();
  boatBrain = new BoatBrain(motor1, motor2, boat);
  boat = new Boat(motor1, motor2, boatBrain, boatPos);
  size(800,800);


}
void draw() {
  boat.boatBrain.navigate();  //pure peacocking - not used until navigation algoritm is in place..

}

class Sea {
}

class Boat {
  private Motor motor1, motor2;
  private BoatBrain boatBrain;
  private int movementState;
  private PVector position = new PVector(0,0);
  Boat() {};  //simple constructor
  
  Boat(Motor motor1, Motor motor2, BoatBrain boatBrain, PVector boatPos) {
    this.motor1=motor1;
    this.motor2=motor2;
    this.boatBrain=boatBrain;
    this.movementState=0;
    this.position.x=boatPos.x;
    this.position.y=boatPos.y;
  }
  private void reactToAppliedForces() {}

}
class Motor {
  private boolean On;
  private boolean Forward;
  Motor() {
    this.On = false;
    this.Forward = false;
  }
  private void setOnOff() {
    this.On = !this.On;
  }
  private void setForwardBackward() {
    this.Forward = !this.Forward;
  }

}


class BoatBrain {
  private Motor motor1, motor2;
  private Boat boat;
  private boolean On;
  
  BoatBrain(Motor motor1, Motor motor2, Boat boat) {
    this.motor1=motor1;
    this.motor2=motor2;
    this.boat=boat;
    On=true;
  }
  
  public void navigate() {

  }
}

void keyPressed() {
  println("");
  println("a key got pressed");
  if(key=='0') {
    boat.motor1.setOnOff(); 
  }
  if(key=='1') {
    boat.motor1.setForwardBackward(); 
  }
  if(key=='2') {
    boat.motor2.setOnOff(); 
  }
  if(key=='3') {
    boat.motor2.setForwardBackward(); 
  }



Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #3 - Mar 7th, 2009, 1:34am
 
Nice - thank you.
If I were to take a better Object Oriented Design-approach I guess I should put the stuff that right now resides in the top and in the Setup-method in a main-method in one of the classes. However, I can't see how that main-method would ever be called, if I don't explicit make it happen myself by calling it from eg. the Setup-method.
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #4 - Mar 7th, 2009, 9:40am
 
sw01 wrote on Mar 6th, 2009, 9:45pm:
You can't assign the variables outside of a method if you are using setup.

Sorry, but that's not correct.
A better wording would be: "You should avoid assigning objects at global level if there is a setup", but actually it is safe is most cases. Now, there are problematic cases, hence the "should".

int i = 5; // OK
ArrayList a = new ArrayList(); // OK
MyObject mo = new MyObject(); // Suspicious because of below (that could be done in constructor too)
PImage foo = loadImage("x"); // KO, data folder is known only after start of setup
int x = width: // KO, because size() is in setup()

So your advice isn't bad, it is better to play safe if you are not sure... Smiley
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #5 - Mar 7th, 2009, 9:54am
 
Ah, right.  I had that rule lodged in my mind without thinking exactly *why* I shouldn't do it.
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #6 - Mar 7th, 2009, 10:19am
 
PhiLho  wrote on Mar 7th, 2009, 9:40am:
int i = 5; // OK
ArrayList a = new ArrayList(); // OK
MyObject mo = new MyObject(); // Suspicious because of below (that could be done in constructor too)
PImage foo = loadImage("x"); // KO, data folder is known only after start of setup
int x = width: // KO, because size() is in setup()


I still don't get why some stuff should go in the Setup and other shouldn't (more specifically, I don't understand what makes the line "MyObject mo = new MyObject();" suspicious). Whats good design, when using, and not using, the Setup-method Any guides/texts on this
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #7 - Mar 7th, 2009, 2:05pm
 
Hi

My thoughts on it is that I always avoid, where possible, to instantiate variables in the global scope or in the constructor.
When instantiating in the global scope these objects will take up memory even before they are used and the same goes for putting things in the constructor.

I will often have an init() method and lots of getters and setters below my constructor, so that I can instantiate an object(being "empty"), but wait to later on to actually fill it with data. This goes for my external classes, setup is different...
Design patterns and use of private/public methods like getters and setters will simplify both the way you design classes and the memory footprint you use up.
A local variable will only take up memory when the method gets called, a global will not release memory when you are done with it.

I think of the setup() as the constructor of a sketch, but a constructor that you must run, a sort of main(). So I will define the fields I need as this:

PImage i1, i2;
PVector v1, v2;

setup()
{
i1 = new PImage();
v1 = new PVector();
}

just the way sw01 does it.
As PhiLho writes: some methods and fields are not available before setup has been executed. So MyObject mo = new MyObject() before setup() can be suspicious as we dont know what the constructor of MyObject() will utilize? will it access frameCount(), width or other fields and methods not currently available?
The error messages you will get when doing instantiating before setup(), when something goes wrong, are also crazy and not the least bit helpful (an important subject that is often left out is how to code to help the debugger help you :) ).

I don't have a deep understanding of how the processing environment works, so the above is just from my experience and what I believe to be good coding conventions in general.

When doing the boatBrain -> boat and boat -> boatBrain you are sending references all over the place and coupling these object strongly, this means that later on you can not have a boat or boatBrain exist without the other. Probably not an issue....for now :)
Maybe something like at "composite pattern" or "strategy pattern" if more algorithms are involved, would simplify things.
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #8 - Mar 7th, 2009, 3:10pm
 
Nothing to add to RickiG explanations! Smiley
I still create objects in constructors, when I am sure I will use them. Now, it is a question of design principles and such.
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #9 - Mar 7th, 2009, 5:09pm
 
Yep, it makes more sense now. I think I'm going for this book:
http://www.amazon.co.uk/Thinking-Java-Bruce-Eckel/dp/0131872486/ref=wl_it_dp?ie=UTF8&coliid=IIX2505OBML6Z&colid=1JIEED1XOWCIH

it sounds like the thing I need.
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #10 - Mar 7th, 2009, 5:20pm
 
While you wait for your book http://sourcemaking.com/design_patterns
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #11 - Mar 7th, 2009, 5:46pm
 
to RickiG:

So instead of letting each object have a HAS-A relation to each other you want met to do something like this:

myClass1 myObject1;
myClass2 myObject2;

void setup() {
myObject1 = new myClass1();
myObject2 = new myClass2();
myObject2.wreakHavocOn_myObject1(-1);
}

class myClass1 {
 private int variableToBeAlteredBy_myObject2;
 myClass1() {}  //constructor
 public void setVariable(int newValue) {
   variableToBeAlteredBy_myObject2 = newValue;
 }
}

class myClass2 {
 myClass2() {}  //constructor
 private void wreakHavocOn_myObject1(int newValue) {
   myObject1.setVariable(newValue);
 }
}
Re: boat has-a boatBrain AND boatBrain has-a boat?
Reply #12 - Mar 7th, 2009, 8:42pm
 
Note: Thinking in Java, 3rd Edition is a free online book... Smiley
If you want a dead tree book, I highly recommend Head First Java (O'Reilly), it was the book that made me really understand what OO design is (despite previous attempts to learn that with C++...). Head First Design Patterns is good too, but more for advanced uses.
Page Index Toggle Pages: 1