Step 5: Migrate the simulation model logic
Intro
Recall that in Part 1 and Part 2 we placed all simulation-related classes in the 'tutorial.model' package of the console app. In this part of the tutorial, this logic will be located in a separate subproject, or bundle, whose name ends with 'simulation'.
These were the wizard settings when we created the application (yours may have been different):
So, in this case, the simulation logic bundle will have the name 'com.company.tutorial3.simulation'. Names of other generated bundles will also start with 'com.company.tutorial3'.
Let’s explore the contents of the 'simulation' bundle:
-
The
ExperimentRunclass is almost the same as in the console application. -
The
Mappingclass is similar to its counterpart in the console app. -
The
Modelclass plays the same role as in the console app, we will update this class soon. -
The
Arcand theNodeclasses in thegraphsubpackage are the same as their siblings in the 'tutorial.model' package of the console application.
Here is what we will do next:
-
Migrate most of the 'tutorial.model' classes to the 'simulation' bundle of the desktop application.
-
Update the
Modelclass in the desktop application.
Migrate the model package and road graph classes
In the …simulation bundle, rename the …simulation.graph package to …simulation.model
(for example, if the root package is named com.company.tutorial3.simulation.graph, then
it should change its name to com.company.tutorial3.simulation.model).
| Use code refactoring capabilities of your IDE. In Eclipse, use package’s context menu item Refactor → Rename. |
Move the Model class from the ..simulation package to the …model package.
| Use "Refactor" → "Move" context menu item for convenience, so that IDE updates the references appropriately. |
Sometimes the IDE is not adding appropriate import statements.
If the Model class fails to find the Mapping class after being moved to another package,
add the missing import manually.
|
Now the …simulation bundle file structure is close to what we already have in the console application.
Copy the following classes from the console application (tutorial.model package)
into the …simulation.model package in the desktop application:
-
Asset -
Dispatcher -
RequestGenerator -
Statistics -
Store -
TransportationRequest -
TransportationTask -
Truck -
Warehouse
| If you have both the desktop app and the console app opened in Eclipse, you can select those java files in the console app (in Project Explorer tree), copy them (use Ctrl+C or the context menu item), then select the target package, and finally paste the copied items (Ctrl+V or the context menu item). |
There should be some compilation errors in the copied classes.
This is OK, since they need an updated Model class.
Migrate the Model class
Rather than updating the Model class, we will replace it and fix any compilation errors.
First, remove the Model class from the the desktop application (…simulation.model package).
Then, copy the Model class from the console application to the desktop application, into the …simulation.model package.
This will cause a couple of compilation errors, so let’s fix them:
-
Open the 'MANIFEST.MF' file of the 'simulation' bundle and add 'org.apache.commons.math3' into the dependency list. This is required, since we are going to use various random distributions during simulation.
-
Remove any failing
importstatements. -
Import the correct
ScenarioandMappingclasses. These should be from the desktop application source code. -
Add a new import statement to the
Modelclass:
import com.amalgamasimulation.randomdatamodel.DistributionFactory;
-
Replace the
createPolyline()method:
private Polyline createPolyline(com.company.tutorial3.datamodel.Arc dmArc) {
List<Point> points = new ArrayList<>();
points.add(new Point(dmArc.getSource().getX(), dmArc.getSource().getY()));
dmArc.getPoints().forEach(
bendpoint -> points.add(new Point(bendpoint.getX(), bendpoint.getY())));
points.add(new Point(dmArc.getDest().getX(), dmArc.getDest().getY()));
return new Polyline(points.stream().distinct().toList());
}
-
In the
Modelclass constructor, find thenewRequestIntervalDistributiondeclaration and replace it:
var newRequestIntervalDistribution = DistributionFactory
.createDistribution(scenario.getIntervalBetweenRequestsHrs(), randomGenerator);
-
Add the following methods to the
Modelclass, as they are required by other classes in the desktop application:
public List<Arc> getArcs() {
return arcs;
}
public GraphEnvironment<Node, Arc, ?> getGraphEnvironment() {
return graphEnvironment;
}
public double getEndTime() {
return dateToTime(scenario.getEndDate());
}
The simulation logic is now fully migrated. In your IDE you can safely close the project with the source code of Part 2.
Check the result
-
Start the application (use the product file in the
relengfolder). -
Create a new scenario.
-
Add two nodes, give them different IDs, make their names equal to IDs.
-
Connect the nodes with an arc.
-
Add one Warehouse at the 1st node, and one Store at the 2nd node. Make assets' names and IDs not null.
-
Add one Truck, make sure all its fields are not null and the speed is positive.
-
Click the root item of the Scenario structure tree and set 'Max delivery time' to be positive, edit 'Interval between requests' to contain some non-null value.
-
Switch to the Simulation mode.
Model initialization should work without error, and the model should also run without issue.
But we still see no warehouses, stores, and trucks in the animation window. Let’s make them all visible.