{"id":1073,"date":"2016-10-17T11:30:37","date_gmt":"2016-10-17T16:30:37","guid":{"rendered":"http:\/\/rpchurchill.com\/?p=1073"},"modified":"2017-02-03T14:34:04","modified_gmt":"2017-02-03T19:34:04","slug":"a-simple-discrete-event-simulation-part-26","status":"publish","type":"post","link":"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/10\/17\/a-simple-discrete-event-simulation-part-26\/","title":{"rendered":"A Simple Discrete-Event Simulation: Part 26"},"content":{"rendered":"<p>Having sorted out the internal reference issues in JavaScript I could go ahead and post the next update to the model framework.  In this iteration the entities are completely passive, which means that the newly created entities are generated using a secondary puck within the <code>ArrivalsComponent<\/code> element.  Repeatedly clicking on the &#8220;Step&#8221; button advances through the events one by one, up to 360 minutes.  (40-ish clicks, refresh the browser to reset.)<\/p>\n<p><iframe loading=\"lazy\" width=\"400px\" height=\"700px\" src=\"https:\/\/www.rpchurchill.com\/demo\/des\/discrete-event-sim_20161017.html\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p>I&#8217;ve included the code for the <code>ArrivalsComponent<\/code> element to show how the two pucks cooperate.  Pucks become inactive when they aren&#8217;t reinserted into the future events queue (or the current events queue, but we&#8217;ll get back to that later).  The main puck, the one associated with the <code>blockIncrement<\/code> method, is recycled every 30 minutes through the entire duration of the simulation.  The secondary puck, associated with the <code>makeEntity<\/code> method, is reactivated as needed during every 30-minute cycle, and is recycled until all of the arrivals for that interval are created.<\/p>\n<p>The newly created entities should be forwarded to some other location (i.e., actually injected into the model), and I&#8217;ve left a comment and blank line as a placeholder.  This will get filled in as I create the other component types.<\/p>\n<p>Right now I&#8217;m redrawing the display every time the <code>activate<\/code> method is called (at the end, after the work has been done) but later this operation will have to be called externally, so the displays for every element in the model can be redrawn during every update.<\/p>\n<p>Finally, I cleaned up a few things to better follow JavaScript&#8217;s preferred naming conventions, use of ending semi-colons, and a few other things as suggested by <a href=\"https:\/\/www.jetbrains.com\/webstorm\/\">WebStorm<\/a>.  (I maintain a full personal license for all of <a href=\"https:\/\/www.jetbrains.com\/\">JetBrains<\/a>&#8216; products.)  <\/p>\n<p>Here&#8217;s the code for the <code>ArrivalsComponent<\/code> itself.<\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">\r\n    \/\/Arrivals component: generates entities that will be processed by the model\r\n    function ArrivalsComponent(scheduleBlockMinutes,scheduleArray) {\r\n      setOfEntities.push(this);\r\n      this.componentID = getNewID();\r\n      this.componentName = \"Arrivals\";\r\n      this.startBlockTime = globalSimClock;\r\n      this.currentBlockTime = globalSimClock;\r\n      this.incrementTime = scheduleBlockMinutes;\r\n      this.endBlockTime = globalSimClock + this.incrementTime;\r\n      this.entitiesScheduled = 0;\r\n      this.entitiesRemaining = 0;\r\n      this.currentEntityID = \"\";\r\n      this.activity = \"creation\";\r\n      this.scheduleIndex = 0;\r\n      this.endTime = endSimTime;\r\n      this.nextComponent = null;\r\n      \/\/this.nextState = \"increment\";\r\n      feq.newItem(globalSimClock,this,\"increment\");  \/\/assume all components created at time zero\r\n      \r\n      \/\/could also create blank and then use this.dataGroup.define externally so initiation not internal like this\r\n      this.dataGroup = new DisplayGroup(this.componentName,10,10,100,\"#00FFFF\",\"#FF0000\",\"#FFFF00\");\r\n      this.dataGroup.addValue(this.componentID,\"comp. ID\",\"integer\");\r\n      this.dataGroup.addValue(this.startBlockTime,\"Start Time\",\"numdec\",5);\r\n      this.dataGroup.addValue(this.currentBlockTime,\"CurrentTime\",\"numdec\",5);\r\n      this.dataGroup.addValue(this.endBlockTime,\"End Time\",\"numdec\",5);\r\n      this.dataGroup.addValue(this.entitiesScheduled,\"# Entities\",\"integer\");\r\n      this.dataGroup.addValue(this.entitiesRemaining,\"# Remaining\",\"integer\");\r\n      this.dataGroup.addValue(this.currentEntityID,\"Entity ID\",\"integer\");\r\n      this.dataGroup.addValue(this.activity,\"Activity\",\"text\");\r\n      \r\n      this.assignDisplayValues = function() {\r\n        this.dataGroup.valueList[0].value = this.componentID;\r\n        this.dataGroup.valueList[1].value = this.startBlockTime;\r\n        this.dataGroup.valueList[2].value = this.currentBlockTime;\r\n        this.dataGroup.valueList[3].value = this.endBlockTime;\r\n        this.dataGroup.valueList[4].value = this.entitiesScheduled;\r\n        this.dataGroup.valueList[5].value = this.entitiesRemaining;\r\n        this.dataGroup.valueList[6].value = this.currentEntityID;\r\n        this.dataGroup.valueList[7].value = this.activity;\r\n      };\r\n      this.drawData = function() {\r\n        this.assignDisplayValues();\r\n        this.dataGroup.drawBasic();\r\n      };\r\n      \r\n      this.makeEntity = function() {\r\n        var e = generateNewEntity(this);\r\n        this.currentBlockTime = globalSimClock;\r\n        this.entitiesRemaining--;\r\n        this.currentEntityID = e.entityID;  \/\/should create function to get this\r\n        this.activity = \"make entity\";\r\n        \/\/do something to send it to the entry component\r\n        \r\n        \/\/more to generate\r\n        if (this.entitiesRemaining > 0) {\r\n          var nextIndex = this.entitiesScheduled-this.entitiesRemaining;\r\n          var nextTime = this.arrivalArray[nextIndex];\r\n          var thisIndex = nextIndex-1;\r\n          var thisTime = this.arrivalArray[thisIndex];\r\n          advance(nextTime-thisTime,\"makeEntity\");\r\n          \/\/advance(arrivalArray[this.entitiesScheduled-this.entitiesRemaining]-arrivalArray[this.entitiesScheduled-this.entitiesRemaining-1],\"makeEntity\");\r\n        }\r\n        displayProgressText(\"Entry component \"+this.componentID+\" generates entity: \"+this.currentEntityID+\" at time \"+globalSimClock);\r\n      };  \/\/this.makeEntity\r\n      this.blockIncrement = function() {  \/\/should be called at the beginning of every time block\r\n        \/\/get arrival count per array index\r\n        this.entitiesScheduled = scheduleArray[this.scheduleIndex];\r\n        if (this.entitiesScheduled > 0) {\r\n          \/\/var arrivalArray = [];\r\n          this.arrivalArray = [];\r\n          for (var i=0; i<this.entitiesScheduled; i++) {\r\n            this.arrivalArray[i] = Math.random() * scheduleBlockMinutes;\r\n          } \r\n          \/\/sort the array\r\n          this.arrivalArray.sort(compareNumeric);\r\n          \/\/generate the arrivals          \r\n          \/\/for (var i=0; i<this.entitiesScheduled; i++) {\r\n          \/\/  this.generateNewEntity(this,globalSimClock + this.arrivalArray[i]);\r\n          \/\/}\r\n          feq.newItem(globalSimClock+this.arrivalArray[0],this,\"makeEntity\");  \/\/assume all components created at time zero\r\n        }\r\n        this.scheduleIndex++;\r\n        displayProgressText(\"Entry component \"+this.componentID+\" generates \"+this.entitiesScheduled+\" new entities at time \"+globalSimClock);\r\n        \/\/set values for display-------------\r\n        this.startBlockTime = globalSimClock;\r\n        this.currentBlockTime = globalSimClock;\r\n        this.endBlockTime = globalSimClock + this.incrementTime;\r\n        this.entitiesRemaining = this.entitiesScheduled;\r\n        this.currentEntityID = \"\";\r\n        this.activity = \"generate\";\r\n        \/\/----------------------------------\r\n        if (globalSimClock + this.incrementTime >= this.endTime) {\r\n          \/\/this.nextState = \"destroy\";\r\n          advance(this.incrementTime,\"destroy\");\r\n        } else {\r\n          advance(this.incrementTime,\"increment\");\r\n        }\r\n      };  \/\/this.blockIncrement\r\n      this.destroy = function() {\r\n        displayProgressText(\"Entry component \"+this.entityID+\" terminated at time \"+globalSimClock);\r\n        \/\/do something to take this element out of the global element list - setOfEntities\r\n      };  \/\/this.destroy\r\n      this.activate = function(nextState) {\r\n        if (nextState == \"makeEntity\") {\r\n          this.makeEntity();\r\n        } else if (nextState == \"increment\") {\r\n          this.blockIncrement();\r\n        } else if (nextState == \"destroy\") {\r\n          this.destroy();\r\n        } else {\r\n          errorUndefinedAdvanceState(this.entityID,nextState);\r\n        }\r\n        clearCanvas(\"#000000\");\r\n        this.drawData();\r\n      }\r\n    }  \/\/ArrivalsComponent\r\n<\/pre>\n<p>Here are a couple of supporting items that need to be declared first.<\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">\r\n    \/\/entity item passive\r\n    \/\/stores minimal state information, does nothing on its won\r\n    function EntityPassive() {\r\n      this.entityID = getNewID();\r\n      this.entryTime = globalSimClock;\r\n      this.localEntryTime = 0.0;\r\n      this.stampLocalEntryTime = function() {\r\n        this.localEntryTime = globalSimClock;\r\n      }\r\n    }  \/\/EntityPassive\r\n\r\n\r\n    \/\/function to generate new entities\r\n    function generateNewEntity(generator) {\r\n      \/\/generator is an arrivals component\r\n      \/\/start is an initial activation time\r\n      var newEntity = new EntityPassive();\r\n      setOfEntities.push(newEntity);\r\n      return newEntity;\r\n    }  \/\/generateNewEntity\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Having sorted out the internal reference issues in JavaScript I could go ahead and post the next update to the model framework. In this iteration the entities are completely passive, which means that the newly created entities are generated using &hellip; <a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2016\/10\/17\/a-simple-discrete-event-simulation-part-26\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[60],"tags":[121,49],"_links":{"self":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1073"}],"collection":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1073"}],"version-history":[{"count":4,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1073\/revisions"}],"predecessor-version":[{"id":1436,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1073\/revisions\/1436"}],"wp:attachment":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1073"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1073"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1073"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}