Initializes a new instance of the EntityGenerator class.
Type of Entity to generate.
RandomVar that defines the entity inter-arrival times, or a number repreenting a fixed interval, or null to generate a single entity.
Maximum number of entities to generate, or null to generate an unlimited number of entities.
Simulated time when entity generation should start, or null to start generating entities immediately.
Simulated time when entity generation should stop, or null to keep generating entities until the simulation reaches its timeEnd value.
Gets or sets a number that represents the entity's priority.
The default value for this property is 0.
Entities with higher priority will skip ahead of other entities when entering Queue objects and when finishing delays that end at the same simulated time.
Gets or sets a number that represents the entity's priority.
The default value for this property is 0.
Entities with higher priority will skip ahead of other entities when entering Queue objects and when finishing delays that end at the same simulated time.
Gets a serial number that uniquely identifies the Entity.
Gets a reference to the Simulation object that this entity is part of.
Async method that simulates a delay.
When this method is invoked, the Entity pauses execution for a given number of simulated time units.
For example, the script below causes the Customer entity to enter a service queue qJoe, then undergo a delay based on a service random variable, then leave the service queue:
class Customer extends Entity<BarberShop> {
service = new Uniform(15 - 3, 15 + 3);
async script() {
const shop = this.simulation;
await this.enterQueue(shop.qWait); // enter the line
await this.enterQueue(shop.qJoe); // seize Joe the barber
this.leaveQueue(shop.qWait); // leave the line
await this.delay(this.service.sample()); // get a haircut
this.leaveQueue(shop.qJoe); // free Joe
}
}
Note that calls to async methods such as delay, enterQueue, seize, and waitSignal should be preceded by the await keyword.
If you use the signal parameter to create an interruptible delay, the call to delay may return when the specified delay has elapsed or when the specified signal has been received. You can use this feature to implement preempting services. For example, the code below shows a preemt method:
class Preempt extends Entity {
// seizes a resource and applies an interruptible delay to allow
// higher-priority entities to preempt the service.
async preempt(resource: Queue, delay: number, trackingQueues: Queue[] = []) {
// while we have a delay
while (delay >= 1e-3) {
// send signal to interrupt lower-priority entities
this.sendSignal(resource);
// seize the resource
trackingQueues.forEach(q => this.enterQueueImmediately(q));
await this.enterQueue(resource);
trackingQueues.forEach(q => this.leaveQueue(q));
// apply interruptible delay and update delay value
delay -= await this.delay(delay, null, resource);
// release the resource (time-out or signal)
this.leaveQueue(resource);
}
}
}
Number of simulated time units to wait for.
IMovePath object containing information about how the entity should be animated during the delay.
Signal that can be used to interrupt the delay.
The amount of simulated time elapsed since the method was invoked.
Async method that waits until a Queue has enough capacity, then adds this Entity to the Queue seizing a specified number of capacity units.
An entity may enter multiple queues at once, but it cannot enter the same queue multiple times.
For example, the script below causes the Customer entity to enter a service queue qJoe, then undergo a delay based on a service random variable, then leave the service queue:
class Customer extends Entity<BarberShop> {
service = new Uniform(15 - 3, 15 + 3);
async script() {
const shop = this.simulation;
this.enterQueueImmediately(shop.qWait); // enter the line
await this.enterQueue(shop.qJoe); // seize Joe the barber
this.leaveQueue(shop.qWait); // leave the line
await this.delay(this.service.sample()); // get a haircut
this.leaveQueue(shop.qJoe); // free Joe
}
}
In the example above, the qWait queue has unlimited capacity. It does not restrict the flow of entities, but simply tracks how many queue capacity units were used and for how long.
The qJoe queue, on the other hand, does have limited capacity. Entities trying to enter it may experience delays, having to wait until there is enough capacity. Like qWait, it also tracks how many queue capacity units were used and for how long.
Note that calls to async methods such as delay, enterQueue, seize, and waitSignal should be preceded by the await keyword.
The amount of simulated time elapsed since the method was invoked.
This method is synchronous. It does not require an await and assumes the queue has enough capacity to take the entity.
This method is slightly more efficient than {@see enterQueue}, but should only be used if the Queue is guaranteed to have enough capacity.
For example:
class Customer extends Entity {
async script() {
let sim = this.simulation as MMC;
// enter waiting queue
if (sim.qWait.canEnter()) { // queue has enough capacity
this.enterQueueImmediately(sim.qWait); // no need to wait (faster)
} else {
await this.enterQueue(sim.qWait); // will have to wait (slower)
}
await this.enterQueue(sim.qService);
this.leaveQueue(sim.qWait);
await this.delay(sim.service.sample());
this.leaveQueue(sim.qService);
}
}
Gets an IAnimationPosition value used by the Animation class to position entities in animated queues.
By default, the Animation class animates entities in queues based on the queue location and angle, and on the entity's icon. This method allows you to override the default queue layout and provide custom positions for the entities in the queues.
For example, the code below overrides the getAnimationPosition method to calculate the entity's position and angle based on the entity's position along a car-following strip:
export class Car extends Entity implements ICarFollow {
speed = 0; // starting speed
accel = 10; // acceleration/deceleration
position = 0; // current position
maxSpeed = 0; // random value from simulation
async script() {
// script updates 'position'
// ...
}
// gets the car's animation position
getAnimationPosition(q: Queue, start: IPoint, end: IPoint): IAnimationPosition {
const
sim = this.simulation as CarFollow,
pt = Point.interpolate(start, end, this.position / sim.stripLength);
return {
position: pt,
angle: Point.angle(start, end, false)
}
}
}
Queue being animated.
Position of the queue's start.
Position of the queue's end.
An IAnimationPosition value used to position the entity in the animation, or null to use the standard queue layout.
Causes the Entity to leave a Queue it has previously entered using the enterQueue method.
Generates entities of a given type according to a schedule.
Seizes a resource (possibly preempting it), enters one or more waiting queues, performs a delay, and leaves the waiting queues and the resource.
This method provides a short way of telling an entity to enter one or more waiting queues, seize a resource, leave the waiting queues, use the resource for a while, and leave the resource. For example:
async script() {
// this call
await this.seize(sim.qResource, sim.delay.sample(), sim.qWait);
// does the same as this
this.enterQueueImmediately(sim.qWait);
await this.enterQueue(sim.qResource);
this.leaveQueue(sim.qWait);
await this.delay(sim.delay.sample());
this.leaveQueue(sim.qResource);
}
The seize method also allows you to specify a preempt signal, which is used to provide preemptive behavior. If used, entities with higher priority will be able to temporarily stop lower-priority entities, perform their work, and restore the suspended entities when done. For example:
async script() {
// execute some work allowing higher-priority entities to
// temporarily suspend the transaction and resume it later.
// (this example uses sim.qResource as a preempt signal)
await this.seize(sim.qResource, sim.delay.sample(), sim.qWait, sim.qResource);
}
Resource to seize.
Amount of time required to perform the work.
Waiting queues. Waiting queues should have unlimited capacity.
Signal used to pre-empt the resource (defaults to none).
Number of Queue capacity units to seize.
Sends a signal that releases entities currently waiting for the signal.
Signal value.
Maximum number of entities to release. If not specified, all entities waiting for the signal are released.
Pauses entity execution until another entity sends a signal.
For example, the code below shows how you could use the sendSignal and waitSignal methods to simulate a traffic light:
class Car extends Entity {
async script() {
let sim = this.simulation as CrossWalk;
// enter crossing wait area
await this.enterQueue(sim.qCarXing);
// wait for green light
while (sim.light != Signal.GREEN) {
await this.waitSignal(Signal.GREEN);
}
// leave crossing wait area
this.leaveQueue(sim.qCarXing);
}
}
class TrafficLight extends Entity {
async script() {
let sim = this.simulation as CrossWalk;
while (true) {
this.setLight(Signal.GREEN);
await this.delay(sim.cycle.green);
this.setLight(Signal.YELLOW);
await this.delay(sim.cycle.yellow);
this.setLight(Signal.RED);
await this.delay(sim.cycle.red);
}
}
setLight(value: Signal) {
const sim = this.simulation as CrossWalk;
sim.light = value;
let released = this.sendSignal(value);
console.log('light is', Signal[sim.light], released, 'entities released at', sim.timeNow);
}
}
Note that calls to async methods such as delay, enterQueue, seize, and waitSignal should be preceded by the await keyword.
Value of the the signal to wait for.
The amount of simulated time elapsed since the method was invoked.
Generated using TypeDoc
Class used internally by the Simulation.generateEntities method to create and activate entities according to a schedule.