Skip to content

Commit 33df88f

Browse files
committed
Add base schema
1 parent 4d700ba commit 33df88f

32 files changed

+533
-39
lines changed

pom.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,16 @@
3535
<artifactId>javafx-controls</artifactId>
3636
<version>18.0.1</version>
3737
</dependency>
38+
<dependency>
39+
<groupId>org.slf4j</groupId>
40+
<artifactId>slf4j-api</artifactId>
41+
<version>2.0.6</version>
42+
</dependency>
43+
<dependency>
44+
<groupId>org.slf4j</groupId>
45+
<artifactId>slf4j-simple</artifactId>
46+
<version>2.0.6</version>
47+
</dependency>
3848
<dependency>
3949
<groupId>org.jruby</groupId>
4050
<artifactId>jruby</artifactId>
@@ -116,6 +126,14 @@
116126
<groupId>org.openjfx</groupId>
117127
<artifactId>javafx-controls</artifactId>
118128
</dependency>
129+
<dependency>
130+
<groupId>org.slf4j</groupId>
131+
<artifactId>slf4j-api</artifactId>
132+
</dependency>
133+
<dependency>
134+
<groupId>org.slf4j</groupId>
135+
<artifactId>slf4j-simple</artifactId>
136+
</dependency>
119137
</dependencies>
120138

