Add a few predicates and actions for the event system
This commit is contained in:
parent
f7dfabb898
commit
1fc16a0d41
|
@ -26,12 +26,10 @@ import com.squareup.moshi.Types;
|
|||
|
||||
import ctbrec.Config;
|
||||
import ctbrec.Model;
|
||||
import ctbrec.OS;
|
||||
import ctbrec.StringUtil;
|
||||
import ctbrec.Version;
|
||||
import ctbrec.event.Event;
|
||||
import ctbrec.event.EventBusHolder;
|
||||
import ctbrec.event.LogReaction;
|
||||
import ctbrec.event.ModelStateChangedEvent;
|
||||
import ctbrec.io.HttpClient;
|
||||
import ctbrec.recorder.LocalRecorder;
|
||||
|
@ -73,7 +71,7 @@ public class CamrecApplication extends Application {
|
|||
private TabPane rootPane = new TabPane();
|
||||
private List<Site> sites = new ArrayList<>();
|
||||
public static HttpClient httpClient;
|
||||
|
||||
public static String title;
|
||||
|
||||
@Override
|
||||
public void start(Stage primaryStage) throws Exception {
|
||||
|
@ -114,7 +112,8 @@ public class CamrecApplication extends Application {
|
|||
|
||||
private void createGui(Stage primaryStage) throws IOException {
|
||||
LOG.debug("Creating GUI");
|
||||
primaryStage.setTitle("CTB Recorder " + getVersion());
|
||||
CamrecApplication.title = "CTB Recorder " + getVersion();
|
||||
primaryStage.setTitle(title);
|
||||
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
||||
primaryStage.getIcons().add(new Image(icon));
|
||||
int windowWidth = Config.getInstance().getSettings().windowWidth;
|
||||
|
@ -230,10 +229,11 @@ public class CamrecApplication extends Application {
|
|||
if (e.getType() == MODEL_STATUS_CHANGED) {
|
||||
ModelStateChangedEvent evt = (ModelStateChangedEvent) e;
|
||||
Model model = evt.getModel();
|
||||
if (evt.getNewState() == ONLINE) {
|
||||
if (evt.getNewState() == ONLINE && primaryStage != null && primaryStage.getTitle() != null) {
|
||||
String header = "Model Online";
|
||||
String msg = model.getDisplayName() + " is now online";
|
||||
OS.notification(primaryStage.getTitle(), header, msg);
|
||||
LOG.debug(msg);
|
||||
//OS.notification(primaryStage.getTitle(), header, msg);
|
||||
}
|
||||
}
|
||||
} catch (Exception e1) {
|
||||
|
@ -242,13 +242,16 @@ public class CamrecApplication extends Application {
|
|||
}
|
||||
});
|
||||
|
||||
EventBusHolder.BUS.register(new Object() {
|
||||
LogReaction reaction = new LogReaction();
|
||||
@Subscribe
|
||||
public void modelEvent(Event e) {
|
||||
reaction.reactToEvent(e);
|
||||
}
|
||||
});
|
||||
// EventBusHolder.BUS.register(new Object() {
|
||||
// URL url = CamrecApplication.class.getResource("/Oxygen-Im-Highlight-Msg.mp3");
|
||||
// PlaySound playSound = new PlaySound(url);
|
||||
// EventHandler reaction = new EventHandler(playSound);
|
||||
// // LogReaction reaction = new LogReaction();
|
||||
// @Subscribe
|
||||
// public void modelEvent(Event e) {
|
||||
// reaction.reactToEvent(e);
|
||||
// }
|
||||
// });
|
||||
|
||||
|
||||
LOG.debug("Alert System registered");
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package ctbrec.ui.controls;
|
||||
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.geometry.Pos;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.scene.layout.StackPane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class Wizard extends BorderPane {
|
||||
|
||||
private Pane[] pages;
|
||||
private StackPane stack;
|
||||
private Stage stage;
|
||||
private int page = 0;
|
||||
private Button next;
|
||||
private Button prev;
|
||||
private Button finish;
|
||||
|
||||
public Wizard(Stage stage, Pane... pages) {
|
||||
this.stage = stage;
|
||||
this.pages = pages;
|
||||
|
||||
if (pages.length == 0) {
|
||||
throw new IllegalArgumentException("Provide at least one page");
|
||||
}
|
||||
|
||||
createUi();
|
||||
}
|
||||
|
||||
private void createUi() {
|
||||
stack = new StackPane();
|
||||
setCenter(stack);
|
||||
|
||||
next = new Button("Next");
|
||||
next.setOnAction(evt -> nextPage());
|
||||
prev = new Button("Prev");
|
||||
prev.setOnAction(evt -> prevPage());
|
||||
Button cancel = new Button("Cancel");
|
||||
cancel.setOnAction(evt -> stage.close());
|
||||
finish = new Button("Finish");
|
||||
HBox buttons = new HBox(5, prev, next, cancel, finish);
|
||||
buttons.setAlignment(Pos.BASELINE_RIGHT);
|
||||
setBottom(buttons);
|
||||
BorderPane.setMargin(buttons, new Insets(5));
|
||||
|
||||
if (pages.length != 0) {
|
||||
stack.getChildren().add(pages[0]);
|
||||
}
|
||||
setButtonStates();
|
||||
}
|
||||
|
||||
private void prevPage() {
|
||||
page = Math.max(0, --page);
|
||||
stack.getChildren().clear();
|
||||
stack.getChildren().add(pages[page]);
|
||||
setButtonStates();
|
||||
}
|
||||
|
||||
private void nextPage() {
|
||||
page = Math.min(pages.length - 1, ++page);
|
||||
stack.getChildren().clear();
|
||||
stack.getChildren().add(pages[page]);
|
||||
setButtonStates();
|
||||
}
|
||||
|
||||
private void setButtonStates() {
|
||||
prev.setDisable(page == 0);
|
||||
next.setDisable(page == pages.length - 1);
|
||||
finish.setDisable(page != pages.length - 1);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package ctbrec.ui.event;
|
||||
|
||||
import ctbrec.OS;
|
||||
import ctbrec.event.Action;
|
||||
import ctbrec.event.Event;
|
||||
import ctbrec.ui.CamrecApplication;
|
||||
|
||||
public class ModelStateNotification extends Action {
|
||||
|
||||
private String header;
|
||||
private String msg;
|
||||
|
||||
public ModelStateNotification(String header, String msg) {
|
||||
this.header = header;
|
||||
this.msg = msg;
|
||||
name = "show notification";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Event evt) {
|
||||
OS.notification(CamrecApplication.title, header, msg);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package ctbrec.ui.event;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
import ctbrec.event.Action;
|
||||
import ctbrec.event.Event;
|
||||
import javafx.scene.media.AudioClip;
|
||||
|
||||
public class PlaySound extends Action {
|
||||
|
||||
private URL url;
|
||||
|
||||
public PlaySound(URL url) {
|
||||
this.url = url;
|
||||
name = "play sound";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Event evt) {
|
||||
AudioClip clip = new AudioClip(url.toString());
|
||||
clip.play();
|
||||
}
|
||||
}
|
|
@ -1,30 +1,94 @@
|
|||
package ctbrec.ui.settings;
|
||||
|
||||
import ctbrec.event.Event.Type;
|
||||
import java.io.InputStream;
|
||||
|
||||
import ctbrec.event.EventHandlerConfiguration;
|
||||
import ctbrec.ui.controls.Wizard;
|
||||
import javafx.event.ActionEvent;
|
||||
import javafx.geometry.Insets;
|
||||
import javafx.scene.Scene;
|
||||
import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.ScrollPane;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.control.TextField;
|
||||
import javafx.scene.control.TitledPane;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.Border;
|
||||
import javafx.scene.layout.BorderPane;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.HBox;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
public class ActionSettingsPanel extends TitledPane {
|
||||
|
||||
private TableView actionTable;
|
||||
|
||||
public ActionSettingsPanel(SettingsTab settingsTab) {
|
||||
setText("Actions");
|
||||
setText("Events & Actions");
|
||||
setExpanded(true);
|
||||
setCollapsible(false);
|
||||
createGui();
|
||||
}
|
||||
|
||||
private void createGui() {
|
||||
GridPane mainLayout = SettingsTab.createGridLayout();
|
||||
BorderPane mainLayout = new BorderPane();
|
||||
setContent(mainLayout);
|
||||
|
||||
actionTable = createActionTable();
|
||||
actionTable.setPrefSize(300, 200);
|
||||
ScrollPane scrollPane = new ScrollPane(actionTable);
|
||||
scrollPane.setFitToHeight(true);
|
||||
scrollPane.setFitToWidth(true);
|
||||
scrollPane.setBorder(Border.EMPTY);
|
||||
mainLayout.setCenter(scrollPane);
|
||||
BorderPane.setMargin(scrollPane, new Insets(5));
|
||||
|
||||
Button add = new Button("Add");
|
||||
add.setOnAction(this::add);
|
||||
Button delete = new Button("Delete");
|
||||
delete.setOnAction(this::delete);
|
||||
delete.setDisable(true);
|
||||
HBox buttons = new HBox(10, add, delete);
|
||||
mainLayout.setBottom(buttons);
|
||||
BorderPane.setMargin(buttons, new Insets(5));
|
||||
}
|
||||
|
||||
private void add(ActionEvent evt) {
|
||||
EventHandlerConfiguration config = new EventHandlerConfiguration();
|
||||
Pane namePane = createNamePane(config);
|
||||
GridPane pane2 = SettingsTab.createGridLayout();
|
||||
pane2.add(new Label("Pane 2"), 0, 0);
|
||||
GridPane pane3 = SettingsTab.createGridLayout();
|
||||
pane3.add(new Label("Pane 3"), 0, 0);
|
||||
Stage dialog = new Stage();
|
||||
dialog.setTitle("New Action");
|
||||
InputStream icon = getClass().getResourceAsStream("/icon.png");
|
||||
dialog.getIcons().add(new Image(icon));
|
||||
Wizard root = new Wizard(dialog, namePane, pane2, pane3);
|
||||
Scene scene = new Scene(root, 640, 480);
|
||||
scene.getStylesheets().addAll(getScene().getStylesheets());
|
||||
dialog.setScene(scene);
|
||||
dialog.showAndWait();
|
||||
}
|
||||
|
||||
private void delete(ActionEvent evt) {
|
||||
|
||||
}
|
||||
|
||||
private Pane createNamePane(EventHandlerConfiguration config) {
|
||||
GridPane layout = SettingsTab.createGridLayout();
|
||||
int row = 0;
|
||||
for (Type type : Type.values()) {
|
||||
Label l = new Label(type.name());
|
||||
mainLayout.add(l, 0, row);
|
||||
Button b = new Button("Configure");
|
||||
mainLayout.add(b, 1, row++);
|
||||
}
|
||||
layout.add(new Label("Name"), 0, row);
|
||||
TextField name = new TextField();
|
||||
layout.add(name, 1, row);
|
||||
return layout;
|
||||
}
|
||||
|
||||
|
||||
private TableView createActionTable() {
|
||||
TableView view = new TableView();
|
||||
return view;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,8 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
|||
|
||||
//right side
|
||||
rightSide.getChildren().add(siteConfigAccordion);
|
||||
rightSide.getChildren().add(new ActionSettingsPanel(this));
|
||||
ActionSettingsPanel actions = new ActionSettingsPanel(this);
|
||||
rightSide.getChildren().add(actions);
|
||||
proxySettingsPane = new ProxySettingsPane(this);
|
||||
rightSide.getChildren().add(proxySettingsPane);
|
||||
for (int i = 0; i < sites.size(); i++) {
|
||||
|
@ -141,7 +142,6 @@ public class SettingsTab extends Tab implements TabSelectionListener {
|
|||
siteConfigAccordion.getPanes().add(pane);
|
||||
}
|
||||
}
|
||||
siteConfigAccordion.setExpandedPane(siteConfigAccordion.getPanes().get(0));
|
||||
}
|
||||
|
||||
private Node createRecordLocationPanel() {
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
|
||||
public abstract class Action implements Consumer<Event> {
|
||||
|
||||
protected String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -7,18 +7,29 @@ public abstract class Event {
|
|||
* This event is fired every time the OnlineMonitor sees a model online
|
||||
* It is also fired, if the model was online before. You can see it as a "still online ping".
|
||||
*/
|
||||
MODEL_ONLINE,
|
||||
MODEL_ONLINE("Model is online"),
|
||||
|
||||
/**
|
||||
* This event is fired whenever the model's online state (Model.STATUS) changes.
|
||||
*/
|
||||
MODEL_STATUS_CHANGED,
|
||||
MODEL_STATUS_CHANGED("Model status changed"),
|
||||
|
||||
|
||||
/**
|
||||
* This event is fired whenever the state of a recording changes.
|
||||
*/
|
||||
RECORDING_STATUS_CHANGED
|
||||
RECORDING_STATUS_CHANGED("Recording status changed");
|
||||
|
||||
private String desc;
|
||||
|
||||
Type(String desc) {
|
||||
this.desc = desc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
|
||||
public abstract Type getType();
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
public class EventReaction {
|
||||
public class EventHandler {
|
||||
|
||||
private List<Predicate<Event>> predicates = new ArrayList<>();
|
||||
private Consumer<Event> action;
|
||||
private List<Consumer<Event>> actions;
|
||||
|
||||
@SafeVarargs
|
||||
public EventReaction(Consumer<Event> action, Predicate<Event>... predicates) {
|
||||
this.action = action;
|
||||
public EventHandler(Consumer<Event> action, Predicate<Event>... predicates) {
|
||||
this(Collections.singletonList(action), predicates);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public EventHandler(List<Consumer<Event>> actions, Predicate<Event>... predicates) {
|
||||
this.actions = actions;
|
||||
for (Predicate<Event> predicate : predicates) {
|
||||
this.predicates.add(predicate);
|
||||
}
|
||||
|
@ -26,7 +32,9 @@ public class EventReaction {
|
|||
}
|
||||
}
|
||||
if(matches) {
|
||||
action.accept(evt);
|
||||
for (Consumer<Event> action : actions) {
|
||||
action.accept(evt);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class EventHandlerConfiguration {
|
||||
|
||||
private String name;
|
||||
private Event.Type event;
|
||||
private List<PredicateConfiguration> predicates = new ArrayList<>();
|
||||
private List<ActionConfiguration> actions = new ArrayList<>();
|
||||
|
||||
public Event.Type getEvent() {
|
||||
return event;
|
||||
}
|
||||
|
||||
public void setEvent(Event.Type event) {
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public List<PredicateConfiguration> getPredicates() {
|
||||
return predicates;
|
||||
}
|
||||
|
||||
public void setPredicates(List<PredicateConfiguration> predicates) {
|
||||
this.predicates = predicates;
|
||||
}
|
||||
|
||||
public List<ActionConfiguration> getActions() {
|
||||
return actions;
|
||||
}
|
||||
|
||||
public void setActions(List<ActionConfiguration> actions) {
|
||||
this.actions = actions;
|
||||
}
|
||||
|
||||
public class PredicateConfiguration {
|
||||
private String type;
|
||||
private Map<String, Object> configuration = new HashMap<>();
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void setConfiguration(Map<String, Object> configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class ActionConfiguration {
|
||||
private String type;
|
||||
private Map<String, Object> configuration = new HashMap<>();
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Map<String, Object> getConfiguration() {
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void setConfiguration(Map<String, Object> configuration) {
|
||||
this.configuration = configuration;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -4,11 +4,11 @@ import java.util.function.Predicate;
|
|||
|
||||
import ctbrec.event.Event.Type;
|
||||
|
||||
public class TypePredicate implements Predicate<Event> {
|
||||
public class EventTypePredicate implements Predicate<Event> {
|
||||
|
||||
private Type type;
|
||||
|
||||
private TypePredicate(Type type) {
|
||||
private EventTypePredicate(Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ public class TypePredicate implements Predicate<Event> {
|
|||
return evt.getType() == type;
|
||||
}
|
||||
|
||||
public static TypePredicate of(Type type) {
|
||||
return new TypePredicate(type);
|
||||
public static EventTypePredicate of(Type type) {
|
||||
return new EventTypePredicate(type);
|
||||
}
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class LogReaction extends EventReaction {
|
||||
|
||||
private static final transient Logger LOG = LoggerFactory.getLogger(LogReaction.class);
|
||||
|
||||
public LogReaction() {
|
||||
super(evt -> {
|
||||
LOG.debug("LogReaction: {}", evt);
|
||||
}, TypePredicate.of(Event.Type.RECORDING_STATUS_CHANGED));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import ctbrec.Model;
|
||||
|
||||
public class ModelPredicate implements Predicate<Event> {
|
||||
|
||||
private Model model;
|
||||
|
||||
private ModelPredicate(Model model) {
|
||||
this.model = model;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Event evt) {
|
||||
if(evt instanceof AbstractModelEvent) {
|
||||
AbstractModelEvent modelEvent = (AbstractModelEvent) evt;
|
||||
Model other = modelEvent.getModel();
|
||||
return Objects.equals(model, other);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static ModelPredicate of(Model model) {
|
||||
return new ModelPredicate(model);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package ctbrec.event;
|
||||
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import ctbrec.Model;
|
||||
|
||||
public class ModelStatePredicate implements Predicate<Event> {
|
||||
|
||||
private Model.State state;
|
||||
|
||||
private ModelStatePredicate(Model.State state) {
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(Event evt) {
|
||||
if(evt instanceof AbstractModelEvent) {
|
||||
ModelStateChangedEvent modelEvent = (ModelStateChangedEvent) evt;
|
||||
Model.State newState = modelEvent.getNewState();
|
||||
return newState == state;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static ModelStatePredicate of(Model.State state) {
|
||||
return new ModelStatePredicate(state);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue