Заявка (Entity)

Entityявляется базовым классом для всех заявок, которые создаются, работают с ресурсами и принимают участие в процессе, описанном Вами с помощью диаграммы из объектов Основной библиотеки AnyLogic. Базовым классом для ресурсов является ResourceUnit.

Под заявкой в Основной библиотеке может пониматься человек, документ, деталь, пакет данных, грузовик - все, что может являться объектом, для которого задан какой-то процесс.

Entity по сути является обычным Java классом с той функциональностью, которая необходима и достаточна для обработки и отображения анимации заявки объектами Основной библиотеки. Вы можете расширить эту функциональность добавлением дополнительных полей и методов и работой с ними из объектов диаграммы, описывающей Ваш процесс. 

Заявки в Основной библиотеке создаются с помощью объектов Source, Split, Combine и некоторых других. Уничтожаются же заявки обычно с помощью объекта Sink, хотя они могут уничтожаться и в других объектах. В любом случае, Вы должны быть уверены, что уничтоженная заявка не обладает никакими ресурсами и не находится в сети. Хорошей практикой является вызов метода checkDisposal(ActiveObject ao) у заявки, которая уничтожается не с помощью объекта Sink.

Содержимое заявки

Заявка может содержать другие заявки. Например, заявка Bus (автобус) может содержать заявки типа Passenger (пассажир). Ряд объектов позволяет работать с содержимым заявки: Pickup, Dropoff, Batch и Unbatch. Кроме того, у Вас есть программный доступ к содержимому заявки: 

LinkedList<Entity> contents - (доступное) содержимое заявки, до добавления первой заявки переменная равна null

addEntityToContents( Entity entity ) - метод добавляет заявку entity в содержимое этой заявки, создает переменную contents, если она равна null

Ресурсы, захваченные заявкой

Все ресурсы, захваченные заявкой (с помощью объектов Seize и Service) и еще не освобожденные (с помощью Release или Service), хранятся в переменной  resourceUnits:

LinkedList<ResourceUnit> resourceUnits - список ресурсов, захваченных заявкой, до добавления первого ресурса переменная равна null

addResourceUnit( ResourceUnit unit )[предназначен только для внутреннего использования] добавляет ресурс к заявке.

Пожалуйста, обратите внимание, что если захвачено определенное количество ресурсов, заданных объектом ResourcePool, моделирующем ресурсы Просто как их количество, а не как Индивидуальные объекты), то блок таких ресурсов будет представлен в этой коллекции ресурсов только одним объектом. Этот объект будет типа  ResourceUnitAggregated, и иметь одно поле - quantity, хранящее количество захваченных ресурсов этого типа.

Сетевые ресурсы хранятся в другой переменной, см. ниже.

Программный интерфейс, связанный с моделированием транспортных сетей

Если заявка находится в сети, то она хранит определенную информацию, связанную с ее пребыванием в этой сети. Пользователю предоставляется следующий программный интерфейс, большей частью предоставляемый также и классом ResourceUnit (посредством общего базового класса AnimatableItem):

setNetwork( Network network, ShapeRectangle location )[предназначен только для внутреннего использования] добавляет заявку в заданную сеть и помещает ее в указанное место сети.

Network getNetwork() - возвращает сеть, в которой находится заявка (если таковой нет, то возвращает null)

setNetworkLocation( ShapeRectangle location )[предназначен только для внутреннего использования] помещает заявку в указанное место сети

ShapeRectangle getNetworkLocation() - возвращает текущее местоположение (узел) заявки в сети или же последний узел, в котором она находилась, если в данный момент времени заявка движется

setNetworkSpeed( double speed ) - задает скорость движения заявки по сети

getNetworkSpeed() - возвращает скорость движения заявки по сети

setNetworkShown( boolean shown ) - [предназначен только для внутреннего использования] отображает или же прячет заявку в сети

boolean isNetworkShown() - проверяет, отображается ли заявка сетью в данный момент времени