121139
<reporting>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ifml3.api;
2+
3+
import java.util.concurrent.Flow.Publisher;
4+
import java.util.concurrent.Flow.Subscriber;
5+
6+
public interface ComponentConnector<IN, OUT> {
7+
8+
Subscriber<IN> subscriber();
9+
10+
Publisher<OUT> publisher();
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ifml3.api.internal;
2+
3+
import ifml3.api.ComponentConnector;
4+
import java.util.concurrent.Flow.Publisher;
5+
import java.util.concurrent.Flow.Subscriber;
6+
7+
public record BaseComponentConnector<IN, OUT>(
8+
Subscriber<IN> subscriber,
9+
Publisher<OUT> publisher
10+
) implements ComponentConnector<IN, OUT> {
11+
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
package ifml3.api.internal;
2+
3+
import java.util.concurrent.Flow.Subscriber;
4+
import java.util.concurrent.Flow.Subscription;
5+
import java.util.function.Consumer;
6+
7+
public class BaseSubscriber<T> implements Subscriber<T> {
8+
9+
private final Consumer<T> consumer;
10+
11+
private Subscription subscription;
12+
13+
public BaseSubscriber(final Consumer<T> consumer) {
14+
this.consumer = consumer;
15+
}
16+
17+
@Override
18+
public void onSubscribe(final Subscription subscription) {
19+
this.subscription = subscription;
20+
this.subscription.request(1L);
21+
}
22+
23+
@Override
24+
public void onNext(final T item) {
25+
consumer.accept(item);
26+
subscription.request(1L);
27+
}
28+
29+
@Override
30+
public void onError(final Throwable throwable) {
31+
throw new IllegalStateException(throwable);
32+
}
33+
34+
@Override
35+
public void onComplete() {
36+
}
37+
}

src/main/java/ifml3/app/Ifml3App.java

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,54 @@
55
import ifml3.app.i18n.Translation;
66
import ifml3.app.view.MainView;
77
import ifml3.app.view.View;
8+
import ifml3.app.view.ui.internal.PlayerComponent;
9+
import ifml3.engine.Engine;
10+
import ifml3.engine.internal.SimpleEngine;
11+
import ifml3.lexer.Lexer;
12+
import ifml3.lexer.internal.SimpleLexer;
813
import java.util.ResourceBundle;
914
import javafx.application.Application;
1015
import javafx.stage.Stage;
16+
import org.slf4j.Logger;
17+
import org.slf4j.LoggerFactory;
1118

1219
public class Ifml3App extends Application {
1320

21+
private static final Logger logger = LoggerFactory.getLogger(Ifml3App.class);
22+
1423
private Translation translation;
1524
private View view;
25+
private PlayerComponent player;
26+
private Lexer lexer;
27+
private Engine engine;
1628

1729
@Override
1830
public void init() {
31+
logger.info("Initialization...");
1932
this.translation = new AppTranslation(ResourceBundle.getBundle("lang/ifml3"));
20-
this.view = new MainView(translation);
33+
final var mainView = new MainView(translation);
34+
this.view = mainView;
35+
this.player = mainView.player();
36+
this.lexer = new SimpleLexer();
37+
this.engine = new SimpleEngine();
38+
connectComponents();
39+
}
40+
41+
private void connectComponents() {
42+
logger.info("Connect components");
43+
final var playerConnector = player.uiConnector();
44+
final var uiConnector = lexer.uiConnector();
45+
final var engineConnector = lexer.engineConnector();
46+
final var lexerConnector = engine.lexerConnector();
47+
playerConnector.publisher().subscribe(uiConnector.subscriber());
48+
uiConnector.publisher().subscribe(playerConnector.subscriber());
49+
lexerConnector.publisher().subscribe(engineConnector.subscriber());
50+
engineConnector.publisher().subscribe(lexerConnector.subscriber());
2151
}
2252

2353
@Override
2454
public void start(final Stage stage) throws Exception {
55+
logger.info("Start application");
2556
stage.setScene(view.scene());
2657
stage.setTitle(translation.message(AppMessage.APP_TITLE));
2758
stage.show();

src/main/java/ifml3/app/view/MainView.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package ifml3.app.view;
22

3+
import ifml3.api.ComponentConnector;
34
import ifml3.app.i18n.AppMessage;
45
import ifml3.app.i18n.Translation;
6+
import ifml3.app.view.ui.internal.PlayerComponent;
57
import javafx.scene.Scene;
68
import javafx.scene.control.ComboBox;
79
import javafx.scene.control.Label;
@@ -14,10 +16,12 @@ public class MainView implements View {
1416

1517
private final Translation translation;
1618
private final Scene scene;
19+
private final PlayerComponent player;
1720

1821
public MainView(final Translation translation) {
1922
this.translation = translation;
20-
final var pane = new BorderPane(label("center"), menuBar(), label("right"), inputLine(), treeView());
23+
this.player = new PlayerComponent();
24+
final var pane = new BorderPane(player.get(), menuBar(), label("right"), inputLine(), treeView());
2125
scene = new Scene(pane, 800.0, 600.0);
2226
}
2327

@@ -26,6 +30,10 @@ public Scene scene() {
2630
return scene;
2731
}
2832

33+
public PlayerComponent player() {
34+
return player;
35+
}
36+
2937
private Label label(final String text) {
3038
return new Label(text);
3139
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ifml3.app.view.ui;
2+
3+
import javafx.scene.Parent;
4+
5+
public interface UIComponent {
6+
7+
Parent get();
8+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package ifml3.app.view.ui.internal;
2+
3+
import ifml3.api.ComponentConnector;
4+
import ifml3.api.internal.BaseComponentConnector;
5+
import ifml3.api.internal.BaseSubscriber;
6+
import ifml3.app.view.ui.UIComponent;
7+
import ifml3.ui.TextSanitizer;
8+
import ifml3.ui.UserCommand;
9+
import ifml3.ui.UserInterface;
10+
import ifml3.ui.UserMessage;
11+
import ifml3.ui.internal.UserTextSanitizer;
12+
import java.util.concurrent.Flow.Subscriber;
13+
import java.util.concurrent.SubmissionPublisher;
14+
import javafx.event.ActionEvent;
15+
import javafx.scene.Parent;
16+
import javafx.scene.control.TextArea;
17+
import javafx.scene.control.TextField;
18+
import javafx.scene.layout.VBox;
19+
import org.slf4j.Logger;
20+
import org.slf4j.LoggerFactory;
21+
22+
public class PlayerComponent implements UIComponent, UserInterface {
23+
24+
private static final Logger logger = LoggerFactory.getLogger(PlayerComponent.class);
25+
26+
private final SubmissionPublisher<UserCommand> publisher;
27+
private final Subscriber<UserMessage> subscriber;
28+
private final TextSanitizer sanitizer;
29+
private final ComponentConnector<UserMessage, UserCommand> connector;
30+
private final VBox vBox;
31+
private final TextArea textArea;
32+
private final TextField textField;
33+
34+
public PlayerComponent() {
35+
// @todo at least sanitizer should be as dependency
36+
this.sanitizer = new UserTextSanitizer();
37+
this.publisher = new SubmissionPublisher<>();
38+
this.textArea = new TextArea();
39+
this.textArea.setEditable(false);
40+
this.textArea.setPrefRowCount(1_000);
41+
this.textField = new TextField();
42+
this.textField.setOnAction(this::processCommand);
43+
this.vBox = new VBox(textArea, textField);
44+
this.subscriber = new BaseSubscriber<>(this::processMessage);
45+
this.connector = new BaseComponentConnector<>(subscriber, publisher);
46+
}
47+
48+
@Override
49+
public Parent get() {
50+
return vBox;
51+
}
52+
53+
@Override
54+
public ComponentConnector<UserMessage, UserCommand> uiConnector() {
55+
return connector;
56+
}
57+
58+
private void processCommand(final ActionEvent event) {
59+
final var text = textField.getText();
60+
logger.info("Input from user: '{}'", text);
61+
textField.setText("");
62+
textArea.appendText("> " + text + "\n");
63+
final var input = sanitizer.sanitize(text);
64+
// @todo preprocessing needed
65+
publisher.submit(() -> input);
66+
}
67+
68+
private void processMessage(final UserMessage message) {
69+
logger.info("Get message for user: {}", message);
70+
textArea.appendText("\n" + message.message() + "\n\n");
71+
}
72+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package ifml3.engine;
2+
3+
import ifml3.api.ComponentConnector;
4+
5+
public interface Engine {
6+
7+
ComponentConnector<EngineCommand, EngineMessage> lexerConnector();
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package ifml3.engine;
2+
3+
import ifml3.lexer.Phrase;
4+
import java.util.Collection;
5+
6+
@FunctionalInterface
7+
public interface EngineCommand {
8+
9+
Collection<Phrase> phrases();
10+
}

0 commit comments

Comments
 (0)