Coverage Summary for Class: ModelWrapper (it.polimi.ingsw.Model)
| Class | Method, % | Branch, % | Line, % |
|---|---|---|---|
| ModelWrapper | 83,3% (5/6) | 75% (3/4) | 81,8% (18/22) |
| ModelWrapper$ModelModifier | |||
| Total | 83,3% (5/6) | 75% (3/4) | 81,8% (18/22) |
1 package it.polimi.ingsw.Model; 2 3 import it.polimi.ingsw.Misc.OptionalValue; 4 import it.polimi.ingsw.Server.Lobby; 5 import it.polimi.ingsw.Server.Messages.Events.Internal.GameOverEvent; 6 import it.polimi.ingsw.Server.Messages.Events.Internal.ModelUpdateEvent; 7 8 import java.util.Objects; 9 10 /** 11 * This class is used by the controller to enact the game logic and (optionally) notifies the view (ie the server) 12 * whenever a meaningful change to the underlying data is carried out. 13 */ 14 public class ModelWrapper { 15 private final OptionalValue<Lobby> toNotify; 16 private Model model; 17 18 /** 19 * Wraps a {@link Model} along with a {@link OptionalValue}<{@link Lobby}> object to allow for easy notification 20 * to the view (ie the lobby component) of any and all changes to the model that are carried through this object's method: 21 * {@link #editModel(ModelModifier, boolean)} 22 * 23 * @param model a non null reference to the Model 24 * @param lobby a non null optional value (can obviously be empty, but not null) 25 */ 26 public ModelWrapper(Model model, OptionalValue<Lobby> lobby) { 27 Objects.requireNonNull(model); 28 Objects.requireNonNull(lobby); 29 30 this.model = model; 31 this.toNotify = lobby; 32 notifyLobby(); 33 } 34 35 /** 36 * When called, notifies all clients connected to the lobby of a {@link ModelUpdateEvent} and also (if necessary) 37 * of a {@link GameOverEvent} 38 */ 39 private void notifyLobby() { 40 this.toNotify.ifPresent(lobby -> { 41 lobby.notifyPlayers(new ModelUpdateEvent(this.modelCopy(true))); 42 this.model.getWinners().ifPresent(winners -> 43 lobby.notifyPlayers(new GameOverEvent(winners.stream() 44 .map(PlayerBoard::getNickname) 45 .toList()))); 46 }); 47 } 48 49 /** 50 * When called, returns a copy of the Model object 51 * 52 * @param sanitize if set to true, tells the method to remove the {@link StudentBag} reference to prevent 53 * peeking at the contents of the bag 54 * @return an optionally sanitized clone of the wrapped {@link Model} object 55 */ 56 public Model modelCopy(boolean sanitize) { 57 Model copy = model.copy(); 58 if (sanitize) { 59 copy.getMutableStudentBag().removeContentReference(); 60 } 61 return copy; 62 } 63 64 /** 65 * When called, allows a {@link ModelModifier} type of function to carry out changes to the {@link Model}, then notifies 66 * the lobby of such changes 67 * 68 * @param modelModifier a function or method that can be linked to the {@link ModelModifier} interface 69 * @param keepUnsafeReference if set to true, the model reference is kept unaltered after a successful edit action, allowing for 70 * debugging introspection of the model. If unsure, set it to false for best security. 71 * @throws Exception the modelModifier can optionally throw Exceptions, which will be escalated to the caller. 72 */ 73 public void editModel(ModelModifier modelModifier, boolean keepUnsafeReference) throws Exception { 74 Model toModify; 75 if (keepUnsafeReference) { 76 toModify = this.model; 77 } else { 78 toModify = modelCopy(false); 79 } 80 modelModifier.modifyModel(toModify); 81 this.model = toModify; 82 notifyLobby(); 83 } 84 85 /** 86 * An interface that covers methods trying to access the Model. Read {@link #modifyModel(Model)} for more information 87 */ 88 public interface ModelModifier { 89 /** 90 * The function responsible for changes to the {@link Model} 91 * 92 * @param model a reference to the {@link Model} object. In order to grant safe access to the model, the reference ceases to hold 93 * meaning once this function terminates 94 * @throws Exception the modelModifier can optionally throw Exceptions, which will be escalated to the caller. 95 */ 96 void modifyModel(Model model) throws Exception; 97 } 98 }