I the process of working off some of the TODO: items I have sprinkled through the code I ended up fleshing out the model verification function. It is called after everything is defined but before the model runs. I haven’t let a negative finding prevent the model from running — yet — since I currently have a working configuration. The function also ensures that certain settings are initialized.
Here’s the function itself. Explanations and supplementary listings follow.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
function verifyModel() { var modelOK = true; var verifyErrorCodes = ""; var i; //verify forward and backward links exist and are connected to legitimate elements for (i=0; i<numComponents; i++) { var error = setOfComponents[i].verifyLinks(); if (error.length > 0) { verifyErrorCodes += error; modelOK = false; } } //ensure Path components have exclusive setting of their terminating (non-path) component for (i=0; i<numComponents; i++) { if (setOfComponents[i].componentType == "Path") { setOfComponents[i].setExclusive(setOfComponents[i].getNextExclusive()); } } //verify that forward links from EntryComponents are NOT exclusive for (i=0; i<numComponents; i++) { if (setOfComponents[i].getComponentType() == "Entry") { //test to ensure all next components are NOT exclusive var error = setOfComponents[i].verifyNextNotExclusive(); if (error.length > 0) { verifyErrorCodes += error; modelOK = false; } } } //ensure components use downstream distribution method appropriate to the kinds of downstream connections (single, distribution, routing logic) //get destination component indices for outgoing links for (i=0; i<numComponents; i++) { if ((setOfComponents[i].componentType == "Queue") || (setOfComponents[i].componentType == "Process")) { setOfComponents[i].getNextComponentIDs(); } } if (!modelOK) { displayProgressText(verifyErrorCodes); displayProgressText("Model configuration errors identified"); } else { displayProgressText("Model configuration verified"); } } //verify model |
The function starts out by verifying that all previous and next component links exists and are valid in a number of ways. Here’s an example of the most general formation. A customized version of the verifyLinks
method was created for each component type. Component types that do not support one type of link or another (e.g., Exit components do not include forward connections) do not test those elements. It is possible that these methods can be even more standardized and modularized, and I may look into that at some point.
In general, the method ensures that the count of connections is not zero, that the list of connections does contain references to something, that the references are to objects, that the objects are (likely to be) components by testing for the presences of the componentType
property, and that the connections are not to types of components that make no sense (e.g., Entry components cannot be connected to Exit components and vice versa).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
this.verifyLinks = function() { var error = ""; if (this.nextComponentCount > 0) { for (var i=0; i<this.nextComponentCount; i++) { //> if (this.nextComponentList[i]) { //link exists if (typeof this.nextComponentList[i] === "object") { //link points to an object if ("componentType" in this.nextComponentList[i]) { //object contains member componentType if ((this.nextComponentList[i].componentType == "Arrivals") || (this.nextComponentList[i].componentType == "Entry")) { error += this.componentType+" comp. "+this.componentID+" next comp. list element "+i+" is not an allowed comp.\n"; } } else { //linked object does not contain member componentType error += this.componentType+" comp. "+this.componentID+" next comp. list item "+i+" does not have componentType\n"; } } else { //link points to something that is not an object error += this.componentType+" comp. "+this.componentID+" next comp. list item "+i+" is not an object\n"; } } else { //link that should exist does not error += this.componentType+" comp. "+this.componentID+" next comp. list item "+i+" does not exist\n"; } } } else { error += this.componentType+" comp. "+this.componentID+" has index of zero next components\n"; } if (this.previousComponentCount > 0) { for (var i=0; i<this.previousComponentCount; i++) { //> if (this.previousComponentList[i]) { //link exists if (typeof this.previousComponentList[i] === "object") { //link points to an object if ("componentType" in this.previousComponentList[i]) { //object contains member componentType if ((this.previousComponentList[i].componentType == "Arrivals") || (this.previousComponentList[i].componentType == "Exit")) { error += this.componentType+" comp. "+this.componentID+" previous comp. list element "+i+" is not an allowed comp.\n"; } } else { //linked object does not contain member componentType error += this.componentType+" comp. "+this.componentID+" previous comp. list item "+i+" does not have componentType\n"; } } else { //link points to something that is not an object error += this.componentType+" comp. "+this.componentID+" previous comp. list item "+i+" is not an object\n"; } } else { //link that should exist does not error += this.componentType+" comp. "+this.componentID+" previous comp. list item "+i+" does not exist\n"; } } } else { error += this.componentType+" comp. "+this.componentID+" has index of zero previous components\n"; } return error; }; |
The function continues by setting the value of the exclusive
property for each Path component based the exclusive
property of its terminating non-Path component. This assumes that the exclusive
property of each non-Path component has already been set.
Here’s the getNextExclusive
function I had to define in the Path component. I noticed that I do this pass-through thing frequently and should come up with a consistent naming convention for methods like this.
1 2 3 4 5 6 7 |
this.getNextExclusive = function() { if (this.nextComponent.getComponentType() != "Path") { return this.nextComponent.getExclusive(); } else { return this.nextComponent.getNextExclusive(); } }; |
The verifyModel
function then tests the nextComponentList
links of every Entry component to ensure that all connected components are defined to be non-exclusive. Here’s the code for the A customized version of the
method.verifyLinks
method was created for each component type.
1 2 3 4 5 6 7 8 9 |
this.verifyNextNotExclusive = function() { var error = ""; for (var i=0; i<this.nextComponentCount; i++) { if (this.nextComponentList[i].getExclusive()) { error += this.componentType+" comp. "+this.componentID+", next comp. "+i+" should not be exclusive\n"; } } return error; }; |
Finally, I moved the mechanism for assigning destination component indices for forward links to here.
Some of the methods return error codes, and these are placed in the scrolling text area. The messages include detailed notes about the components and connections that are incorrectly configured.
I have a comment in place to implement a mechanism to assign the desired distribution method based on the nature of the downstream connections.
I currently have the routing logic attached to the individual components, but there is also a need to ensure that certain combinations of destinations can be reached from the point of view of an entity moving through a system. Moreover, destinations may need to be identitied in an aggregate way, like a toll plaza containing many booths. I will implement a test mechanism to address that process at some point as well.
There are many more things that can be tested or automated in this or similar functions. However, this was a pretty good start.
Last but not least, and not related to this project, I was able to complete another class on Udemy over the weekend, this time about Sass and SCSS.