diff --git a/.gitignore b/.gitignore index 60a3681..70cdfab 100644 --- a/.gitignore +++ b/.gitignore @@ -54,3 +54,6 @@ failsafe-reports/ # ===== Coverage tools ===== coverage/ jacoco.exec + +# ====== Stock data files ======= # +.txt \ No newline at end of file diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java index e93f779..f7876a5 100644 --- a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/Main.java @@ -3,11 +3,21 @@ import edu.ntnu.idi.idatt2003.g40.mappe.model.Stock; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileConverter; import edu.ntnu.idi.idatt2003.g40.mappe.service.FileParser; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.utils.ConfigValues; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager; +import edu.ntnu.idi.idatt2003.g40.mappe.view.ingame.InGameView; +import edu.ntnu.idi.idatt2003.g40.mappe.view.mainmenu.MainMenuController; +import edu.ntnu.idi.idatt2003.g40.mappe.view.mainmenu.MainMenuView; import javafx.application.Application; +import javafx.scene.Node; +import javafx.scene.Scene; +import javafx.scene.layout.Pane; import javafx.stage.Stage; import java.io.IOException; import java.util.List; +import java.util.Objects; public class Main extends Application { static void main() { @@ -24,6 +34,24 @@ static void main() { @Override public void start(final Stage stage) throws Exception { + Scene scene = new Scene(new Pane()); + scene.getStylesheets() + .add(Objects.requireNonNull(getClass().getResource("/styles.css")).toExternalForm()); + stage.setScene(scene); + stage.setWidth(ConfigValues.VIEWPORT_WIDTH.getValue()); + stage.setHeight(ConfigValues.VIEWPORT_HEIGHT.getValue()); + EventManager eventManager = new EventManager(); + ViewManager viewManager = new ViewManager(stage, eventManager); + MainMenuView mainMenuView = new MainMenuView(); + new MainMenuController(mainMenuView, eventManager); + + InGameView inGameView = new InGameView(); + + + viewManager.addView(mainMenuView); + viewManager.addView(inGameView); + viewManager.setScene(mainMenuView); + stage.show(); } } diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventData.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventData.java new file mode 100644 index 0000000..70465f6 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventData.java @@ -0,0 +1,13 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.service.event; + +/** + * Data object sent through the event system by the {@link EventManager}. + * + * @param the type of data this object represents. + * @param eventType the event type this object represents. + * @param data the data this object contains. + * + */ +public record EventData(EventType eventType, T data) { + +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java new file mode 100644 index 0000000..a2bf1b5 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventManager.java @@ -0,0 +1,57 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.service.event; + +import java.util.ArrayList; +import java.util.EnumMap; +import java.util.List; +import java.util.Map; + +/** + * Event broker in the pub/sub model. + * + *

Read more about pub/sub + * + * Here + * + *

