Package madkit.kernel

# Class Scheduler

java.lang.Object
madkit.kernel.AbstractAgent
madkit.kernel.Agent
madkit.kernel.Scheduler

All Implemented Interfaces:
  `Comparable<AbstractAgent>`

Direct Known Subclasses:
  `DateBasedDiscreteEventScheduler`

public class Scheduler extends Agent

     Scheduler is the core agent for defining multi-agent based simulations.

     This class defines a generic threaded agent which is in charge of activating
     the simulated agents using Activator. Activator are tool
     objects which are able to trigger any available method belonging to the
     agents that have a role within a group.

     The purpose of this approach is to allow the manipulation of agents
     regardless of their concrete Java classes.

     So a scheduler holds a collection of activators that target specific groups
     and roles and thus allow to define very complex scheduling policies if
     required. A default behavior is implemented and corresponds to the triggering
     of the activators according to the order in which they have been added to the
     scheduler engine using addActivator(Activator).

     The default state of a scheduler is Scheduler.SimulationState.PAUSED.

     The default delay between two simulation steps is 0 milliseconds (max speed).

     Default GUI components are defined for this agent and they could be easily
     integrated in any GUI.

     As of MaDKit 5.3, two different temporal schemes could used:
     tick-based: The time is represented as a BigDecimal which is
     incremented at will. BigDecimal is used to avoid rounding errors that
     may happen when working with double values. This is the preferred choice if
     the simulation is based on simple loop following a discrete time approach.

     date-based: The time is represented using LocalDateTime. This is
     far more convenient when the model refers to a real-world case for which
     representing usual temporal units such as hours or weeks is required (the
     default used unit is ChronoUnit.SECONDS). This mode also allow to
     handle agents that evolve considering different time scales or during
     specific period of the day.

     Those two modes are exclusive and can be selected using the corresponding
     constructor of the scheduler

Since:
  MaDKit 2.0
Version:
  5.3
Author:
  Fabien Michel
See Also:
  - `Activator`
  - `BigDecimal`
  - `LocalDateTime`

- ## Nested Class Summary

  Nested Classes
  Modifier and Type
  Class
  Description
  `static enum`
  `Scheduler.SimulationState`
  A simulation state.
  `static interface`
  `Scheduler.SimulationTime`

  ## Nested classes/interfaces inherited from class madkit.kernel.AbstractAgent

  `AbstractAgent.ReturnCode, AbstractAgent.State`

- ## Constructor Summary

  Constructors
  Constructor
  Description
  `Scheduler()`
  Constructs a `Scheduler` using a tick-based `Scheduler.SimulationTime`.
  `Scheduler(double endTick)`
  Constructs a `Scheduler` using a tick-based that will end the simulation for the specified tick.
  `Scheduler(LocalDateTime initialDate)`
  Constructs a `Scheduler` using a date-based time which relies on `LocalDateTime`

