madkit.kernel

## Class Scheduler

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

- All Implemented Interfaces:
    java.lang.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 and Description
    --- | ---
    `static class` | `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 and 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(java.time.LocalDateTime initialDate)` Constructs a `Scheduler` using a date-based time which relies on `LocalDateTime`

  - ### Method Summary

    All Methods Instance Methods Concrete Methods Deprecated Methods
    Modifier and Type | Method and 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, java.lang.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()`
    `javax.swing.JLabel` | `getGVTLabel()` Returns a label giving the simulation time
    `javax.swing.JMenu` | `getSchedulerMenu()` Returns a menu which could be used in any GUI.
    `javax.swing.JLabel` | `getSchedulerStatusLabel()` Returns a label giving some information on the simulation process
    `javax.swing.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: while (isAlive()) { if (GVT > getSimulationDuration()) { if (logger !
    `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` | `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, 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 Detail

    - #### 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(java.time.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 Detail

    - #### 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

    - #### 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 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,
                                    java.lang.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 javax.swing.JToolBar getSchedulerToolBar()

      Returns a toolbar which could be used in any GUI.
      Returns:
        a toolBar controlling the scheduler's actions

    - #### getSchedulerMenu

          public javax.swing.JMenu getSchedulerMenu()

      Returns a menu which could be used in any GUI.
      Returns:
        a menu controlling the scheduler's actions

    - #### getSchedulerStatusLabel

          public javax.swing.JLabel getSchedulerStatusLabel()

      Returns a label giving some information on the simulation process
      Returns:
        a label giving some information on the simulation process

    - #### getGVTLabel

          public javax.swing.JLabel getGVTLabel()

      Returns a label giving the simulation time
      Returns:
        a label giving the simulation time

Fabien Michel, Olivier Gutknecht, Jacques Ferber - September 9 2019