diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java index 871b653..928fa52 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/ClientCallbackImpl.java @@ -8,25 +8,52 @@ import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback; import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject; + +/** + * RMI client callback implementation of {@link IClientCallback}. + * Receives notifications from the server and updates the client game model. + */ public class ClientCallbackImpl extends UnicastRemoteObject implements IClientCallback { + /** The client controller used to apply events and update the model */ private final ClientController clientController; + + /** + * Class constructor. + * @param clientController the client controller + * @throws RemoteException if any RMI error occurs + */ public ClientCallbackImpl(ClientController clientController) throws RemoteException { this.clientController = clientController; } + + /** + * Called by the server when the game is initialized. + * Sets the client game model in the {@link ClientController}. + * @param model the initialized {@link Game} model + * @throws RemoteException if any RMI error occurs + */ @Override public void onGameInit(Game model) throws RemoteException { - clientController.setModel(model); // setta il model + clientController.setModel(model); } + + /** + * Called by the server when an action has been accepted. + * If the event contains an error, it is printed to the console. + * Otherwise, the event is applied to the local model. + * @param event the {@link NetworkEvent} sent by the server + * @throws RemoteException if any RMI error occurs + */ @Override public void onAction(NetworkEvent event) throws RemoteException { if(event.getIsError()) { System.out.println(event.toString()); } else { - event.apply(clientController.localController); // delega tutto al controller + event.apply(clientController.localController); //clientController.view.update(); TODO } } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java index 8d0721c..84d797f 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Client/RMIClient.java @@ -1,43 +1,56 @@ package it.polimi.ingsw.gc14.Network.RMI.Client; +import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry; import java.rmi.registry.Registry; import it.polimi.ingsw.gc14.Controller.ClientController; import it.polimi.ingsw.gc14.Network.NetworkEvent; +import it.polimi.ingsw.gc14.Network.RMI.Common.IClientCallback; import it.polimi.ingsw.gc14.Network.RMI.Common.IGameServer; +import it.polimi.ingsw.gc14.Network.RMI.Server.RMIServer; -public class RMIClient { +/** + * Client RMI. Uses the methods exposed by the server RMI. + */ +public class RMIClient { + /** The host address of the RMI server */ private final String host; + + /** The port of the RMI server */ private final int port; + + /** The remote stub used to call methods on the server */ private IGameServer stub; + + /** + * Class constructor. + * @param host the host address of the RMI server + * @param port the port of the RMI server + */ public RMIClient(String host, int port) { this.host = host; this.port = port; } - public boolean connect(String username,int preferredInt,ClientController clientController) { - // 1. Connettiti al registry + /** + * Connects to the RMI server and attempts to join the game. + * Looks up the RMI registry to retrieve the {@link IGameServer} stub. + * Then, creates a {@link ClientCallbackImpl} and calls {@link RMIServer#joinGame(String, int, IClientCallback)}. + * @param username the player's username + * @param preferredInt the desired number of players + * @param clientController the client controller used to create the callback + * @return true if the player successfully joined the game, false otherwise + */ + public boolean connect(String username,int preferredInt, ClientController clientController) { try { Registry registry = LocateRegistry.getRegistry(host, port); - - // 2. Prendi lo stub del server this.stub = (IGameServer) registry.lookup("RMIGameServer"); - - // 3. Crea il callback e registralo ClientCallbackImpl callback = new ClientCallbackImpl(clientController); - if (!stub.joinGame(username,preferredInt, callback)) - { - stub = null; - return false; - } - else - { - return true; - } + return stub.joinGame(username, preferredInt, callback); } catch (Exception e) { e.printStackTrace(); @@ -46,8 +59,12 @@ public class RMIClient { } - - public void doEvent(NetworkEvent event) throws Exception { + /** + * Sends a {@link NetworkEvent} to the server. + * @param event the event to send + * @throws RemoteException if any RMI error occurs + */ + public void doEvent(NetworkEvent event) throws RemoteException { stub.doEvent(event); } diff --git a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java index 1770da4..3578350 100644 --- a/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java +++ b/src/main/java/it/polimi/ingsw/gc14/Network/RMI/Server/RMIServer.java @@ -15,19 +15,47 @@ import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; - import java.rmi.*; + +/** + * Server RMI. Exposes a method to join the game and one to execute an event. + */ public class RMIServer implements IGameServer { + /** Server game's controller */ private GameController controller; + + /** Server game's model */ + private Game model; + + /** RMI registry */ private Registry registry; + + /** RMI port */ private int nPort; + + /** Map containing the associations between a player's username and its callback */ private final Map clients = new ConcurrentHashMap<>(); + + /** Queue containing the events to be applied to the game model */ BlockingQueue actionQueue; + + /** + * List containing the usernames of joined players. + * {@link LimitedList}'s limit defines at which size the list calls its action. The limit can be set using {@link LimitedList#setLimit(int)}. + */ private LimitedList playerList; - // Costruttore + + /** + * Class constructor that initializes the attributes. + * @param controller The game controller + * @param nPort The RMI port + * @param actionQueue The action queue + * @param playerList The player's usernames list + * @throws RemoteException if an RMI error occurs + */ public RMIServer(GameController controller, int nPort, BlockingQueue actionQueue,LimitedList playerList) throws RemoteException { this.controller = controller; this.nPort = nPort; @@ -37,25 +65,29 @@ public class RMIServer implements IGameServer { - - - - // Metodi esposti RMI - public void setController (GameController controller) { - this.controller = controller; - } + // RMI's exposed methods + /** + * Allows a player to join the game. + * If the desired number of player is invalid, the request is rejected. + * If this is the first player, a new game model is created and passed to the controller. Additionally, the playerList's limit is set. + * Then, if the controller successfully adds the player, the username is added to {@link #playerList} and {@link #clients}. + * @param username The player's name + * @param preferredInt The desired number of players + * @param callback The client's callback interface + * @return true if the player successfully joined the game, false otherwise + */ @Override - public boolean joinGame(String username, int preferredInt,IClientCallback callback) { + public boolean joinGame(String username, int preferredInt, IClientCallback callback) { + if (preferredInt<2 || preferredInt>5) { + return false; + } synchronized (controller) { - if(playerList.size()==0 && (preferredInt<2||preferredInt>5)) - return false; + if(playerList.isEmpty()){ + model = new Game(preferredInt); + controller.setModel(model); + playerList.setLimit(preferredInt); + } if (controller.addPlayer(username)) { - if(playerList.size()==0) - { - Game game = new Game(preferredInt); - controller.setModel(game); - playerList.setLimit(preferredInt); - } playerList.add(username); clients.put(username, callback); return true; @@ -63,21 +95,36 @@ public class RMIServer implements IGameServer { return false; } } + + + /** + * Push an action in actionQueue. + * @param action The desired actio + * @return true if the action was successfully added, false otherwise + */ @Override - public boolean doEvent(NetworkEvent event) throws RemoteException { - return actionQueue.offer(event); + public boolean doEvent(NetworkEvent action) { + return actionQueue.offer(action); } - - - // Metodi interni del server + // RMI's internal methods + /** + * Sends an action to all RMI clients. + * @param action The desired action + */ public void notifyAll(NetworkEvent action) throws RemoteException { for (IClientCallback cb : clients.values()) { cb.onAction(action); } } + + + /** + * Sends a model game to all RMI clients. + * @param model The desired model + */ public void notifyAll(Game model) throws RemoteException { for (IClientCallback cb : clients.values()) { cb.onGameInit(model); @@ -86,14 +133,16 @@ public class RMIServer implements IGameServer { - - // Metodi per avviare server RMI + /** + * Starts the RMI server. + * @return true if the server starts successfully, false otherwise + */ public boolean start() { try { registry = LocateRegistry.createRegistry(nPort); registry.rebind("RMIGameServer", this); - System.out.println("RMI Server avviato sulla porta "+nPort); + System.out.println("RMI Server started on port: "+nPort); return true; } catch (Exception e) { @@ -101,6 +150,12 @@ public class RMIServer implements IGameServer { return false; } } + + + /** + * Stops the RMI server. + * @return true if the server stops successfully, false otherwise + */ public boolean stop() { try { registry.unbind("RMIGameServer");