/*
* JaamSim Discrete Event Simulation
* Copyright (C) 2014 Ausenco Engineering Canada Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.jaamsim.ProcessFlow;
import java.util.ArrayList;
import com.jaamsim.Graphics.DisplayEntity;
import com.jaamsim.input.IntegerInput;
import com.jaamsim.input.Keyword;
import com.jaamsim.input.Output;
import com.jaamsim.input.ValueInput;
import com.jaamsim.input.Vec3dInput;
import com.jaamsim.math.Vec3d;
import com.jaamsim.states.StateEntity;
import com.jaamsim.states.StateRecord;
import com.jaamsim.units.DimensionlessUnit;
import com.jaamsim.units.DistanceUnit;
public class EntityContainer extends SimEntity {
@Keyword(description = "The position of the first entity in the container relative to the container.",
exampleList = {"1.0 0.0 0.01 m"})
protected final Vec3dInput positionOffset;
@Keyword(description = "The amount of graphical space shown between entities in the container.",
exampleList = {"1 m"})
private final ValueInput spacingInput;
@Keyword(description = "The number of entities in each row inside the container.",
exampleList = {"4"})
protected final IntegerInput maxPerLineInput;
private ArrayList<DisplayEntity> entityList;
{
positionOffset = new Vec3dInput("PositionOffset", "Key Inputs", new Vec3d(0.0d, 0.0d, 0.01d));
positionOffset.setUnitType(DistanceUnit.class);
this.addInput(positionOffset);
spacingInput = new ValueInput("Spacing", "Key Inputs", 0.0d);
spacingInput.setUnitType(DistanceUnit.class);
spacingInput.setValidRange(0.0d, Double.POSITIVE_INFINITY);
this.addInput(spacingInput);
maxPerLineInput = new IntegerInput("MaxPerLine", "Key Inputs", Integer.MAX_VALUE);
maxPerLineInput.setValidRange( 1, Integer.MAX_VALUE);
this.addInput(maxPerLineInput);
}
public EntityContainer() {
entityList = new ArrayList<>();
}
@Override
public void earlyInit() {
super.earlyInit();
entityList.clear();
}
public void addEntity(DisplayEntity ent) {
entityList.add(ent);
}
public DisplayEntity removeEntity() {
DisplayEntity ent = entityList.remove(entityList.size()-1);
return ent;
}
public int getCount() {
return entityList.size();
}
@Override
public void stateChanged(StateRecord prev, StateRecord next) {
super.stateChanged(prev, next);
// Set the states for the entities carried by the EntityContainer to the new state
for (DisplayEntity ent : entityList) {
if (ent instanceof StateEntity)
((StateEntity)ent).setPresentState(next.name);
}
}
@Override
public void kill() {
for (DisplayEntity ent : entityList) {
ent.kill();
}
super.kill();
}
/**
* Update the position of all entities in the queue. ASSUME that entities
* will line up according to the orientation of the queue.
*/
@Override
public void updateGraphics( double simTime ) {
Vec3d orient = getOrientation();
Vec3d size = this.getSize();
Vec3d tmp = new Vec3d();
// Find widest entity
double maxWidth = 0;
for (int j = 0; j < entityList.size(); j++) {
maxWidth = Math.max(maxWidth, entityList.get(j).getSize().y);
}
// Update the position of each entity (start at the bottom left of the container)
double distanceX = -0.5*size.x;
double distanceY = -0.5*size.y + 0.5*maxWidth;
for (int i = 0; i < entityList.size(); i++) {
// if new row is required, reset distanceX and move distanceY up one row
if (i > 0 && i % maxPerLineInput.getValue() == 0){
distanceX = -0.5*size.x;
distanceY += spacingInput.getValue() + maxWidth;
}
// Rotate each entity about its center so it points to the right direction
DisplayEntity item = entityList.get(i);
item.setOrientation(orient);
// Set Position
Vec3d itemSize = item.getSize();
distanceX += spacingInput.getValue() + 0.5*itemSize.x;
tmp.set3(distanceX/size.x, distanceY/size.y, 0.0d);
Vec3d itemCenter = this.getGlobalPositionForAlignment(tmp);
itemCenter.add3(positionOffset.getValue());
item.setGlobalPositionForAlignment(new Vec3d(), itemCenter);
// increment total distance
distanceX += 0.5*itemSize.x;
}
}
@Output(name = "Count",
description = "The present number of entities in the EntityContainer.",
unitType = DimensionlessUnit.class,
reportable = false)
public int getCount(double simTime) {
return entityList.size();
}
}