package com.twasyl.slideshowfx.services;
import com.twasyl.slideshowfx.concurrent.SavePresentationTask;
import com.twasyl.slideshowfx.engine.presentation.PresentationEngine;
import com.twasyl.slideshowfx.global.configuration.GlobalConfiguration;
import com.twasyl.slideshowfx.utils.PlatformHelper;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.util.Duration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* An implementation of a {@link ScheduledService} that saves regularly the {@link PresentationEngine presentation}
* registered to it.
* @author Thierry Wasylczenko
* @version 1.0.0
* @since SlideshowFX 1.0
*/
public class AutoSavingService extends ScheduledService<Void> {
private static final Set<AutoSavingService> runningServices = new HashSet<>();
private final PresentationEngine presentation;
/**
* Creates a service for auto saving a presentation. The {@link ScheduledService#delay delay} and
* {@link ScheduledService#period period} are automatically set according the
* {@link GlobalConfiguration#getAutoSavingInterval()} if it is not {@code null}.
* @param presentation The presentation to auto save.
*/
public AutoSavingService(PresentationEngine presentation) {
this.setRestartOnFailure(true);
this.presentation = presentation;
final Long interval = GlobalConfiguration.getAutoSavingInterval();
if(interval != null) this.setDelayAndPeriod(interval);
runningServices.add(this);
}
@Override
protected Task<Void> createTask() {
final SavePresentationTask task = new SavePresentationTask(this.presentation);
return task;
}
@Override
protected void executeTask(Task<Void> task) {
super.executeTask(task);
}
/**
* Set the delay and period to this service.
* @param delayInMinutes The delay in minutes.
*/
protected void setDelayAndPeriod(final long delayInMinutes) {
this.setDelay(Duration.minutes(delayInMinutes));
this.setPeriod(Duration.minutes(delayInMinutes));
}
/**
* Resume all services that have been cancelled.
*/
public static void resumeAll() {
runningServices.forEach(service -> PlatformHelper.run(() -> service.restart()));
}
/**
* Cancel all services that are registered.
*/
public static void cancelAll() {
final Iterator<AutoSavingService> iterator = runningServices.iterator();
while(iterator.hasNext()) {
iterator.next().cancel();
iterator.remove();
}
}
/**
* Cancel the service for a given presentation.
* @param presentation The presentation to cancel the auto saving service for.
*/
public static void cancelFor(final PresentationEngine presentation) {
if(presentation != null) {
final long id = presentation.getConfiguration().getId();
runningServices.stream()
.filter(service -> service.presentation.getConfiguration().getId() == id)
.findFirst()
.ifPresent(service -> {
service.cancel();
runningServices.remove(service);
});
}
};
/**
* Change the delay and the period for all {@link AutoSavingService services}. Each service is then restarted.
* @param delayInMinutes The new delay in minutes.
*/
public static void setDelayForAllServices(final long delayInMinutes) {
runningServices.forEach(service -> {
service.setDelayAndPeriod(delayInMinutes);
service.restart();
});
}
}