mirror of
https://github.com/praktimarc/kst4contest.git
synced 2026-04-03 06:25:44 +02:00
Compare commits
2 Commits
main
...
fix-crash-
| Author | SHA1 | Date | |
|---|---|---|---|
| ced79fefd2 | |||
| c7311a5966 |
@@ -1,2 +0,0 @@
|
|||||||
dr2x
|
|
||||||
oe3cin
|
|
||||||
15832
bugsept24.txt
15832
bugsept24.txt
File diff suppressed because it is too large
Load Diff
@@ -23,6 +23,7 @@ import kst4contest.locatorUtils.DirectionUtils;
|
|||||||
import kst4contest.logic.PriorityCalculator;
|
import kst4contest.logic.PriorityCalculator;
|
||||||
import kst4contest.model.*;
|
import kst4contest.model.*;
|
||||||
import kst4contest.test.MockKstServer;
|
import kst4contest.test.MockKstServer;
|
||||||
|
import kst4contest.utils.BoundedDequeObservableList;
|
||||||
import kst4contest.utils.PlayAudioUtils;
|
import kst4contest.utils.PlayAudioUtils;
|
||||||
import kst4contest.view.Kst4ContestApplication;
|
import kst4contest.view.Kst4ContestApplication;
|
||||||
|
|
||||||
@@ -1007,7 +1008,8 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
|
|||||||
// ******All abstract types below here are used by the messageprocessor!
|
// ******All abstract types below here are used by the messageprocessor!
|
||||||
// ***************
|
// ***************
|
||||||
|
|
||||||
private ObservableList<ChatMessage> lst_globalChatMessageList = FXCollections.observableArrayList(); //All chatmessages will be put in there, later create filtered message lists
|
private static final int MAX_CHAT_MESSAGES = 10000;
|
||||||
|
private final BoundedDequeObservableList<ChatMessage> lst_globalChatMessageList = new BoundedDequeObservableList<>(MAX_CHAT_MESSAGES); //All chatmessages will be put in there, later create filtered message lists
|
||||||
// private ObservableList<ChatMessage> lst_toAllMessageList = FXCollections.observableArrayList(); // directed to all
|
// private ObservableList<ChatMessage> lst_toAllMessageList = FXCollections.observableArrayList(); // directed to all
|
||||||
// (beacon)
|
// (beacon)
|
||||||
private FilteredList<ChatMessage> lst_toAllMessageList = new FilteredList<>(lst_globalChatMessageList); // directed to all
|
private FilteredList<ChatMessage> lst_toAllMessageList = new FilteredList<>(lst_globalChatMessageList); // directed to all
|
||||||
@@ -1152,13 +1154,14 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList
|
|||||||
this.lst_selectedCallSignInfofilteredMessageList = lst_selectedCallSignInfofilteredMessageList;
|
this.lst_selectedCallSignInfofilteredMessageList = lst_selectedCallSignInfofilteredMessageList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addChatMessage(ChatMessage message) {
|
||||||
|
lst_globalChatMessageList.addFirst(message);
|
||||||
|
}
|
||||||
|
|
||||||
public ObservableList<ChatMessage> getLst_globalChatMessageList() {
|
public ObservableList<ChatMessage> getLst_globalChatMessageList() {
|
||||||
return lst_globalChatMessageList;
|
return lst_globalChatMessageList;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLst_globalChatMessageList(ObservableList<ChatMessage> lst_globalChatMessageList) {
|
|
||||||
this.lst_globalChatMessageList = lst_globalChatMessageList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
|
|||||||
@@ -772,7 +772,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
dummy.setCallSign("ALL");
|
dummy.setCallSign("ALL");
|
||||||
newMessageArrived.setReceiver(dummy);
|
newMessageArrived.setReceiver(dummy);
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived); // sdtout to all message-List
|
this.client.addChatMessage(newMessageArrived); // sdtout to all message-List
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//message is directed to another chatmember, process as such!
|
//message is directed to another chatmember, process as such!
|
||||||
@@ -817,7 +817,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
if (newMessageArrived.getReceiver().getCallSign()
|
if (newMessageArrived.getReceiver().getCallSign()
|
||||||
.equals(this.client.getChatPreferences().getStn_loginCallSign())) {
|
.equals(this.client.getChatPreferences().getStn_loginCallSign())) {
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
|
|
||||||
if (this.client.getChatPreferences().isNotify_playSimpleSounds()) {
|
if (this.client.getChatPreferences().isNotify_playSimpleSounds()) {
|
||||||
this.client.getPlayAudioUtils().playNoiseLauncher('P');
|
this.client.getPlayAudioUtils().playNoiseLauncher('P');
|
||||||
@@ -960,7 +960,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
String originalMessage = newMessageArrived.getMessageText();
|
String originalMessage = newMessageArrived.getMessageText();
|
||||||
newMessageArrived
|
newMessageArrived
|
||||||
.setMessageText("(>" + newMessageArrived.getReceiver().getCallSign() + ")" + originalMessage);
|
.setMessageText("(>" + newMessageArrived.getReceiver().getCallSign() + ")" + originalMessage);
|
||||||
this.client.getLst_globalChatMessageList().add(0,newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
|
|
||||||
// if you sent the message to another station, it will be sorted in to
|
// if you sent the message to another station, it will be sorted in to
|
||||||
// the "to me message list" with modified messagetext, added rxers callsign
|
// the "to me message list" with modified messagetext, added rxers callsign
|
||||||
@@ -1024,7 +1024,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
newMessageArrived.getSender().setInAngleAndRange(false);
|
newMessageArrived.getSender().setInAngleAndRange(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
|
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
|
||||||
}
|
}
|
||||||
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
|
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
|
||||||
@@ -1364,7 +1364,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
dummy.setCallSign("ALL");
|
dummy.setCallSign("ALL");
|
||||||
newMessageArrived.setReceiver(dummy);
|
newMessageArrived.setReceiver(dummy);
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived); // sdtout to all message-List
|
this.client.addChatMessage(newMessageArrived); // sdtout to all message-List
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
//message is directed to another chatmember, process as such!
|
//message is directed to another chatmember, process as such!
|
||||||
@@ -1408,7 +1408,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
if (newMessageArrived.getReceiver().getCallSign()
|
if (newMessageArrived.getReceiver().getCallSign()
|
||||||
.equals(this.client.getChatPreferences().getStn_loginCallSign())) {
|
.equals(this.client.getChatPreferences().getStn_loginCallSign())) {
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
|
|
||||||
System.out.println("Historic message directed to me: " + newMessageArrived.getReceiver().getCallSign() + ".");
|
System.out.println("Historic message directed to me: " + newMessageArrived.getReceiver().getCallSign() + ".");
|
||||||
|
|
||||||
@@ -1421,7 +1421,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
String originalMessage = newMessageArrived.getMessageText();
|
String originalMessage = newMessageArrived.getMessageText();
|
||||||
newMessageArrived
|
newMessageArrived
|
||||||
.setMessageText("(>" + newMessageArrived.getReceiver().getCallSign() + ")" + originalMessage);
|
.setMessageText("(>" + newMessageArrived.getReceiver().getCallSign() + ")" + originalMessage);
|
||||||
this.client.getLst_globalChatMessageList().add(0,newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
|
|
||||||
// if you sent the message to another station, it will be sorted in to
|
// if you sent the message to another station, it will be sorted in to
|
||||||
// the "to me message list" with modified messagetext, added rxers callsign
|
// the "to me message list" with modified messagetext, added rxers callsign
|
||||||
@@ -1441,7 +1441,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
newMessageArrived.getSender().setInAngleAndRange(false);
|
newMessageArrived.getSender().setInAngleAndRange(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.client.getLst_globalChatMessageList().add(0, newMessageArrived);
|
this.client.addChatMessage(newMessageArrived);
|
||||||
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
|
// System.out.println("MSGBS bgfx: tx call = " + newMessageArrived.getSender().getCallSign() + " / rx call = " + newMessageArrived.getReceiver().getCallSign());
|
||||||
}
|
}
|
||||||
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
|
} catch (NullPointerException referenceDeletedByUserLeftChatDuringMessageprocessing) {
|
||||||
@@ -1514,7 +1514,7 @@ public class MessageBusManagementThread extends Thread {
|
|||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < 10; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
client.getLst_globalChatMessageList().add(pwErrorMsg);
|
client.addChatMessage(pwErrorMsg);
|
||||||
// client.getLst_toMeMessageList().add(pwErrorMsg);
|
// client.getLst_toMeMessageList().add(pwErrorMsg);
|
||||||
// client.getLst_toAllMessageList().add(pwErrorMsg);
|
// client.getLst_toAllMessageList().add(pwErrorMsg);
|
||||||
}
|
}
|
||||||
|
|||||||
168
src/main/java/kst4contest/utils/BoundedDequeObservableList.java
Normal file
168
src/main/java/kst4contest/utils/BoundedDequeObservableList.java
Normal file
@@ -0,0 +1,168 @@
|
|||||||
|
package kst4contest.utils;
|
||||||
|
|
||||||
|
import javafx.collections.ObservableListBase;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bounded ObservableList backed by a circular buffer (ring buffer).
|
||||||
|
* <p>
|
||||||
|
* Provides O(1) {@link #addFirst} and {@link #addLast} as well as O(1)
|
||||||
|
* random access via {@link #get}. When the list reaches {@code maxCapacity},
|
||||||
|
* adding a new element at the front automatically evicts the oldest element
|
||||||
|
* at the back — and vice versa.
|
||||||
|
* <p>
|
||||||
|
* This is a drop-in replacement for {@code FXCollections.observableArrayList()}
|
||||||
|
* wherever elements are prepended frequently, e.g. chat message lists.
|
||||||
|
*/
|
||||||
|
public class BoundedDequeObservableList<E> extends ObservableListBase<E> {
|
||||||
|
|
||||||
|
private final int maxCapacity;
|
||||||
|
private final Object[] elements;
|
||||||
|
private int head = 0;
|
||||||
|
private int size = 0;
|
||||||
|
|
||||||
|
public BoundedDequeObservableList(int maxCapacity) {
|
||||||
|
if (maxCapacity <= 0) throw new IllegalArgumentException("maxCapacity must be > 0");
|
||||||
|
this.maxCapacity = maxCapacity;
|
||||||
|
this.elements = new Object[maxCapacity];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── read access ──────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int size() {
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public E get(int index) {
|
||||||
|
checkIndex(index);
|
||||||
|
return (E) elements[physicalIndex(index)];
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── O(1) deque operations ─────────────────────────────────────────────────
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts {@code element} at index 0 (newest-first order).
|
||||||
|
* If the list is already at capacity the oldest element (last index) is
|
||||||
|
* removed first — both changes are reported as a single compound change.
|
||||||
|
*/
|
||||||
|
public void addFirst(E element) {
|
||||||
|
beginChange();
|
||||||
|
if (size == maxCapacity) {
|
||||||
|
// evict last element
|
||||||
|
int lastPhysical = physicalIndex(size - 1);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
E evicted = (E) elements[lastPhysical];
|
||||||
|
elements[lastPhysical] = null;
|
||||||
|
size--;
|
||||||
|
nextRemove(size, evicted); // index after decrement == old last index
|
||||||
|
}
|
||||||
|
head = (head - 1 + maxCapacity) % maxCapacity;
|
||||||
|
elements[head] = element;
|
||||||
|
size++;
|
||||||
|
nextAdd(0, 1);
|
||||||
|
endChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Appends {@code element} at the last index (oldest-first order).
|
||||||
|
* If the list is already at capacity the newest element (index 0) is
|
||||||
|
* removed first.
|
||||||
|
*/
|
||||||
|
public void addLast(E element) {
|
||||||
|
beginChange();
|
||||||
|
if (size == maxCapacity) {
|
||||||
|
// evict first element
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
E evicted = (E) elements[head];
|
||||||
|
elements[head] = null;
|
||||||
|
head = (head + 1) % maxCapacity;
|
||||||
|
size--;
|
||||||
|
nextRemove(0, evicted);
|
||||||
|
}
|
||||||
|
elements[physicalIndex(size)] = element;
|
||||||
|
size++;
|
||||||
|
nextAdd(size - 1, size);
|
||||||
|
endChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── standard List mutation (O(n) — use addFirst/addLast for hot path) ─────
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(int index, E element) {
|
||||||
|
if (index == 0) {
|
||||||
|
addFirst(element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (index == size) {
|
||||||
|
addLast(element);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
checkIndexForAdd(index);
|
||||||
|
beginChange();
|
||||||
|
if (size == maxCapacity) {
|
||||||
|
int lastPhysical = physicalIndex(size - 1);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
E evicted = (E) elements[lastPhysical];
|
||||||
|
elements[lastPhysical] = null;
|
||||||
|
size--;
|
||||||
|
nextRemove(size, evicted);
|
||||||
|
}
|
||||||
|
// shift elements [index .. size-1] one position towards the end
|
||||||
|
for (int i = size; i > index; i--) {
|
||||||
|
elements[physicalIndex(i)] = elements[physicalIndex(i - 1)];
|
||||||
|
}
|
||||||
|
elements[physicalIndex(index)] = element;
|
||||||
|
size++;
|
||||||
|
nextAdd(index, index + 1);
|
||||||
|
endChange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E remove(int index) {
|
||||||
|
checkIndex(index);
|
||||||
|
beginChange();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
E removed = (E) elements[physicalIndex(index)];
|
||||||
|
// shift elements [index+1 .. size-1] one position towards the front
|
||||||
|
for (int i = index; i < size - 1; i++) {
|
||||||
|
elements[physicalIndex(i)] = elements[physicalIndex(i + 1)];
|
||||||
|
}
|
||||||
|
elements[physicalIndex(size - 1)] = null;
|
||||||
|
size--;
|
||||||
|
nextRemove(index, removed);
|
||||||
|
endChange();
|
||||||
|
return removed;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public E set(int index, E element) {
|
||||||
|
checkIndex(index);
|
||||||
|
beginChange();
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
E old = (E) elements[physicalIndex(index)];
|
||||||
|
elements[physicalIndex(index)] = element;
|
||||||
|
nextSet(index, old);
|
||||||
|
endChange();
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── helpers ───────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
private int physicalIndex(int virtualIndex) {
|
||||||
|
return (head + virtualIndex) % maxCapacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIndex(int index) {
|
||||||
|
if (index < 0 || index >= size)
|
||||||
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIndexForAdd(int index) {
|
||||||
|
if (index < 0 || index > size)
|
||||||
|
throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
|
||||||
|
}
|
||||||
|
}
|
||||||
1783
udpReaderBackup.txt
1783
udpReaderBackup.txt
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user