- ## Method Summary

  Modifier and Type
  Method
  Description
  `void`
  `addActivator(Activator<? extends AbstractAgent> activator)`
  Adds an activator to the simulation engine.
  `protected void`
  `checkMail(Message m)`
  Changes my state according to a `SchedulingMessage` and sends a reply to the sender as acknowledgment.
  `void`
  `doSimulationStep()`
  Defines a default simulation loop which is automatically during the scheduler's life.
  `protected void`
  `end()`
  This method corresponds to the last behavior which is called by the MaDKit kernel.
  `void`
  `executeAndLog(Activator<? extends AbstractAgent> activator, Object... args)`
  Triggers the execute method of this `activator` and logs it using the `Level.FINER` logging level
  `int`
  `getDelay()`
  Returns the delay between two simulation steps
  `double`
  `getGVT()`
  Deprecated.
  as of MaDKit 5.3, replaced by `AbstractAgent.getSimulationTime()`
  `JLabel`
  `getGVTLabel()`
  Returns a label giving the simulation time
  `JMenu`
  `getSchedulerMenu()`
  Returns a menu which could be used in any GUI.
  `JLabel`
  `getSchedulerStatusLabel()`
  Returns a label giving some information on the simulation process
  `JToolBar`
  `getSchedulerToolBar()`
  Returns a toolbar which could be used in any GUI.
  `double`
  `getSimulationDuration()`
  Deprecated.
  as of MDK 5.3, replaced by `AbstractAgent.getSimulationTime()` available methods
  `Scheduler.SimulationState`
  `getSimulationState()`
  The state of the simulation.
  `protected void`
  `live()`
  Scheduler's default behavior. default code is:
  `void`
  `logActivationStep()`
  Logs the current simulation step value.
  `protected void`
  `paused()`
  Runs `checkMail(Message)` every 1000 ms.
  `void`
  `removeActivator(Activator<? extends AbstractAgent> activator)`
  Removes an activator from the simulation engine.
  `void`
  `removeAllActivators()`
  Remove all the activators which have been previously added
  `void`
  `setActivatorPriority(Activator<? extends AbstractAgent> activator, int priority)`
  Sets the priority of an `Activator`.
  `void`
  `setDelay(int delay)`
  Sets the delay between two simulation steps.
  `void`
  `setGVT(double value)`
  Deprecated.
  as of MaDKit 5.3, replaced by `AbstractAgent.getSimulationTime()`
  `void`
  `setSimulationDuration(double endTime)`
  Deprecated.
  as of MDK 5.3, replaced by `AbstractAgent.getSimulationTime()` available methods
  `protected void`
  `setSimulationState(Scheduler.SimulationState newState)`
  Changes the state of the scheduler
  `void`
  `setupFrame(AgentFrame frame)`
  Setup the default Scheduler GUI when launched with the default MaDKit GUI mechanism.

  ### Methods inherited from class madkit.kernel.Agent

  `broadcastMessageWithRoleAndWaitForReplies, getThreadPriority, isDaemon, killAgent, pause, sendMessageAndWaitForReply, sendMessageAndWaitForReply, sendMessageAndWaitForReply, sendMessageAndWaitForReply, sendMessageWithRoleAndWaitForReply, sendMessageWithRoleAndWaitForReply, sendMessageWithRoleAndWaitForReply, sendMessageWithRoleAndWaitForReply, sendReplyAndWaitForReply, sendReplyAndWaitForReply, sendReplyWithRoleAndWaitForReply, sendReplyWithRoleAndWaitForReply, setThreadPriority, waitAnswer, waitAnswer, waitNextMessage, waitNextMessage, waitNextMessage, waitNextMessage`

  ### Methods inherited from class madkit.kernel.AbstractAgent

  `activate, broadcastMessage, broadcastMessageWithRole, bucketModeCreateGroup, bucketModeRequestRole, checkAgentAddress, compareTo, createGroup, createGroup, createGroup, createGroupIfAbsent, createGroupIfAbsent, createGroupIfAbsent, createGUIOnStartUp, destroyCommunity, destroyGroup, destroyRole, executeThisAgent, executeThisAgent, executeThisAgent, getAgentAddressIn, getAgentsWithRole, getAgentsWithRole, getAgentWithRole, getDistantAgentWithRole, getExistingCommunities, getExistingGroups, getExistingRoles, getKernelAddress, getLastReceivedMessage, getLastReceivedMessage, getLogger, getMadkitConfig, getMadkitProperty, getMadkitProperty, getMyGroups, getMyRoles, getName, getNetworkID, getNextEventDate, getOrganizationSnapShot, getReplyTo, getServerInfo, getSimpleNetworkID, getSimulationTime, getState, hasGUI, hashCode, hasRole, isAlive, isCommunity, isGroup, isKernelOnline, isMadkitPropertyTrue, isMessageBoxEmpty, isRole, killAgent, launchAgent, launchAgent, launchAgent, launchAgent, launchAgent, launchAgent, launchAgent, launchAgent, launchAgentBucket, launchAgentBucket, launchAgentBucket, launchAgentBucket, launchNode, launchXmlAgents, leaveGroup, leaveRole, nextMessage, nextMessage, nextMessages, proceedEnumMessage, purgeMailbox, receiveMessage, reload, requestRole, requestRole, sendMessage, sendMessage, sendMessageWithRole, sendMessageWithRole, sendReply, sendReplyWithRole, setLogLevel, setMadkitProperty, setMadkitProperty, setName, toString`

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Constructor Details

  - ### Scheduler

    public Scheduler()
    Constructs a `Scheduler` using a tick-based `Scheduler.SimulationTime`.

  - ### Scheduler

    public Scheduler(double endTick)
    Constructs a `Scheduler` using a tick-based that will end the simulation for the specified tick.
    Parameters:
      `endTick` - the tick at which the simulation will automatically stop

  - ### Scheduler

    public Scheduler(LocalDateTime initialDate)
    Constructs a `Scheduler` using a date-based time which relies on `LocalDateTime`
    Parameters:
      `initialDate` - the date at which the simulation should begin e.g. `LocalDateTime.of(1, 1, 1, 0, 0)` the initial date of the simulation

