From d63f4ade174ff8142a8cf253334331aed0f55ddb Mon Sep 17 00:00:00 2001
From: brutzman <brutzman@nps.edu>
Date: Sun, 15 Aug 2021 07:21:35 -0700
Subject: [PATCH] improved narrative logging with Comment PDUs

---
 .../ExampleSimulationProgram.java             | 77 +++++++++++++++----
 .../ExampleSimulationProgramOutput.txt        | 69 ++++++++++-------
 2 files changed, 101 insertions(+), 45 deletions(-)

diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java
index 3127dc0d83..4991e13476 100644
--- a/examples/src/OpenDis7Examples/ExampleSimulationProgram.java
+++ b/examples/src/OpenDis7Examples/ExampleSimulationProgram.java
@@ -30,15 +30,12 @@ public class ExampleSimulationProgram
     {
       try
       {
-          
-          
         final double LOOP_DURATION_SECONDS  =  1.0; // seconds
         final int    MAX_LOOP_COUNT = 10;
               int    loopCount = 0;
-        VariableRecordType narrativeType = VariableRecordType.OTHER; // of potential use
         boolean simulationComplete = false; // sentinel variable as termination condition
         
-        // TODO reset clock to zero each time for consistent outputs.
+        // TODO reset clock to zero each time for consistent outputs
         
         // your model setup: who's who in this zoo?
         // create PDU objects and set their values
@@ -52,10 +49,11 @@ public class ExampleSimulationProgram
         FirePdu               firePdu = pduFactory.makeFirePdu();
         // should we customize this munition?  what is it for your simulation?
         
+        // TODO simulation management PDUs
+        
         // loop the simulation while allowed, programmer can set additional conditions to break out and finish
         while (loopCount < MAX_LOOP_COUNT) 
         {
-            String narrativeMessage1, narrativeMessage2, narrativeMessage3;
             // initialize loop variables
             loopCount++;
             
@@ -91,21 +89,26 @@ public class ExampleSimulationProgram
             // keep track of timestep: wait duration for elapsed time in this loop
             // Thread.sleep needs a (long) parameter for milliseconds, which are clumsy to use sometimes
             Thread.sleep((long)(LOOP_DURATION_SECONDS * 1000)); // seconds * (1000 msec/sec) = milliseconds
-            System.out.println ("... Pausing for " + LOOP_DURATION_SECONDS + " seconds");
+            System.out.println ("... [Pausing for " + LOOP_DURATION_SECONDS + " seconds]");
             
             // send the status PDUs for this loop and continue
             System.out.println ("sending PDUs for simulation step " + loopCount + ", monitor loopback to confirm sent");
-            sendAllPdus(entityStatePdu, firePdu, null, narrativeMessage1, narrativeMessage2, narrativeMessage3);
-            System.out.println ("... PDUs successfully sent");
+            sendAllPdus(entityStatePdu, firePdu, timeStepComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
+            System.out.println ("... [PDUs successfully sent for this loop]");
             
             // ===============================
             // loop now finished, thus terminate if simulation complete, otherwise send latest PDUs and continue
             if (simulationComplete || (loopCount > 10000)) // for example; including fail-safe condition is good
             {
-                System.out.println ("... Termination condition met, simulationComplete=" + simulationComplete);
+                System.out.println ("... [Termination condition met, simulationComplete=" + simulationComplete + "]"); // ", final loopCount=" + loopCount + 
                 break;
             }
         }   // end of while loop
+        // all done
+        narrativeMessage2 = "runSimulation() completed successfully";
+        sendCommentPdu(narrativeComment, narrativeMessage1, narrativeMessage2, narrativeMessage3);
+        System.out.println ("... [final CommentPdu successfully sent for simulation]");
+        // TODO simulation management PDUs
       } 
       catch (InterruptedException iex) // handle any exception that your code might choose to provoke!
       {
@@ -113,7 +116,19 @@ public class ExampleSimulationProgram
       }
     }
     /* **************************** infrastructure code, modification is seldom needed ************************* */
-    
+        
+    private boolean verboseComments = true;
+    String narrativeMessage1 = new String();
+    String narrativeMessage2 = new String();
+    String narrativeMessage3 = new String();
+          
+    /* VariableRecordType enumerations have potential use with CommentPdu logs */
+    VariableRecordType descriptionComment = VariableRecordType.DESCRIPTION;
+    VariableRecordType   narrativeComment = VariableRecordType.COMPLETE_EVENT_REPORT;
+    VariableRecordType      statusComment = VariableRecordType.APPLICATION_STATUS;
+    VariableRecordType    timeStepComment = VariableRecordType.APPLICATION_TIMESTEP;
+    VariableRecordType       otherComment = VariableRecordType.OTHER;
+        
 	/**
 	 * Output prefix to identify this class, helps with logging
 	 */
@@ -227,19 +242,32 @@ public class ExampleSimulationProgram
         }
     }
 
