From b40bb9beaad038fdb308783764eab437e6894ac3 Mon Sep 17 00:00:00 2001
From: brutzman <brutzman@nps.edu>
Date: Wed, 5 Jan 2022 20:12:19 -0800
Subject: [PATCH] sortPdus using Pdu comparator, reversePdus

---
 examples/src/OpenDis7Examples/PduTrack.java   | 61 +++++++++++++------
 .../PduTrackInterpolation.x3d                 |  4 +-
 examples/src/OpenDis7Examples/PduTrackLog.txt |  6 +-
 3 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/examples/src/OpenDis7Examples/PduTrack.java b/examples/src/OpenDis7Examples/PduTrack.java
index 38b2811fb3..1f134c9a21 100644
--- a/examples/src/OpenDis7Examples/PduTrack.java
+++ b/examples/src/OpenDis7Examples/PduTrack.java
@@ -43,6 +43,8 @@ import edu.nps.moves.dis7.pdus.Vector3Double;
 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Date;
 
 /**
@@ -58,10 +60,10 @@ public class PduTrack
     private Vector3Double  initialLocation;
     private Vector3Double   latestLocation;
     
+    /** waypoint timelineList in seconds */
+    private ArrayList<Float>       timelineList = new ArrayList<>();
     private ArrayList<Vector3Double> waypointsList = new ArrayList<>();
     private ArrayList<EulerAngles> eulerAnglesList = new ArrayList<>();
-    /** timelineList in seconds */
-    private ArrayList<Float>       timelineList = new ArrayList<>();
     
     private String                             author = new String();
     private String                 x3dModelIdentifier = new String();
@@ -160,6 +162,7 @@ public class PduTrack
         if (newPdu.getPduType() == DisPduType.ENTITY_STATE)
         {
             EntityStatePdu deepCopyEspdu = new EntityStatePdu();
+            deepCopyEspdu.setTimestamp         (((EntityStatePdu)newPdu).getTimestamp());
             deepCopyEspdu.setEntityID         (((EntityStatePdu)newPdu).getEntityID());
             deepCopyEspdu.setForceId          (((EntityStatePdu)newPdu).getForceId());
             deepCopyEspdu.setEntityType       (((EntityStatePdu)newPdu).getEntityType());
@@ -262,15 +265,39 @@ public class PduTrack
     }
 
     /**
-     * Sort all points by timestamp
+     * Sort all PDUs by timestamp
+     * @see <a href="https://stackoverflow.com/questions/16252269/how-to-sort-an-arraylist">StackOverflow: How to sort an ArrayList?</a>
+     * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/doc-files/coll-overview.html">Collections Framework Overview</a>
      * @return same object to permit progressive setters
      */
     public PduTrack sortPdus()
     {
-        // TODO
-        // https://stackoverflow.com/questions/16252269/how-to-sort-an-arraylist
+        Collections.sort(pduList, new Comparator<Pdu>() {
+            @Override
+            public int compare(Pdu lhs, Pdu rhs)
+            {
+                // -1 less than, 1 greater than, 0 equal
+                if      (lhs.occursBefore(rhs))
+                         return -1;
+                else if (lhs.occursSameTime(rhs))
+                         return 0;
+                else     return 1;
+            }
+        });
+        return this;
+    }
+    /**
+     * Reverse order of PDU list
+     * @see <a href="https://stackoverflow.com/questions/10766492/what-is-the-simplest-way-to-reverse-an-arraylist">StackOverflow: What is the Simplest Way to Reverse an ArrayList?</a>
+     * @see <a href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/doc-files/coll-overview.html">Collections Framework Overview</a>
+     * @return same object to permit progressive setters
+     */
+    public PduTrack reversePdus()
+    {
+        Collections.reverse(pduList);
         return this;
     }