- ## Method Details

  - ### getDelay

    public int getDelay()
    Returns the delay between two simulation steps
    Returns:
      the delay between two simulation steps.

  - ### setDelay

    public void setDelay(int delay)
    Sets the delay between two simulation steps. That is the real time pause between two calls of `doSimulationStep()`. Using the Scheduler's GUI, the value can be adjusted from 0 to 400.
    Parameters:
      `delay` - the real time pause between two steps in milliseconds, an integer between 0 and 400: O is max speed.

  - ### getGVT

    public double getGVT()
    Deprecated.
    as of MaDKit 5.3, replaced by `AbstractAgent.getSimulationTime()`
    Returns the simulation current tick.
    Returns:
      the gVT

  - ### setGVT

    public void setGVT(double value)
    Deprecated.
    as of MaDKit 5.3, replaced by `AbstractAgent.getSimulationTime()`
    Sets the simulation global virtual time.
    Parameters:
      `value` - the current simulation time

  - ### setupFrame

    public void setupFrame(AgentFrame frame)
    Setup the default Scheduler GUI when launched with the default MaDKit GUI mechanism.
    Overrides:
      `setupFrame` in class `AbstractAgent`
    Parameters:
      `frame` - the default frame which has been created by MaDKit for this agent.
    See Also:
      - `AbstractAgent.setupFrame(AgentFrame)`

  - ### addActivator

    public void addActivator(Activator<? extends AbstractAgent> activator)
    Adds an activator to the simulation engine. This has to be done to make an activator work properly.
    Parameters:
      `activator` - an activator.
    Since:
      MaDKit 5.0.0.8

  - ### setActivatorPriority

    public void setActivatorPriority(Activator<? extends AbstractAgent> activator, int priority)
    Sets the priority of an `Activator`.
    Parameters:
      `activator` -
      `priority` -

  - ### removeActivator

    public void removeActivator(Activator<? extends AbstractAgent> activator)
    Removes an activator from the simulation engine.
    Parameters:
      `activator` - an activator.

  - ### doSimulationStep

    public void doSimulationStep()
    Defines a default simulation loop which is automatically during the scheduler's life. This method should be overridden to define a customized scheduling policy. By default, it executes all the activators in the order they have been added, using `Activator.execute(Object...)`, and then increments the simulation time by one unit. Default implementation is:

         logActivationStep();
         for (final Activator<? extends AbstractAgent> activator : activators) {
                executeAndLog(activator);
         }
         getSimulationTime().addOneTimeUnit();

    By default logs are displayed only if `AbstractAgent.getLogger()` is set above `Level.FINER`.

  - ### logActivationStep

    public void logActivationStep()
    Logs the current simulation step value. logs are displayed only if `AbstractAgent.getLogger()` is set above `Level.FINER`.

  - ### executeAndLog

    public void executeAndLog(Activator<? extends AbstractAgent> activator, Object... args)
    Triggers the execute method of this `activator` and logs it using the `Level.FINER` logging level
    Parameters:
      `activator` - the activator to trigger
      `args` - the args that will be passed to the targeted method

  - ### end

    protected void end()
    Description copied from class: `AbstractAgent`
    This method corresponds to the last behavior which is called by the MaDKit kernel. This call occurs when a threaded agent normally exits its live method or when the agent is killed. Usually a good place to release taken resources or log what has to be logged. It has to be noted that the kernel automatically takes care of removing the agent from the organizations it is in. However, this cleaning is not logged by the agent. Therefore it could be of interest for the agent to do that itself.

    Here is a typical example:

         @Override
         protected void end()
         {
                AbstractAgent.ReturnCode returnCode = leaveRole("a community", "a group", "my role");
                if (returnCode == AbstractAgent.ReturnCode.SUCCESS){
                        if(logger != null)
                                logger.info("I am leaving the artificial society");
                }
                else{
                        if(logger != null)
                                logger.warning("something wrong when ending, return code is "+returnCode);
                }
                if(logger != null)
                        logger.info("I am done");
                }
         }

    Overrides:
      `end` in class `AbstractAgent`

  - ### getSimulationState

    public Scheduler.SimulationState getSimulationState()
    The state of the simulation.
    Returns:
      the state in which the simulation is.
    See Also:
      - `Scheduler.SimulationState`

  - ### setSimulationState

    protected void setSimulationState(Scheduler.SimulationState newState)
    Changes the state of the scheduler
    Parameters:
      `newState` - the new state

  - ### live

    protected void live()
    Scheduler's default behavior. default code is:

         while (isAlive()) {
                if (GVT > getSimulationDuration()) {
                        if (logger != null)
                                logger.info("Simulation has reached end time -> " + getSimulationDuration());
                        return;
                }
                pause(getDelay());
                checkMail(nextMessage());
                switch (getSimulationState()) {
                case RUNNING:
                        doSimulationStep();
                        break;
                case PAUSED:
                        paused();
                        break;
                case STEP:
                        simulationState = PAUSED;
                        doSimulationStep();
                        break;
                case SHUTDOWN:
                        return; // shutdown
                default:
                        getLogger().severe("state not handled " + getSimulationState);
                }
         }

    Overrides:
      `live` in class `Agent`
    See Also:
      - `Agent.live()`

  - ### checkMail

    protected void checkMail(Message m)
    Changes my state according to a `SchedulingMessage` and sends a reply to the sender as acknowledgment.
    Parameters:
      `m` - the received message

  - ### paused

    protected void paused()
    Runs `checkMail(Message)` every 1000 ms.

  - ### removeAllActivators

    public void removeAllActivators()
    Remove all the activators which have been previously added

  - ### setSimulationDuration

    @Deprecated public void setSimulationDuration(double endTime)
    Deprecated.
    as of MDK 5.3, replaced by `AbstractAgent.getSimulationTime()` available methods
    Sets the simulation time for which the scheduler should end the simulation.
    Parameters:
      `endTime` - the end time to set

  - ### getSimulationDuration

    public double getSimulationDuration()
    Deprecated.
    as of MDK 5.3, replaced by `AbstractAgent.getSimulationTime()` available methods
    Returns:
      the simulationDuration

  - ### getSchedulerToolBar

    public JToolBar getSchedulerToolBar()
    Returns a toolbar which could be used in any GUI.
    Returns:
      a toolBar controlling the scheduler's actions

  - ### getSchedulerMenu

    public JMenu getSchedulerMenu()
    Returns a menu which could be used in any GUI.
    Returns:
      a menu controlling the scheduler's actions

  - ### getSchedulerStatusLabel

    public JLabel getSchedulerStatusLabel()
    Returns a label giving some information on the simulation process
    Returns:
      a label giving some information on the simulation process

  - ### getGVTLabel

    public JLabel getGVTLabel()
    Returns a label giving the simulation time
    Returns:
      a label giving the simulation time