COMP 310
Spring 2019

Lab05:  Sending Commands

Home  Info  Canvas   Java Resources  Eclipse Resources  Piazza

Command-based Updating

First, we should review the lecture materials on Command-based Dispatching and Updating.  

Do not attempt to use the generic dispatcher at first.   Get your command dispatching fully operational with minimal modification of your original system then transition over to using the generic dispatcher.    Switching over to the generic dispatcher will require code changes throughout your system which are tedious and time-consuming.    You may get some strange error messages -- ask for help by by posting them to Piazza!

Implementing Command-based Updating

For homework 4, you have already (at least begun) to transition your system to perform command-based updating as described above.  If you have not already completed this, you should first replicate the systems current behavior with command-based dispatching:

  1. Using the constructs above, change the update code of your ball to take an IBallCmd as its input parameter that it then simply "applies".  
  2. Change the code of in the model for the call to the dispatcher's notifyAll method.   Use an anonymous inner class to define the IBallCmd to be sent to the balls (Why do we need an anonymous inner class here?)     Where do you think the code that used to be in the ball's update method now resides?

When you are done, your BallWorld/FishWorld system should run identically as before, but with a new door open to even more possibilities!

Did you have to touch your view code at all?   The controller code?   Why or why not?

For the adventurous: By installing a second Timer object, can you decouple the painting process from the updating of the ball state?   In doing so, can you fix the problem of resizing and animated GIFs affecting the behavior of the balls?

Sending Commands to Other Balls

If you haven't done so already, the system needs to send a reference to the IDispatcher object to the balls when they are notified..  This means that commands you send to the balls will now have access to the IDispatcher!

But since we are changing the type of message being sent to the balls from Graphics objects to IBallCmds, the generic type of the IDispatcher needs to be changed as well.

We can use this to enable commands that send commands to other balls!  However, this requires a slight change to all of your strategies, in that the updateState method must now also take a IDispatcher<IBallCmd> object.  You should modify the IUpdateStrategy  interface as follows:

public interface IUpdateStrategy {
	/**
	 * Update the state of the context Ball.
	 * @param context  The context (host) Ball whose state is to be updated
	 * @param dispatcher  The Dispatcher who sent the command that is calling through to here.
	 */
	public abstract void updateState(Ball context, IDispatcher<IBallCmd> dispatcher);
}

The best way to accomplish this is to use the refactoring capabilities of Eclipse:  right-click the updateState method name in IUpdateStrategy and select "Refactor/Change Method Signature...".  Add the Dispatcher input parameter to the updateState method.   This will automatically add the extra parameter to all afected methods.   Some errors may  persist, so check the Problems list and  DO NOT PROCEEED UNTIL ALL THE PROBLEMS HAVE BEEN RESOLVED!

In the Ball, we pass the Dispatcher along to the update strategy.  The IBallCmd is responsible for passing it along to the Ball's updateState method:

/**
 * Update the state of the ball.   Delegates to the update strategy.
 * @param dispatcher The Dispatcher that sent the command that is calling this method.
 */
public void updateState(IDispatcher<IBallCmd> dispatcher){
	_updateStrategy.updateState(this, dispatcher); // update this ball's state using the strategy.		
}

Now an IUpdateStrategy is free to send commands out through the dispatcher to all the other balls (including itself)!

You can refer back to Friday's lecture to see an example of the SpawnStrategy, which spawns new balls when a "spawn" ball makes contact with any other ball.

Modeling the Spread of Infections

Simulations are a common way to study the natural world.   Researchers make small, confined replicas of the natural world, that have just what are believed to be the crucial essenses of the real situation.   That is, a simulation is an abstraction of the real world, a distillation of its key features.   The theory is that if one can capture the key features of a situation, then the key behaviors of the situation will be replicated.

Let's consider the job of an epidemiologist studying how infections spread in a population.   So, a reasonable question such a researcher might ask is "How does the density of the population affect the ability of a disease to maintain an on-going presence in the population?" 

On the surface, it seems that the spread of disease is very simple:  If an infected person contacts another person, that person will be come infected.   Now that transmission is probably not a 100% sure thing, but let's assume a worst case scenario here.   But after a while, the infected person gets better and is no longer contagious, so they cannot spread the disease anymore, though they are perfectly capable of getting re-infected.   Once again, we are ignoring complications of aquired immunity. 

 Our Ballworld system is a collection of interacting entities, "agents" in CS-speak.   We can change the density of the population of balls either by changing the number of balls or by changing the size of the display canvas in which they are moving.  What we need is a behavior that models the infecting of another ball when it comes into contact with an already infected ball.   We also need to model the "getting well" phenomenon.

So today, we are going to create the InfectStrategy, which "infects" other balls when it makes contact with them.  Here's what the InfectStrategy does:

  1. It sets the color of the ball to black to indicate that it is "infected".
  2. It sends a command to all other balls that:
    1. Checks if it is the ball that sent the command and if so, does nothing.
    2. Checks if the other ball is in contact with the infected ball and if so, changes the other ball's update strategy to be a new InfectStrategy.
  3. After running (updating) a certain number of times (what's a reasonable number? -- remember, it's your simulation!), the strategy changes to a new StraightStrategy with a random color.  At that point, the ball is no longer infected (it doesn't use the InfectStrategy anymore), so it will not affect any other balls.

Depending on the count you use to determine when a ball stops being infected, the number of infected balls, the size of the canvas, and the total number of balls, you will see different interesting behaviors with this strategy.    Does anything change if you have the balls move differently?   While it is one can definitely say that this overtly simple simulation does not accurately mimic actual disease transmission vectors, why is it able to replicate the same large-scale phenomenon?   Is it just coincidence or does our little ballworld system manage to capture a particularly critical aspect of the real world?  What does it tell us about the important issues to pay attention to when we study the real world?

In particular, notice that the breakover from having the disease die out completely to when it completely takes over the population is very sudden.   This behavior is similar to the "phase transition" behavior that you may have seen when studying connectivity in networks in Comp140.   Could the two issues be related?

An interesting note is how such a simple behavior as our infection model can manifest itself in the form of such complex macroscopic phenomena.   This is the classic "butterfly's sneeze" phenomenon. This reasons for this lies at the heart of chaos theory and  is one of the biggest unsolved problems in science today.     Chaotic systems range from atomic systems to traffic jams to social networks to weather systems to galactic systems and are of vast importance in our everyday lives.


© 2019 by Stephen Wong