SimulatorStateTransceiver.java
- package org.opentrafficsim.sim0mq.publisher;
- import java.io.Serializable;
- import java.rmi.RemoteException;
- import org.djutils.event.Event;
- import org.djutils.event.EventListener;
- import org.djutils.event.EventProducer;
- import org.djutils.event.EventType;
- import org.djutils.event.LocalEventProducer;
- import org.djutils.event.TimedEvent;
- import org.djutils.metadata.MetaData;
- import org.djutils.metadata.ObjectDescriptor;
- import org.djutils.serialization.SerializationException;
- import org.opentrafficsim.core.dsol.OtsSimulatorInterface;
- import org.sim0mq.Sim0MQException;
- import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
- /**
- * Transceiver for simulator state change events.
- * <p>
- * Copyright (c) 2020-2024 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
- * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
- * </p>
- * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
- */
- public class SimulatorStateTransceiver extends AbstractTransceiver
- {
- /** The simulator. */
- private final OtsSimulatorInterface simulator;
- /** Multiplexes SimulatorInterface.START_EVENT and SimulatorInterface.STOP_EVENT. */
- @SuppressWarnings("checkstyle:visibilitymodifier")
- final EventProducer eventMultiplexer;
- /** The event that will be emitted for either the START_EVENT or the STOP_EVENT. */
- public static final EventType SIMULATOR_STATE_CHANGED = new EventType(new MetaData("SIMULATOR_STATE_CHANGED_EVENT",
- "simulator started or stopped", new ObjectDescriptor[] {new ObjectDescriptor("New simulator state",
- "New simulator state; true if running; false if stopped", Boolean.class)}));
- /**
- * Construct a new SimulatorStateTransceiver.
- * @param simulator OtsSimulatorInterface; the simulator
- * @throws RemoteException on network error
- */
- public SimulatorStateTransceiver(final OtsSimulatorInterface simulator) throws RemoteException
- {
- super("Simulator state transceiver", MetaData.EMPTY,
- new MetaData("SIMULATOR_STATE_CHANGED_EVENT", "simulator state changed"));
- this.simulator = simulator;
- this.eventMultiplexer = new EventMultiplexer(simulator);
- }
- /** {@inheritDoc} */
- @Override
- public Object[] get(final Object[] address, final ReturnWrapper returnWrapper)
- throws RemoteException, Sim0MQException, SerializationException
- {
- AbstractTransceiver.verifyMetaData(MetaData.EMPTY, address);
- String result = null;
- if (this.simulator.isInitialized())
- {
- if (this.simulator.isStartingOrRunning())
- {
- result = "Starting or running";
- }
- else
- {
- result = "Stopping or stopped";
- }
- }
- else
- {
- result = "Not (yet) initialized";
- }
- return new Object[] {result};
- }
- /** Result of the getLookupEventProducer method. */
- private LookupEventProducer lepi = new LookupEventProducer()
- {
- @Override
- public EventProducer lookup(final Object[] address, final ReturnWrapper returnWrapper)
- throws Sim0MQException, SerializationException
- {
- String bad = AbstractTransceiver.verifyMetaData(MetaData.EMPTY, address);
- if (null != bad)
- {
- returnWrapper.nack(bad);
- return null;
- }
- return SimulatorStateTransceiver.this.eventMultiplexer;
- }
- @Override
- public MetaData getAddressMetaData()
- {
- return MetaData.EMPTY;
- }
- };
- /**
- * Retrieve the event LookupEventProducer.
- * @return EventProducerInterface; the event multiplexer
- */
- public LookupEventProducer getLookupEventProducer()
- {
- return this.lepi;
- }
- }
- /**
- * Create a subscription to SimulatorInterface.START_EVENT and SimulatorInterface.STOP_EVENT and emit a SIMULATOR_STATE_CHANGED
- * event for each.
- */
- class EventMultiplexer extends LocalEventProducer implements EventListener
- {
- /** ... */
- private static final long serialVersionUID = 20200618L;
- /**
- * @param simulator OtsSimulatorInterface; the simulator
- * @throws RemoteException on network error
- */
- EventMultiplexer(final OtsSimulatorInterface simulator) throws RemoteException
- {
- simulator.addListener(this, SimulatorInterface.START_EVENT);
- simulator.addListener(this, SimulatorInterface.STOP_EVENT);
- }
- /** {@inheritDoc} */
- @Override
- public void notify(final Event event) throws RemoteException
- {
- notifyTimedEvent(event);
- }
- /**
- * Avoid a compilation error with Java 11. Could be bug https://bugs.openjdk.java.net/browse/JDK-8206142 which is
- * unsolved...
- * @param <C> the casting class for the event timestamp
- * @param event the event to be notified of
- */
- private <C extends Serializable & Comparable<C>> void notifyTimedEvent(final Event event)
- {
- @SuppressWarnings("unchecked")
- TimedEvent<C> timedEvent = (TimedEvent<C>) event;
- fireTimedEvent(SimulatorStateTransceiver.SIMULATOR_STATE_CHANGED,
- event.getType().equals(SimulatorInterface.START_EVENT), timedEvent.getTimeStamp());
- }
- }