+
     /**
      * Determine whether any ESPDUs have been received by this track
      * @return whether track is empty
@@ -280,8 +307,8 @@ public class PduTrack
         return (getEspduCount() == 0);
     }
     /**
-     * Compute track duration in timestamp ticks
-     * @return duration in timestamp ticks between initial and final ESPDU timestamps in waypointList
+     * Count ESPDUs in pduList
+     * @return number of ESPDUs in pduList
      */
     public int getEspduCount()
     {
@@ -347,6 +374,7 @@ public class PduTrack
     {
         // https://stackoverflow.com/questions/6536094/java-arraylist-copy
         
+           timelineList.clear();
           waypointsList.clear();
         eulerAnglesList.clear();
         float clock = 0.0f;
@@ -356,9 +384,6 @@ public class PduTrack
             if (nextPdu.getPduType() == DisPduType.ENTITY_STATE)
             {
                 EntityStatePdu espdu = (EntityStatePdu)nextPdu;
-                  waypointsList.add(espdu.getEntityLocation());
-                eulerAnglesList.add(espdu.getEntityOrientation());
-                   
                 if (defaultWaypointInterval > 0)
                 {
                     timelineList.add(clock);
@@ -368,14 +393,12 @@ public class PduTrack
                 {
                     timelineList.add(espdu.getTimestamp() * 1.0f); // TODO convert
                 }
+                   waypointsList.add(espdu.getEntityLocation());
+                 eulerAnglesList.add(espdu.getEntityOrientation());
             }
         }
         return this;
     }
-    /**
-     * Create TimeSensor from Pdu list
-     * @return X3D TimeSensor as string
-     */
     public String createX3dTimeSensorString()
     {
         StringBuilder sb = new StringBuilder();
@@ -576,7 +599,7 @@ public class PduTrack
         // https://stackoverflow.com/questions/5175728/how-to-get-the-current-date-time-in-java/5175900
         DateFormat dateFormat = new SimpleDateFormat("d MMMM yyyy");
         Date date = new Date();
-        sb.append("    <meta content='").append(dateFormat.format(date)).append("' name='created'/>").append("\n");
+        sb.append("    <meta content='1 January 2022' name='created'/>").append("\n");
         sb.append("    <meta content='").append(dateFormat.format(date)).append("' name='modified'/>").append("\n");
         if (!getAuthor().isEmpty())
             sb.append("    <meta content='").append(getAuthor()).append("' name='creator'/>").append("\n");
@@ -680,12 +703,12 @@ public class PduTrack
         if (!timelineList.isEmpty())
         {   
             ArrayList<Float> newTimelineList = new ArrayList<>();
-            for (int i = 0; i < timelineList.size(); i++)
+            for (int i = 0; i < getEspduCount(); i++)
             {
                 newTimelineList.add(clock);
                 clock += defaultWaypointInterval;
             }
-            timelineList = newTimelineList;
+            timelineList = newTimelineList; // TO Array copy?
         }
         return this;
     }
@@ -706,10 +729,14 @@ public class PduTrack
         espdu.setMarking("PduTrack");
         for (int i = 0; i < 5; i++)
         {
+            espdu.setTimestamp(i);
             espdu.setEntityLocation(i, i, i);
             espdu.setEntityOrientation(0, (float)(45.0 * Math.PI / 180.0), 0);
             pduTrack.addPdu(espdu);
         }
+        // test track operations
+        pduTrack.reversePdus(); // test
+        pduTrack.sortPdus();    // restore
         pduTrack.createRawWaypoints(); // copies all ESPDU points to waypoints
         
         System.out.println(TRACE_PREFIX + "getEspduCount()="              + pduTrack.getEspduCount());
diff --git a/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d b/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d
index f05f64a93c..0acf341b5b 100644
--- a/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d
+++ b/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d
@@ -4,8 +4,8 @@
   <head>
     <meta content='PduTrackInterpolation.x3d' name='title'/>
     <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/>
-    <meta content='3 January 2022' name='created'/>
-    <meta content='3 January 2022' name='modified'/>
+    <meta content='1 January 2022' name='created'/>
+    <meta content='5 January 2022' name='modified'/>
     <meta content='Don Brutzman' name='creator'/>
     <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d' name='identifier'/>
     <meta content='PduTrack utility, open-dis7-java Library https://github.com/open-dis/open-dis7-java' name='generator'/>
diff --git a/examples/src/OpenDis7Examples/PduTrackLog.txt b/examples/src/OpenDis7Examples/PduTrackLog.txt
index 070653230f..a0fd407190 100644
--- a/examples/src/OpenDis7Examples/PduTrackLog.txt
+++ b/examples/src/OpenDis7Examples/PduTrackLog.txt
@@ -18,8 +18,8 @@ run-single:
   <head>
     <meta content='PduTrackInterpolation.x3d' name='title'/>
     <meta content='Conversion of ESPDU track into X3D animation interpolators and LineSet.' name='description'/>
-    <meta content='3 January 2022' name='created'/>
-    <meta content='3 January 2022' name='modified'/>
+    <meta content='1 January 2022' name='created'/>
+    <meta content='5 January 2022' name='modified'/>
     <meta content='Don Brutzman' name='creator'/>
     <meta content='https://gitlab.nps.edu/Savage/NetworkedGraphicsMV3500/-/blob/master/examples/src/OpenDis7Examples/PduTrackInterpolation.x3d' name='identifier'/>
     <meta content='PduTrack utility, open-dis7-java Library https://github.com/open-dis/open-dis7-java' name='generator'/>
@@ -76,4 +76,4 @@ run-single:
 =================================
 [PduTrack main() self test] selfTest() complete.
 *** PduTrack main() self test complete.
-BUILD SUCCESSFUL (total time: 2 seconds)
+BUILD SUCCESSFUL (total time: 1 second)
-- 
GitLab