/************************************************************************************************************************* File: sketch.js Purpose: This file does all of the heavy lifting for creating the view for my project. It is the javascript backend for the webpage view.html, and it provides drawing functionality so that I can illustrate how my simulation is running. It makes strong use of the p5.js javascript library (included in view.html) to accomplish these tasks. Any tasks related to contacting the server to request information about the simulation/control pieces of it are handled by calling the functions defined in connections.js Note: This file is named sketch.js because that is an imperative imposed by the p5.js library. Naming the file this way allows me to use the setup and draw functions as the main drivers for the graphics of my application. Written by John McGorey - Spring 2019 - Using Microsoft Visual Studio Code 2019 For use in the St. Norbert College CSCI460 Senior Capstone Experience **************************************************************************************************************************/ let trains = []; // The list of trains active in the present simulation let turnouts = []; // The list of turnouts active in the present simulation let rails = []; // The list of rails active in the present simulation let updateCount = 0; // A counter of how many draw cycles have passed since the last batch of requests let updateThreshold = 15; // The number of draw cycles between sending a request to the server for an update function setup() { /*************************************************************************************** Function: setup Purpose: This function does setup before draw is called for the first time. It takes care of creating the canvas to draw on, populating the rails array (via the getRails method in connections.js), and populating the trains and turnouts arrays as well (also through their methods in connections.js) Note: This function's behavior (being called before draw) is provided by the p5.js library. ****************************************************************************************/ createCanvas(1000, 1000); getRails(); getTurnouts(createTurnouts); getTrains(createTrains); } function draw() { /*************************************************************************************** Function: draw Purpose: This function handles drawing the simulation data objects to the screen Every 15 cycles, this function calls getTrains and getTurnouts from the connections.js file to populate the trains and turnouts arrays. Note: This function is called in a controlled loop 60 times a second. This behavior is provided by the p5.js library. ****************************************************************************************/ background(17, 17, 35); if (updateCount >= updateThreshold) { updateCount = 0; getTrains(updateTrains); getTurnouts(loadTurnouts); } // Draw all of the rails for (let i = 0; i < rails.length; i++) { rails[i].Draw(); } // Draw all of the turnouts for (let i = 0; i < turnouts.length; i++) { turnouts[i].Draw(); } // Draw all of the trains for (let i = 0; i < trains.length; i++) { trains[i].Draw(); } updateCount++; } function loadRails(rail_obj_array) { /*************************************************************************************** Function: loadRails Purpose: Populates the rails array with information from the server. Input: rail_obj_array - an array containing rail objects from the server to convert into the Rail objects defined by rail.js Note: This function is only called once in setup because the rails in the layout do not have any 'moving parts', as it were. They can be defined once and work for the duration of the simulation ****************************************************************************************/ rails = []; // Go through the array of objects containing rail blueprints for (let i = 0; i < rail_obj_array.length; i++) { let r = new Rail(rail_obj_array[i]); // Create the new rail rails.push(r); // Add it to the list of rails } } function createTrains(train_obj_array){ /*************************************************************************************** Function: createTrains Purpose: Populates the trains array for the first time with information from the server. This also calls createTrainInput to set up the train select input on view.html Input: trains_obj_array - an array containing raw train objects to be turned into the Train object defined by train.js Note: ****************************************************************************************/ trains = []; // Empty out the train array for (let i = 0; i < train_obj_array.length; i++) { let t = new Train(train_obj_array[i]); // Create the new train trains.push(t); // Add it to the list of trains } createTrainInput(); } function updateTrains(train_obj_array) { /*************************************************************************************** Function: updateTrains Purpose: Updates the exiting train objects in the trains array with new info from the server. Input: trains_obj_array - An array containing the updated train info to move into the existing train objects Note: This method updates the existing train objects with the new info rather than recreating the entire list. This was an experiment to see if there was any better performance doing it this way vs. recreating the entire list. ****************************************************************************************/ for (let i = 0; i < train_obj_array.length; i++) { trains[i].SetPosition(train_obj_array[i]); trains[i].UpdateStatus(train_obj_array[i]); trains[i].SetRail(train_obj_array[i]); } } function createTurnouts(turnout_obj_array) { /*************************************************************************************** Function: createTurnouts Purpose: Populates the turnouts array for the first time with information from the server. This also calls createTurnoutInput to setup the turnout select input on view.html Input: turnout_obj_array - an array containing raw turnout objects to be turned into the Turnout object defined by turnout.js ****************************************************************************************/ turnouts = []; // Empty out the turnout array for (let i = 0; i < turnout_obj_array.length; i++) { let t = new Turnout(turnout_obj_array[i]); // Create the new turnout turnouts.push(t); // Add it to the list of turnouts } createTurnoutInput(); } function loadTurnouts(turnout_obj_array) { /*************************************************************************************** Function: loadTurnouts Purpose: Populates the turnouts array with updated information from the server. Input: turnout_obj_array - an array containing raw turnout objects to be turned into the Turnout object defined by turnout.js Note: This function empties and recreates the entire turnouts array ****************************************************************************************/ turnouts = []; // Empty out the turnout array for (let i = 0; i < turnout_obj_array.length; i++) { let t = new Turnout(turnout_obj_array[i]); // Create the new turnout turnouts.push(t); // Add it to the list of turnouts } } function createTurnoutInput() { /*************************************************************************************** Function: createTurnoutInput() Purpose: Populates the turnout selection input on view.html ****************************************************************************************/ let element = document.getElementById('turnoutId'); if (element) { for (let i = 0; i < turnouts.length; i++) { element.options[i] = new Option("Turnout " + i, i); } } } function createTrainInput() { /*************************************************************************************** Function: createTrainInput Purpose: Populates the train selection input on view.html ****************************************************************************************/ let element = document.getElementById('trainId'); if (element) { for (let i = 0; i < trains.length; i++) { element.options[i] = new Option("Train " + i, i); } } }