Skip to content

Commit

Permalink
Merge pull request #25 from Zmax0/dev/2.4.4.1
Browse files Browse the repository at this point in the history
2.4.4.1
  • Loading branch information
Zmax0 committed Jun 11, 2024
2 parents 1170da0 + 8167dda commit ed8ace7
Show file tree
Hide file tree
Showing 6 changed files with 180 additions and 24 deletions.
24 changes: 9 additions & 15 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<urban-spork.version>2.4.4</urban-spork.version>
<maven-surefire-plugin.versioin>3.2.3</maven-surefire-plugin.versioin>
<maven-jar-plugin.version>3.3.0</maven-jar-plugin.version>
<maven-compiler-plugin.version>3.12.1</maven-compiler-plugin.version>
<jacoco-maven-plugin.version>0.8.11</jacoco-maven-plugin.version>
<build-helper-maven-plugin.version>3.5.0</build-helper-maven-plugin.version>
<junit.jupiter.version>5.10.1</junit.jupiter.version>
<jackson.version>2.16.1</jackson.version>
<logback.version>1.4.14</logback.version>
<netty.version>4.1.104.Final</netty.version>
<maven-surefire-plugin.versioin>3.2.5</maven-surefire-plugin.versioin>
<maven-jar-plugin.version>3.4.1</maven-jar-plugin.version>
<maven-compiler-plugin.version>3.13.0</maven-compiler-plugin.version>
<jacoco-maven-plugin.version>0.8.12</jacoco-maven-plugin.version>
<junit.jupiter.version>5.10.2</junit.jupiter.version>
<jackson.version>2.17.1</jackson.version>
<logback.version>1.5.6</logback.version>
<netty.version>4.1.110.Final</netty.version>
<bouncycastle.version>2.73.6</bouncycastle.version>
<javafx.version>21.0.1</javafx.version>
<javafx.version>22.0.1</javafx.version>
<jfoenix.version>9.0.10</jfoenix.version>
</properties>
<dependencyManagement>
Expand Down Expand Up @@ -133,11 +132,6 @@
<artifactId>jacoco-maven-plugin</artifactId>
<version>${jacoco-maven-plugin.version}</version>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>${build-helper-maven-plugin.version}</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
Expand Down
8 changes: 6 additions & 2 deletions urban-spork-client-gui/resource/console.css
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,8 @@ GridPane {
-fx-background-color: #000;
}

