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
ExperimentRun
class is almost the same as in the console application. -
The
Mapping
class is similar to its counterpart in the console app. -
The
Model
class plays the same role as in the console app, we will update this class soon. -
The
Arc
and theNode
classes in thegraph
subpackage 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
Model
class 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
import
statements. -
Import the correct
Scenario
andMapping
classes. These should be from the desktop application source code. -
Add a new import statement to the
Model
class:
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
Model
class constructor, find thenewRequestIntervalDistribution
declaration and replace it:
var newRequestIntervalDistribution = DistributionFactory
.createDistribution(scenario.getIntervalBetweenRequestsHrs(), randomGenerator);
-
Add the following methods to the
Model
class, 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
releng
folder). -
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.