+ * + * @see EventSubscriber + * @see EventPublisher + * + */ +public final class EventManager { + + /** + * Map where key is {@link EventType} and value is list of {@link EventSubscriber} objects. + * + *

Used to identify which subscribers to fire the event towards.

+ * + */ + private final Map> subscriberMap = + new EnumMap<>(EventType.class); + + /** + * Method for adding a subscriber to the subscriber map given an event type. + * + * @param subscriber the {@link EventSubscriber} object to add. + * @param eventType the {@link EventType} this subscriber should subscribe to. + * + * + */ + public void addSubscriber(final EventSubscriber subscriber, final EventType eventType) { + subscriberMap.computeIfAbsent(eventType, k -> new ArrayList<>()).add(subscriber); + } + + /** + * Method for invoking event to all subscriber of that type. + * + * @param the type of event data to send. + * @param data the data to send. + * + * + */ + public void invokeEvent(final EventData data) { + for (EventSubscriber e : subscriberMap.get(data.eventType())) { + e.handleEvent(data); + } + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventPublisher.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventPublisher.java new file mode 100644 index 0000000..a26b85c --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventPublisher.java @@ -0,0 +1,20 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.service.event; + +/** + * Interface representing a publisher in the pub/sub model (observer pattern). + * + * @see EventManager + * @see EventSubscriber + */ +public interface EventPublisher { + + /** + * Method for triggering (invoking) the event. + * + * @param the type of event data to invoke. + * @param data the data to invoke. + * @param eventManager the {@link EventManager} object to use as broker when invoking event. + */ + void invoke(EventData data, EventManager eventManager); +} + diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventSubscriber.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventSubscriber.java new file mode 100644 index 0000000..69645d7 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventSubscriber.java @@ -0,0 +1,18 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.service.event; + +/** + * Interface representing a subscriber in a pub/sub model. + * + * @see EventManager + * @see EventSubscriber + */ +public interface EventSubscriber { + + /** + * Method for handling the event subscribed to. + * + * @param the type of event data to handle. + * @param data the actual data to handle. + */ + void handleEvent(EventData data); +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java new file mode 100644 index 0000000..52a60b9 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/service/event/EventType.java @@ -0,0 +1,38 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.service.event; + +/** + * Enum representing different event types. + * + *

Examples:

+ *
    + *
  • Scene changes
  • + *
  • Database operations
  • + *
  • Other
  • + *
+ * + * + */ +public enum EventType { + + /** + * Event type representing events that causes the current scene to change. + * + *

Primarily handled by the active + * {@link edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager} object.

+ * + * @see edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager + * + */ + SCENE_CHANGE, + + /** + * Event type representing events that causes the scene to change to the previous one. + * + *

Primarily handled by the active + * {@link edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager} object.

+ * + * @see edu.ntnu.idi.idatt2003.g40.mappe.view.ViewManager + * + */ + SCENE_BACK, +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/ConfigValues.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/ConfigValues.java new file mode 100644 index 0000000..0af1843 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/utils/ConfigValues.java @@ -0,0 +1,16 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.utils; + +public enum ConfigValues { + VIEWPORT_WIDTH(600), + VIEWPORT_HEIGHT(600); + + private int value; + + ConfigValues(final int value) { + this.value = value; + } + + public int getValue() { + return value; + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewController.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewController.java new file mode 100644 index 0000000..5d7a7c0 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewController.java @@ -0,0 +1,77 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view; + +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventManager; +import edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventPublisher; + +/** + * Handles logic and event publishing for {@link ViewElement} objects. + * + *

Implements {@link EventPublisher}

+ * + * @param The type of {@link ViewElement} this controller is attached to. We use generics + * because we want to call methods that may be specific for certain view element + * objects, and we want to reduce casting. + * @see ViewElement + * @see EventPublisher + * @see EventManager + * + */ +public abstract class ViewController> + implements EventPublisher { + + /** + * The {@link ViewElement} object this controller is associated with. + * + */ + private final T1 viewElement; + /** + * The {@link EventManager} object to send events to. + * + */ + private final EventManager eventManager; + + /** + * Constructor. + * + * @param viewElement the instance of type T1 this controller is attached to. + * @param eventManager the {@link EventManager} object this controller communicates with. + * + */ + protected ViewController(final T1 viewElement, final EventManager eventManager) { + this.viewElement = viewElement; + this.eventManager = eventManager; + initInteractions(); + } + + /** + * Getter method for the event manager. + * + * @return the {@link EventManager} object. + * + */ + protected EventManager getEventManager() { + return eventManager; + } + + /** + * Getter method for the current view element. + * + * @return the {@link ViewElement} object. + * + */ + public T1 getViewElement() { + return viewElement; + } + + /** + * Abstract method to initialize logic for the view element. + * + */ + protected abstract void initInteractions(); + + @Override + public final void invoke(final EventData data, final EventManager eventManager) { + eventManager.invokeEvent(data); + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewData.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewData.java new file mode 100644 index 0000000..06dbdfc --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewData.java @@ -0,0 +1,39 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view; + +/** + * Object containing data about {@link ViewElement} objects. + * + *

Sent in {@link edu.ntnu.idi.idatt2003.g40.mappe.service.event.EventData} + * objects of type SCENE_CHANGE

+ * + *

Handled by the {@link ViewManager} to update and change views

+ * + */ +public class ViewData { + + /** + * Name of the scene. + * + */ + private final String sceneName; + + /** + * Constructor. + * + * @param sceneName the name of the scene. + * + */ + public ViewData(final String sceneName) { + this.sceneName = sceneName; + } + + /** + * Getter method for the scene name. + * + * @return scene name. + * + */ + public String getSceneName() { + return sceneName; + } +} diff --git a/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java new file mode 100644 index 0000000..fec4af4 --- /dev/null +++ b/src/main/java/edu/ntnu/idi/idatt2003/g40/mappe/view/ViewElement.java @@ -0,0 +1,155 @@ +package edu.ntnu.idi.idatt2003.g40.mappe.view; + + +import javafx.scene.control.Button; +import javafx.scene.layout.Pane; +import java.util.ArrayList; + +/** + * Base class for view elements, such as the main menu, or list items. + * + *

Extends {@link Pane}

+ * + * @param the type of pane this view element represents. + * + */ +public abstract class ViewElement { + + /** + * List of buttons in this view. + * + */ + private final ArrayList