Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow objects to listen for changes to the equipment list #6391

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion megamek/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,20 @@ plugins {
id 'jacoco'
id 'java'
id 'org.ec4j.editorconfig' version '0.1.0'

id 'org.openjfx.javafxplugin' version '0.1.0'
}

java {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}

javafx {
// Version 23 requires JDK 21
version = "22.0.2"
modules = [ 'javafx.base' ]
}

sourceSets {
main {
java {
Expand Down
59 changes: 58 additions & 1 deletion megamek/src/megamek/common/Entity.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
package megamek.common;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import megamek.MMConstants;
import megamek.client.bot.princess.FireControl;
import megamek.client.ui.Base64Image;
Expand Down Expand Up @@ -50,6 +53,10 @@
import megamek.utilities.xml.MMXMLUtility;

import java.awt.*;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serial;
import java.math.BigInteger;
import java.util.List;
import java.util.*;
Expand Down Expand Up @@ -453,7 +460,7 @@ public enum InvalidSourceBuildReason {
/**
* A list of all mounted equipment. (Weapons, ammo, and misc)
*/
protected List<Mounted<?>> equipmentList = new ArrayList<>();
protected transient ObservableList<Mounted<?>> equipmentList = FXCollections.observableArrayList();

/**
* A list of all mounted weapons. This only includes regular weapons, not
Expand Down Expand Up @@ -15846,4 +15853,54 @@ public boolean canonUnitWithInvalidBuild() {
return false;
}

private final List<ListChangeListener<Mounted<?>>> equipmentListeners = new ArrayList<>();

/**
* Adds a listener to this entity's equipment list
* @param listener an object which will be informed when the entity's equipment changes
*/
public void addEquipmentChangedListener(ListChangeListener<Mounted<?>> listener) {
equipmentList.addListener(listener);
equipmentListeners.add(listener);
}

/**
* Removes a listener from this entity's equipment list
* @param listener the listener to rmove
*/
public void removeEquipmentChangedListener(ListChangeListener<Mounted<?>> listener) {
equipmentList.removeListener(listener);
equipmentListeners.remove(listener);
}

/**
* Replaces any existing equipment listeners with a new one.
* Only listeners of the exact same class of the listener are replaced.
* This can help prevent memory leaks, if a listening object is no longer needed it will be removed from the list of listeners by the replacing object.
* @param listener The new listener to add.
*/
public void replaceEquipmentChangedListener(ListChangeListener<Mounted<?>> listener) {
for (Iterator<ListChangeListener<Mounted<?>>> iterator = equipmentListeners.iterator(); iterator.hasNext(); ) {
var existing = iterator.next();
if (listener.getClass().equals(existing.getClass())) {
equipmentList.removeListener(existing);
iterator.remove();
}
}

equipmentList.addListener(listener);
equipmentListeners.add(listener);
}

@Serial
private void writeObject(ObjectOutputStream out) throws IOException {
out.defaultWriteObject();
out.writeObject(new ArrayList<>(equipmentList));
}

@Serial
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
equipmentList = FXCollections.observableArrayList((ArrayList<Mounted<?>>) in.readObject());
}
}
Loading