+    /**
+     * Send Comment PDU
+     * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
+     * @param commentType    enumeration value describing purpose of the narrative comment
+     * @param comments       String array of narrative comments
+     */
+    public void sendCommentPdu(VariableRecordType commentType,
+                                     // vararg... variable-length set of String comments can optionally follow
+                                       String... comments)
+    {
+        sendAllPdus (null, null, commentType, comments);
+    }
+
     /**
      * Send EntityState, Fire, Comment PDUs
      * @see <a href="https://docs.oracle.com/javase/tutorial/java/javaOO/arguments.html">Passing Information to a Method or a Constructor</a> Arbitrary Number of Arguments
      * @param entityStatePdu the ESPDU to send, if any
      * @param firePdu        the FirePDU to send, if any
-     * @param commentType    enumeration value describing the narrative comment
+     * @param commentType    enumeration value describing purpose of the narrative comment
      * @param comments       String array of narrative comments
      */
     public void sendAllPdus(EntityStatePdu entityStatePdu,
-                               FirePdu firePdu,
-                               VariableRecordType commentType,
-                               // vararg... variable length string
-                               String... comments)
+                                   FirePdu firePdu,
+                        VariableRecordType commentType,
+                              // vararg... variable-length set of String comments can optionally follow
+                                 String... comments)
     {
         if (entityStatePdu != null)
             sendSinglePdu(entityStatePdu);
@@ -258,9 +286,12 @@ public class ExampleSimulationProgram
             if (!newCommentsList.isEmpty())
             {
                 if (commentType == null)
-                    commentType = VariableRecordType.OTHER;
+                    commentType = otherComment; // fallback value otherComment
+                // now build the commentPdu from these string inputs
                 CommentPdu commentPdu = pduFactory.makeCommentPdu(commentType, newCommentsList.toArray(new String[0])); // comments);
                 sendSinglePdu(commentPdu);
+                if (isVerboseComments())
+                    System.out.println("*** [Narrative comment sent: " + commentType.name() + "] " + newCommentsList.toString());
             }
         }
     }
@@ -300,4 +331,18 @@ public class ExampleSimulationProgram
         
         System.out.println(TRACE_PREFIX + "complete."); // report successful completion
     }
+
+    /**
+     * @return whether verboseComments mode is enabled
+     */
+    public boolean isVerboseComments() {
+        return verboseComments;
+    }
+
+    /**
+     * @param newVerboseComments whether verboseComments mode is enabled
+     */
+    public void setVerboseComments(boolean newVerboseComments) {
+        this.verboseComments = newVerboseComments;
+    }
 }
diff --git a/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt b/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt
index 0b2cc4a134..e0456131e0 100644
--- a/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt
+++ b/examples/src/OpenDis7Examples/ExampleSimulationProgramOutput.txt
@@ -4,43 +4,54 @@ Deleting: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.prope
 deps-jar:
 Updating property file: C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\built-jar.properties
 Compiling 1 source file to C:\x-nps-gitlab\NetworkedGraphicsMV3500\examples\build\classes
-warning: [options] bootstrap class path not set in conjunction with -source 8
-1 warning
 compile-single:
 run-single:
 [OpenDis7Examples.ExampleSimulationProgram] started...
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] Using network interface Intel(R) Centrino(R) Ultimate-N 6300 AGN
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  Using network interface Intel(R) Centrino(R) Ultimate-N 6300 AGN
 Network confirmation: address=239.1.2.3 port=3000
