Added WindCommand and multiple command execution to RaceLogic
- Dispatch commands with CompositeCommand - Single WindCommand handles upwind and downwind logic - Changed key bindings as Mac lacks PgUp PgDn - ControllerServer is observable, RaceLogic updates CompositeCommand as observer
This commit is contained in:
@@ -1,12 +1,20 @@
|
|||||||
package mock.model;
|
package mock.model;
|
||||||
|
|
||||||
import javafx.animation.AnimationTimer;
|
import javafx.animation.AnimationTimer;
|
||||||
|
import mock.model.commandFactory.Command;
|
||||||
|
import mock.model.commandFactory.CommandFactory;
|
||||||
|
import mock.model.commandFactory.CompositeCommand;
|
||||||
|
import network.Messages.Enums.BoatActionEnum;
|
||||||
import network.Messages.Enums.BoatStatusEnum;
|
import network.Messages.Enums.BoatStatusEnum;
|
||||||
import network.Messages.Enums.RaceStatusEnum;
|
import network.Messages.Enums.RaceStatusEnum;
|
||||||
import network.Messages.LatestMessages;
|
import network.Messages.LatestMessages;
|
||||||
import shared.model.Race;
|
import visualiser.gameController.ControllerServer;
|
||||||
|
|
||||||
public class RaceLogic implements Runnable {
|
import java.util.Observable;
|
||||||
|
import java.util.Observer;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class RaceLogic implements Observer, Runnable {
|
||||||
/**
|
/**
|
||||||
* State of current race modified by this object
|
* State of current race modified by this object
|
||||||
*/
|
*/
|
||||||
@@ -16,6 +24,8 @@ public class RaceLogic implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private RaceServer server;
|
private RaceServer server;
|
||||||
|
|
||||||
|
private CompositeCommand commands;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises race loop with state and server message queue
|
* Initialises race loop with state and server message queue
|
||||||
* @param race state of race to modify
|
* @param race state of race to modify
|
||||||
@@ -24,6 +34,7 @@ public class RaceLogic implements Runnable {
|
|||||||
public RaceLogic(MockRace race, LatestMessages messages) {
|
public RaceLogic(MockRace race, LatestMessages messages) {
|
||||||
this.race = race;
|
this.race = race;
|
||||||
this.server = new RaceServer(race, messages);
|
this.server = new RaceServer(race, messages);
|
||||||
|
this.commands = new CompositeCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -123,7 +134,7 @@ public class RaceLogic implements Runnable {
|
|||||||
|
|
||||||
//If it is still racing, update its position.
|
//If it is still racing, update its position.
|
||||||
if (boat.getStatus() == BoatStatusEnum.RACING) {
|
if (boat.getStatus() == BoatStatusEnum.RACING) {
|
||||||
|
commands.execute();
|
||||||
race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli());
|
race.updatePosition(boat, framePeriod, race.getRaceClock().getDurationMilli());
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -173,4 +184,13 @@ public class RaceLogic implements Runnable {
|
|||||||
iters++;
|
iters++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Observable o, Object arg) {
|
||||||
|
ControllerServer server = (ControllerServer)o;
|
||||||
|
BoatActionEnum action = server.getAction();
|
||||||
|
MockBoat boat = race.getBoats().get(0);
|
||||||
|
|
||||||
|
commands.addCommand(CommandFactory.createCommand(race, boat, action));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ public class CommandFactory {
|
|||||||
switch(action) {
|
switch(action) {
|
||||||
case AUTO_PILOT: return new VMGCommand(race, boat);
|
case AUTO_PILOT: return new VMGCommand(race, boat);
|
||||||
case TACK_GYBE: return new TackGybeCommand(race, boat);
|
case TACK_GYBE: return new TackGybeCommand(race, boat);
|
||||||
|
case UPWIND: return new WindCommand(race, boat, true);
|
||||||
|
case DOWNWIND: return new WindCommand(race, boat, false);
|
||||||
default: return null; // TODO - please please have discussion over what to default to
|
default: return null; // TODO - please please have discussion over what to default to
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package mock.model.commandFactory;
|
||||||
|
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wraps multiple commands into a composite to execute queued commands during a frame.
|
||||||
|
*/
|
||||||
|
public class CompositeCommand implements Command {
|
||||||
|
private Stack<Command> commands;
|
||||||
|
|
||||||
|
public CompositeCommand() {
|
||||||
|
this.commands = new Stack<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCommand(Command command) {
|
||||||
|
commands.push(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
while(!commands.isEmpty()) commands.pop().execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package mock.model.commandFactory;
|
||||||
|
|
||||||
|
import mock.model.MockBoat;
|
||||||
|
import mock.model.MockRace;
|
||||||
|
import shared.model.Bearing;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by connortaylorbrown on 4/08/17.
|
||||||
|
*/
|
||||||
|
public class WindCommand implements Command {
|
||||||
|
private MockRace race;
|
||||||
|
private MockBoat boat;
|
||||||
|
private int direction;
|
||||||
|
|
||||||
|
public WindCommand(MockRace race, MockBoat boat, boolean upwind) {
|
||||||
|
this.race = race;
|
||||||
|
this.boat = boat;
|
||||||
|
this.direction = upwind? 1 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
double wind = race.getWindDirection().degrees();
|
||||||
|
double heading = boat.getBearing().degrees();
|
||||||
|
|
||||||
|
double offset = 3;
|
||||||
|
if(wind - heading < 0) offset *= -1 * direction;
|
||||||
|
boat.setBearing(Bearing.fromDegrees(heading + offset));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
package visualiser.gameController;
|
package visualiser.gameController;
|
||||||
|
|
||||||
|
import mock.model.commandFactory.Command;
|
||||||
|
import mock.model.commandFactory.CommandFactory;
|
||||||
import network.BinaryMessageDecoder;
|
import network.BinaryMessageDecoder;
|
||||||
import network.MessageDecoders.BoatActionDecoder;
|
import network.MessageDecoders.BoatActionDecoder;
|
||||||
import network.Messages.Enums.BoatActionEnum;
|
import network.Messages.Enums.BoatActionEnum;
|
||||||
@@ -9,11 +11,12 @@ import visualiser.gameController.Keys.KeyFactory;
|
|||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
|
import java.util.Observable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service for dispatching key press data to race from client
|
* Service for dispatching key press data to race from client
|
||||||
*/
|
*/
|
||||||
public class ControllerServer implements Runnable {
|
public class ControllerServer extends Observable implements Runnable {
|
||||||
/**
|
/**
|
||||||
* Socket to client
|
* Socket to client
|
||||||
*/
|
*/
|
||||||
@@ -22,6 +25,10 @@ public class ControllerServer implements Runnable {
|
|||||||
* Wrapper for input from client
|
* Wrapper for input from client
|
||||||
*/
|
*/
|
||||||
private DataInputStream inputStream;
|
private DataInputStream inputStream;
|
||||||
|
/**
|
||||||
|
* Last received boat action
|
||||||
|
*/
|
||||||
|
private BoatActionEnum action;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialise server-side controller with live client socket
|
* Initialise server-side controller with live client socket
|
||||||
@@ -36,6 +43,10 @@ public class ControllerServer implements Runnable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BoatActionEnum getAction() {
|
||||||
|
return action;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait for controller key input from client and loop.
|
* Wait for controller key input from client and loop.
|
||||||
*/
|
*/
|
||||||
@@ -48,8 +59,10 @@ public class ControllerServer implements Runnable {
|
|||||||
inputStream.read(message);
|
inputStream.read(message);
|
||||||
BinaryMessageDecoder encodedMessage = new BinaryMessageDecoder(message);
|
BinaryMessageDecoder encodedMessage = new BinaryMessageDecoder(message);
|
||||||
BoatActionDecoder boatActionDecoder = new BoatActionDecoder(encodedMessage.getMessageBody());
|
BoatActionDecoder boatActionDecoder = new BoatActionDecoder(encodedMessage.getMessageBody());
|
||||||
BoatActionEnum decodedMessage = boatActionDecoder.getBoatAction();
|
action = boatActionDecoder.getBoatAction();
|
||||||
System.out.println("Received key: " + decodedMessage);
|
|
||||||
|
this.notifyObservers();
|
||||||
|
this.setChanged();
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ public class KeyFactory {
|
|||||||
keyState.put("SPACE", new VMGKey("VMG"));
|
keyState.put("SPACE", new VMGKey("VMG"));
|
||||||
keyState.put("SHIFT", new SailsToggleKey("Toggle Sails"));
|
keyState.put("SHIFT", new SailsToggleKey("Toggle Sails"));
|
||||||
keyState.put("ENTER", new TackGybeKey("Tack/Gybe"));
|
keyState.put("ENTER", new TackGybeKey("Tack/Gybe"));
|
||||||
keyState.put("PAGE_UP", new UpWindKey("Upwind"));
|
keyState.put("UP", new UpWindKey("Upwind"));
|
||||||
keyState.put("PAGE_DOWN", new DownWindKey("Downwind"));
|
keyState.put("DOWN", new DownWindKey("Downwind"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package mock.model.commandFactory;
|
||||||
|
|
||||||
|
import mock.model.MockRace;
|
||||||
|
import network.Messages.Enums.BoatActionEnum;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import shared.model.Boat;
|
||||||
|
import shared.model.Race;
|
||||||
|
import visualiser.model.VisualiserRace;
|
||||||
|
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by connortaylorbrown on 4/08/17.
|
||||||
|
*/
|
||||||
|
public class WindCommandTest {
|
||||||
|
private Race race;
|
||||||
|
private Boat boat;
|
||||||
|
private Command upwind;
|
||||||
|
private Command downwind;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
boat = new Boat(0, "Bob", "NZ");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void upwindCommandDecreasesAngle() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user