.chart-series-line {
-fx-stroke-width: 2;
.chart {
-fx-max-height: 250;
}

.chart-legend {
Expand All @@ -167,6 +167,10 @@ GridPane {
-fx-background-color: transparent;
}

.chart-series-line {
-fx-stroke-width: 2;
}

.default-color0.chart-series-line {
-fx-stroke: #0a84ff;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -332,8 +333,8 @@ private JFXTabPane initTabPane() {
tab0.setClosable(false);
// tab1
Tab tab1 = newSingleNodeTab(logTextArea, I18N.getString(I18N.CONSOLE_TAB1_TEXT));
//
Tab tab2 = newSingleNodeTab(new TrafficCounterLineChart(instance).init(), I18N.getString(I18N.CONSOLE_TAB2_TEXT));
// tab2
Tab tab2 = initTrafficTab();
// ====================
// main tab pane
// ====================
Expand Down Expand Up @@ -375,6 +376,16 @@ private Tab newSingleNodeTab(Node node, String tabTitle) {
return tab;
}

private Tab initTrafficTab() {
StackPane stackPane = new StackPane();
stackPane.setAlignment(Pos.TOP_CENTER);
stackPane.getChildren().add(new TrafficCounterLineChart(instance).init());
Tab tab = new Tab(I18N.getString(I18N.CONSOLE_TAB2_TEXT));
tab.setContent(stackPane);
tab.setClosable(false);
return tab;
}

private void addGridPane0Children(GridPane gridPane0) {
// ---------- Grid Children ----------
gridPane0.add(wrap(moveUpServerConfigButton), 1, 13);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
package com.urbanspork.client.gui.spine;

import javafx.geometry.Point2D;

/**
* Java implement of <a href="https://en.wikipedia.org/wiki/Centripetal_Catmull–Rom_spline">Centripetal Catmull–Rom spline</a>
*
* @param alpha The alpha value ranges from 0 to 1
* <ul>
* <li>0.5 for the centripetal spline
* <li>0.0 for the uniform spline
* <li>1.0 for the chordal spline
* </ul>
* @author Zmax0
*/
public record CatmullRom(double alpha) {
/**
* Calculate Catmull-Rom for a sequence of initial points and return the combined curve.
*
* @param points Base points from which the quadruples for the algorithm are taken
* @param segment The number of points include in each curve segment
* @return The combined curve
*/
public Point2D[] interpolate(Point2D[] points, int segment) {
if (points.length < 2) {
throw new IllegalArgumentException("The points parameter must be greater than 2");
}
if (points.length < 3) {
return points;
}
Point2D[] controls = getControls(points);
Point2D[] curve = new Point2D[points.length + (points.length - 1) * segment];
for (int i = 0; i < controls.length - 3; i++) {
curve[i * (segment + 1)] = controls[i + 1];
Point2D[] temp = interpolate(controls[i], controls[i + 1], controls[i + 2], controls[i + 3], segment);
System.arraycopy(temp, 0, curve, i * (segment + 1) + 1, segment);
}
curve[curve.length - 1] = (controls[controls.length - 2]); // last
return curve;
}

private Point2D[] getControls(Point2D[] point) {
Point2D[] controls = new Point2D[point.length + 2];
System.arraycopy(point, 0, controls, 1, point.length);
// set two control points at start C1 and end C2
if (point[0].equals(point[point.length - 1])) { // if is close
// C1 = P(n-1)
controls[0] = point[point.length - 2];
// C2 = P1
controls[controls.length - 1] = point[1];
} else {
// C1 = P0 - (P1 - P0)
controls[0] = point[0].subtract(point[1].subtract(point[0]));
// C2 = Pn + (Pn - P(n-1))
controls[controls.length - 1] = point[point.length - 1].add(point[point.length - 1].subtract(point[point.length - 2]));
}
return controls;
}

/**
* Calculate Catmull-Rom spline curve points starts with p1 and ends with p2
*
* @param p0 The (x,y) point pairs that define the Catmull-Rom spline
* @param p1 The (x,y) point pairs that define the Catmull-Rom spline
* @param p2 The (x,y) point pairs that define the Catmull-Rom spline
* @param p3 The (x,y) point pairs that define the Catmull-Rom spline
* @param segment The number of points to include in each curve segment
* @return points for the resulting curve
*/
public Point2D[] interpolate(Point2D p0, Point2D p1, Point2D p2, Point2D p3, int segment) {
// calculate knots
double t0 = 0;
double t1 = getT(t0, p0, p1);
double t2 = getT(t1, p1, p2);
double t3 = getT(t2, p2, p3);
double step = (t2 - t1) / (segment - 1);
// evaluate the point
Point2D[] curve = new Point2D[segment];
curve[0] = p1;
for (int i = 1; i < segment - 1; i++) {
double t = t1 + i * step;
Point2D a1 = p0.multiply((t1 - t) / (t1 - t0)).add(p1.multiply((t - t0) / (t1 - t0)));
Point2D a2 = p1.multiply((t2 - t) / (t2 - t1)).add(p2.multiply((t - t1) / (t2 - t1)));
Point2D a3 = p2.multiply((t3 - t) / (t3 - t2)).add(p3.multiply((t - t2) / (t3 - t2)));
Point2D b1 = a1.multiply((t2 - t) / (t2 - t0)).add(a2.multiply((t - t0) / (t2 - t0)));
Point2D b2 = a2.multiply((t3 - t) / (t3 - t1)).add(a3.multiply((t - t1) / (t3 - t1)));
curve[i] = b1.multiply((t2 - t) / (t2 - t1)).add(b2.multiply((t - t1) / (t2 - t1)));
}
curve[curve.length - 1] = p2;
return curve;
}

// calculate knots
private double getT(double t, Point2D p0, Point2D p1) {
Point2D d = p1.subtract(p0);
return Math.pow(d.dotProduct(d), alpha * .5) + t;
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
package com.urbanspork.client.gui.traffic;

import com.urbanspork.client.Client;
import com.urbanspork.client.gui.spine.CatmullRom;
import io.netty.handler.traffic.TrafficCounter;
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.beans.property.ObjectProperty;
import javafx.collections.ObservableList;
import javafx.geometry.Point2D;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.PathElement;
import javafx.util.Duration;

public class TrafficCounterLineChart {
Expand All @@ -27,7 +32,52 @@ public TrafficCounterLineChart(ObjectProperty<Client.Instance> instance) {
public LineChart<Number, Number> init() {
NumberAxis xAxis = new NumberAxis(0, WINDOW, WINDOW);
NumberAxis yAxis = new NumberAxis();
LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis);
yAxis.setTickLabelsVisible(false);
yAxis.setTickMarkVisible(false);
yAxis.lookup(".axis-minor-tick-mark").setVisible(false);
LineChart<Number, Number> lineChart = new LineChart<>(xAxis, yAxis) {
@Override
protected void layoutPlotChildren() {
super.layoutPlotChildren();
ObservableList<Series<Number, Number>> data = getData();
data.stream().map(Series::getNode).<Path>mapMulti((node, consumer) -> {
if (node instanceof Path path) {
consumer.accept(path);
}
}).forEach(this::curve);
}

private void curve(Path path) {
ObservableList<PathElement> elements = path.getElements();
if (elements.size() > 3) {
curve(elements);
}
}

private void curve(ObservableList<PathElement> elements) {
int size = elements.size();
Point2D[] points = new Point2D[size - 1];
for (int i = 0; i < points.length; i++) {
PathElement e = elements.get(i + 1);
if (e instanceof LineTo lineTo) {
points[i] = new Point2D(lineTo.getX(), lineTo.getY());
}
}
Point2D[] interpolate = new CatmullRom(0.5).interpolate(points, 32);
// update
for (int i = 1; i < size; i++) {
PathElement e = elements.get(i);
if (e instanceof LineTo lineTo) {
lineTo.setX(interpolate[i - 1].getX());
lineTo.setY(interpolate[i - 1].getY());
}
}
// add
for (int i = 0; i < interpolate.length - size; i++) {
elements.add(new LineTo(interpolate[i + size].getX(), interpolate[i + size].getY()));
}
}
};
lineChart.setAnimated(false);
lineChart.setCreateSymbols(false);
ObservableList<XYChart.Series<Number, Number>> data = lineChart.getData();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
import io.netty.util.Timeout;

import java.time.Duration;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
Expand All @@ -16,7 +15,7 @@ public class LruCache<K, V> {
final Duration timeToLive;
final HashedWheelTimer timer = new HashedWheelTimer(1, TimeUnit.SECONDS);
final BiConsumer<K, V> afterExpired;
final Map<K, Pair<V>> inner = Collections.synchronizedMap(new LinkedHashMap<>() {
final Map<K, Pair<V>> inner = new LinkedHashMap<>() {
@Override
protected boolean removeEldestEntry(Map.Entry<K, Pair<V>> eldest) {
boolean flag = size() > capacity;
Expand All @@ -28,7 +27,7 @@ protected boolean removeEldestEntry(Map.Entry<K, Pair<V>> eldest) {
}
return flag;
}
});
};

public LruCache(long capacity, Duration timeToLive, BiConsumer<K, V> afterExpired) {
this.capacity = capacity;
Expand Down Expand Up @@ -73,7 +72,7 @@ public V remove(K key) {
}

public void release() {
for (Map.Entry<K, Pair<V>> entry : inner.entrySet()) {
for (Map.Entry<K, Pair<V>> entry : Map.copyOf(inner).entrySet()) {
afterExpired.accept(entry.getKey(), entry.getValue().value);
}
timer.stop();
Expand Down

0 comments on commit ed8ace7

Please sign in to comment.