-... Pausing for 1.0 seconds
+... My simulation just did something, no really...
+... [Pausing for 1.0 seconds]
 sending PDUs for simulation step 1, monitor loopback to confirm sent
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   1. received DisPduType 01 ENTITY_STATE size 144 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   2. received DisPduType 02 FIRE size 96 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   3. received DisPduType 22 COMMENT size 104 bytes
-... PDUs successfully sent
-... Pausing for 1.0 seconds
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 1. received DisPduType 01 ENTITY_STATE, size 144 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 2. received DisPduType 02 FIRE, size 96 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 3. received DisPduType 22 COMMENT, size 104 bytes)
+*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgram, runSimulation() loop 1]
+... [PDUs successfully sent for this loop]
+... My simulation just did something, no really...
+... [Pausing for 1.0 seconds]
 sending PDUs for simulation step 2, monitor loopback to confirm sent
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   4. received DisPduType 01 ENTITY_STATE size 144 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   5. received DisPduType 02 FIRE size 96 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   6. received DisPduType 22 COMMENT size 104 bytes
-... PDUs successfully sent
-... Pausing for 1.0 seconds
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 4. received DisPduType 01 ENTITY_STATE, size 144 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 5. received DisPduType 02 FIRE, size 96 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 6. received DisPduType 22 COMMENT, size 104 bytes)
+*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgram, runSimulation() loop 2]
+... [PDUs successfully sent for this loop]
+... My simulation just did something, no really...
+... [Pausing for 1.0 seconds]
 sending PDUs for simulation step 3, monitor loopback to confirm sent
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   7. received DisPduType 01 ENTITY_STATE size 144 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   8. received DisPduType 02 FIRE size 96 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]   9. received DisPduType 22 COMMENT size 104 bytes
-... PDUs successfully sent
-... Pausing for 1.0 seconds
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 7. received DisPduType 01 ENTITY_STATE, size 144 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 8. received DisPduType 02 FIRE, size 96 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 9. received DisPduType 22 COMMENT, size 104 bytes)
+*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgram, runSimulation() loop 3]
+... [PDUs successfully sent for this loop]
+... My simulation just did something, no really...
+... [Pausing for 1.0 seconds]
 sending PDUs for simulation step 4, monitor loopback to confirm sent
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  10. received DisPduType 01 ENTITY_STATE size 144 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  11. received DisPduType 02 FIRE size 96 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  12. received DisPduType 22 COMMENT size 104 bytes
-... PDUs successfully sent
-... Pausing for 1.0 seconds
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 10. received DisPduType 01 ENTITY_STATE, size 144 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 11. received DisPduType 02 FIRE, size 96 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 12. received DisPduType 22 COMMENT, size 104 bytes)
+*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgram, runSimulation() loop 4]
+... [PDUs successfully sent for this loop]
+... My simulation just did something, no really...
+... [Pausing for 1.0 seconds]
 sending PDUs for simulation step 5, monitor loopback to confirm sent
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  13. received DisPduType 01 ENTITY_STATE size 144 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  14. received DisPduType 02 FIRE size 96 bytes
-[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface]  15. received DisPduType 22 COMMENT size 104 bytes
-... PDUs successfully sent
-... Termination condition met, simulationComplete=true
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 13. received DisPduType 01 ENTITY_STATE, size 144 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 14. received DisPduType 02 FIRE, size 96 bytes)
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 15. received DisPduType 22 COMMENT, size 104 bytes)
+*** [Narrative comment sent: APPLICATION_TIMESTEP] [MV3500 ExampleSimulationProgram, runSimulation() loop 5]
+... [PDUs successfully sent for this loop]
+... [Termination condition met, simulationComplete=true]
+[edu.nps.moves.dis7.utilities.DisThreadedNetworkInterface] 16. received DisPduType 22 COMMENT, size 120 bytes)
+*** [Narrative comment sent: COMPLETE_EVENT_REPORT] [MV3500 ExampleSimulationProgram, runSimulation() completed successfully]
+... [final CommentPdu successfully sent for simulation]
 [OpenDis7Examples.ExampleSimulationProgram] complete.
 BUILD SUCCESSFUL (total time: 10 seconds)
-- 
GitLab