package srsim.simulator;
import java.io.IOException;
import java.net.URL;
import java.util.List;
import srsim.domain.Room;
import srsim.domain.Simulation;
import srsim.io.ConfigurationManager;
import srsim.io.PreferencesServer;
import srsim.persistence.IDataStore;
/**
* The smartroom simulator class initializes and controlls the simulation.
*
* @author phil
*
*/
public class SmartRoomSimulator extends Thread implements ISimulationController {
private boolean running;
private Simulation simulation;
private SimulationTracker tracker;
private PreferencesServer preferencesServer;
private void init(final IDataStore dataStore) {
setName("SmartRoomSimulator");
running = false;
simulation = new Simulation(new SystemTimeTimeSource());
if (dataStore != null) {
tracker = new SimulationTracker(this, dataStore);
}
}
public SmartRoomSimulator() {
init(null);
}
public SmartRoomSimulator(final IDataStore dataStore) {
init(dataStore);
}
@Override
public void startSimulation() {
if (running == false) {
running = true;
if (tracker != null) {
tracker.track();
}
start();
}
}
/**
* Returns true if a simulation is currently in progress
*
* @return
*/
public boolean isRunning() {
return running;
}
@Override
public void run() {
try {
while (running && !simulation.isFinished()) {
simulation.step();
}
} catch (SimulationContextException e) {
System.err.println(e.getMessage());
} catch (InterruptedException e) {
System.err.println(e.getMessage());
}
}
@Override
public void stopSimulation() throws InterruptedException {
running = false;
if (tracker != null) {
tracker.shutDown();
}
join();
}
@Override
public void addRoom(final Room room) {
simulation.addRoom(room);
}
@Override
public List<Room> getRooms() {
return simulation.getRooms();
}
@Override
public void addSimulationListener(final IContextListener simulationListener) {
if (simulationListener instanceof ISimulationListener) {
simulation
.addSimulationListener((ISimulationListener) simulationListener);
}
}
@Override
public void readConfiguration(final URL url) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException,
SimulationContextException, SimulationConfigurationException {
simulation = ConfigurationManager.readFromFile(url);
simulation.addSimulationListener(tracker);
}
@Override
public void writeConfiguration(final String fileName)
throws SimulationContextException, IOException {
ConfigurationManager.writeToFile(fileName, simulation);
}
@Override
public void setPreference(final String roomId, final String key,
final String value) throws SimulationContextException {
if (roomId == null) {
simulation.getContext().setPreference(key, value);
} else {
for (Room room : simulation.getRooms()) {
if (room.getName().equalsIgnoreCase(roomId)) {
room.getLocalContext().setPreference(key, value);
}
}
}
}
@Override
public void unsetPreference(final String roomId, final String key,
final String value) throws SimulationContextException {
if (roomId == null) {
simulation.getContext().unsetPreference(key, value);
} else {
for (Room room : simulation.getRooms()) {
if (room.getName().equalsIgnoreCase(roomId)) {
room.getLocalContext().unsetPreference(key, value);
}
}
}
}
/**
* Starts listening for client connections on the given port
*
* @param port
* @throws IOException
*/
public void listenForClients(final int port) throws IOException {
preferencesServer = new PreferencesServer(this);
preferencesServer.listen(port, true);
}
@Override
public void shutDown() throws InterruptedException, IOException {
if (running) {
stopSimulation();
}
if (preferencesServer != null) {
preferencesServer.shutDown();
}
join();
}
@Override
public void setPresence(final String roomId, final String clientAddress)
throws SimulationContextException {
for (Room room : simulation.getRooms()) {
if (room.getName().equalsIgnoreCase(roomId)) {
room.getLocalContext().setPresence(clientAddress);
break;
}
}
}
@Override
public void unsetPresence(final String clientAddress)
throws SimulationContextException {
for (Room room : simulation.getRooms()) {
SimulationContext context = room.getLocalContext();
if (context.getPresentSubjects().contains(clientAddress)) {
context.unsetPresence(clientAddress);
break;
}
}
}
@Override
public long getTimeStamp() throws SimulationContextException {
return simulation.getContext().getTimeSource().getTimeStamp();
}
}