LinkedList<ResourceUnit> getNetworkResourceUnits() - возвращает коллекцию сетевых ресурсов, захваченных заявкой (или null, если таковых нет)

ResourceUnit getNetworkResourceUnit( NetworkResourcePool pool ) - возвращает первый сетевой ресурс заданного типа из списка захваченных заявкой ресурсов.

Управление анимацией заявки

Основная библиотека предоставляет пользователям широкий спектр возможностей по управлению визуальным представлением заявок на презентации (эта функциональность предоставляется также и классом ResourceUnit (посредством общего базового класса AnimatableItem)). 

По умолчанию заявка отображается на анимации небольшим кружком случайно выбранного цвета. Если Вас устраивает такой внешний вид, но Вы хотите изменить цвет на  какой-то определенный, используйте следующие методы:

setColor(Color color) - задает цвет кружка (принятой по умолчанию анимации)

Color getColor() - возвращает цвет принятой по умолчанию анимации

Если Вы хотите присвоить заявке какую-то другую фигуру анимации (или группу фигур), Вы должны сделать следующее. Если фигура должна быть присвоена заявке во время ее создания, Вы должны указать фигуру в поле параметра Фигура анимации заявки объекта Source. Если затем Вы захотите изменить фигуру во время выполнения модели (отразив, тем самым, например, изменение состояния заявки), Вы можете воспользоваться следующими методами:

setShape(Shape shape) - задает фигуру анимации заявки

getShape() - возвращает фигуру анимации заявки

Пожалуйста, обратите внимание, что если Вы присвоите одну и ту же фигуру сразу нескольким заявкам, все они будут отображаться на презентации одинаково, т.е. при попытке изменить анимацию одной заявки Вы измените анимации всех этих заявок. Если Вы хотите иметь уникальную фигуру анимации у каждой заявки, чтобы иметь возможность индивидуально настраивать свойства каждой анимации, используйте опцию Уникальная фигура для каждой заявки соответствующего объекта Source или самостоятельно присвойте уникальную фигуру каждой заявке.

Когда заявка отображается на анимации, она отображается относительно фигуры анимации того объекта, в котором заявка находится в текущий момент времени. Если у этого объекта выбран Тип анимации Путь (или если заявка движется по сети), то фигура анимации заявки будет направлена согласно направлению ее движения, т.е. она будет поворачиваться при изменении этого направления. Иногда это нежелательно, поэтому мы предоставляем возможность запрещения вращения заявки:

enableRotation( boolean yes ) - разрешает или запрещает вращение анимации заявки

isRotationEnabled() - проверяет, разрешено ли вращение заявки.

Кроме того, Вы можете сместить положение и угол поворота анимации заявки относительно места и угла поворота, заданных фигурой анимации соответствующего объекта:

void setOffsets( double dx, double dy, double da ) - задает смещение места и угла поворота анимации заявки относительно места и угла поворота, заданных фигурой анимации соответствующего объекта.

void resetOffsets() - "сбрасывает" значения всех смещений анимации (x,y и угол поворота) в 0.

Вы также можете узнать текущие значения смещений:

getOffsetX()- возвращает смещение анимации заявки по оси x относительно места, определенного заданной фигурой анимации соответствующего объекта.

getOffsetY()- возвращает смещение анимации заявки по оси y относительно места, определенного заданной фигурой анимации соответствующего объекта.

double getOffsetAngle() - возвращает угол дополнительного поворота анимации заявки относительно поворота, определенного заданной фигурой анимации соответствующего объекта.

Возможность сдвигать анимацию позволяет Вам, например, помещать анимацию заявки рядом с анимацией ресурса, захваченного этой заявкой. Имеет смысл использовать Тип анимации объекта Одиночная, чтобы Вы были уверены, что координаты анимации одинкаовы для всех заявок.

Кроме того, Вы можете переопределить метод draw(), реализующий весь процесс отрисовки анимации заявки:

void draw( Panel panel, Graphics2D g, AffineTransform xform, double x, double y, double angle, boolean publicOnly ) - отрисовывает заявку в заданном контексте.

В любой момент времени Вы можете получить координаты и угол поворота анимации заявки с помощью следующих методов:

double getX() - возвращает x координату анимации заявки (с учетом смещения, если оно есть), если же заявка не отображается на анимации, то возвращает  0.

double getY() - возвращает y координату анимации заявки (с учетом смещения, если оно есть), если же заявка не отображается на анимации, то возвращает  0.

double getAngle() - возвращает угол поворота анимации заявки (с учетом смещения, если оно есть), если же заявка не отображается на анимации, то возвращает  0.

Position getPosition( Position pos ) - получает координаты и угол поворота анимации заявки (с учетом смещений, если они есть) и помещает их в существующий объект Position, переданный в качестве аргумента метода, или, если его значение равно null, создает новый объект и возвращает его. Если заявка не отображается на анимации, возвращает null. Этот метод более эффективен, чем методы getX() и т.д., поскольку он позволяет повторно использовать объект Position и избегать создания еще одного объекта (что случается при каждом вызове getX() и т.д.). Класс Position представляет собой простую структуру данных с тремя полями типа double: x, y, и angle.

Эти методы применимы как к "обычным" анимациям (предоставляемыми объектами Delay, Queue и т.д.), так и к анимациям моделей транспортных сетей. Возвращаемые методами координаты являются относительными (в случае "обычной" анимации они считаются относительно группы, к которой принадлежит фигура анимации объекта, а в случае анимации транспортных сетей - относительно группы фигур сети).

Создание и использование нестандартных классов заявок

 Чтобы создать нестандартный класс заявки

  1. В панели Проект, щелкните правой кнопкой мыши по модели (элемент верхнего уровня дерева) и выберите Создать|Java класс
  2. Введите имя нового класса (например, Customer) и выберите com.xj.anylogic.libraries.enterprise.Entity в качестве базового класса (если Ваша модель уже содержит какие-то объекты Основной библиотеки, то этот класс можно будет выбрать из выпадающего списка). Щелкните по кнопке Далее.
  3. Задайте значения полей класса, например, timeArrived типа double и waitingTime типа double. Оставьте выбранными флажки Создать конструктор и Создать метод toString(). Щелкните по кнопке Готово.
Вы увидите редактор кода, в котором будет показан автоматически созданный код Вашего Java класса. Изучив этот код, можно легко понять, как можно самостоятельно добавлять в класс заявки новые поля и методы. Обратите внимание, что у класса были созданы сразу два конструктора: один, по умолчанию, без параметров, и второй, с параметрами, инициализирующими поля класса. Эти конструкторы используются объектами, создающими новые заявки, такими, как Source.

Чтобы создавать заявки нестандартного типа, скажем, Customer, Вам нужно поместить вызов конструктора этого типа в поле Новая заявка соответствующего объекта, например, Source. Однако хоть заявки в потоке теперь и будут типа Customer, объекты потоковой диаграммы будут продолжать считать их заявками типа Entity, и не позволят явно обращаться к дополнительной функциональности класса Customer. Чтобы разрешить доступ к полям нестандартного класса заявки в коде динамических параметров объектов потоковой диаграммы, Вам нужно указать имя нестандартного класса заявки в качестве Класса заявки этого объекта. Если, например, Вы знаете, что через объект  Delay будут проходить только заявки класса Customer, Вы должны написать Customer в поле Класс заявки этого объекта Delay. Тогда Вы сможете написать код entity.serviceTime = delayTime в параметре объекта Действие при входе. Пожалуйста, обратите внимание, что если какие-то заяки в Вашем потоке заявок имеют тип Customer, а какие-то - скажем, Staff, то Вы должны оставить в качестве класса заявки значение по умолчанию  (Entity), и самостоятельно анализировать класс поступающей заявки, написав, например if(entity instanceof Customer) ((Customer)entity).serviceTime = delayTime.