Skip to content

Commit cbeefa0

Browse files
committed
feat: added a new module fxgl-intelligence
1 parent 9114311 commit cbeefa0

File tree

5 files changed

+300
-0
lines changed

5 files changed

+300
-0
lines changed

fxgl-intelligence/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
### fxgl-intelligence
2+
3+
This module does not have module-info as some of its dependencies do not provide a proper module-info.java

fxgl-intelligence/pom.xml

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>fxgl-framework</artifactId>
7+
<groupId>com.github.almasb</groupId>
8+
<version>21+dev-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>fxgl-intelligence</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.github.almasb</groupId>
17+
<artifactId>fxgl-core</artifactId>
18+
<version>${fxgl.version}</version>
19+
</dependency>
20+
21+
<dependency>
22+
<groupId>org.java-websocket</groupId>
23+
<artifactId>Java-WebSocket</artifactId>
24+
<version>${websocket.version}</version>
25+
</dependency>
26+
27+
<dependency>
28+
<groupId>org.seleniumhq.selenium</groupId>
29+
<artifactId>selenium-java</artifactId>
30+
<version>${selenium.version}</version>
31+
</dependency>
32+
</dependencies>
33+
34+
<build>
35+
<plugins>
36+
<!-- Compile java -->
37+
<plugin>
38+
<artifactId>maven-compiler-plugin</artifactId>
39+
</plugin>
40+
41+
<!-- Compile kotlin -->
42+
<plugin>
43+
<groupId>org.jetbrains.kotlin</groupId>
44+
<artifactId>kotlin-maven-plugin</artifactId>
45+
</plugin>
46+
47+
<!-- Create sources.jar -->
48+
<plugin>
49+
<groupId>org.apache.maven.plugins</groupId>
50+
<artifactId>maven-source-plugin</artifactId>
51+
</plugin>
52+
53+
<!-- Create javadoc.jar -->
54+
<plugin>
55+
<groupId>org.apache.maven.plugins</groupId>
56+
<artifactId>maven-jar-plugin</artifactId>
57+
</plugin>
58+
59+
<!-- Attach kotlin sources -->
60+
<plugin>
61+
<groupId>org.codehaus.mojo</groupId>
62+
<artifactId>build-helper-maven-plugin</artifactId>
63+
</plugin>
64+
65+
<!-- Generate test coverage reports -->
66+
<plugin>
67+
<groupId>org.jacoco</groupId>
68+
<artifactId>jacoco-maven-plugin</artifactId>
69+
<version>${jacoco.version}</version>
70+
<configuration>
71+
<destFile>${project.build.directory}/coverage-reports/jacoco-unit.exec</destFile>
72+
<dataFile>${project.build.directory}/coverage-reports/jacoco-unit.exec</dataFile>
73+
</configuration>
74+
<executions>
75+
<execution>
76+
<id>jacoco-initialize</id>
77+
<goals>
78+
<goal>prepare-agent</goal>
79+
</goals>
80+
</execution>
81+
<execution>
82+
<id>jacoco-site</id>
83+
<phase>package</phase>
84+
<goals>
85+
<goal>report</goal>
86+
</goals>
87+
</execution>
88+
<execution>
89+
<id>report</id>
90+
<phase>test</phase>
91+
<goals>
92+
<goal>report</goal>
93+
</goals>
94+
</execution>
95+
</executions>
96+
</plugin>
97+
</plugins>
98+
</build>
99+
</project>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* FXGL - JavaFX Game Library. The MIT License (MIT).
3+
* Copyright (c) AlmasB ([email protected]).
4+
* See LICENSE for details.
5+
*/
6+
7+
package com.almasb.fxgl.intelligence;
8+
9+
/**
10+
* @author Almas Baim (https://github.com/AlmasB)
11+
*/
12+
public class SpeechRecognitionService {
13+
14+
}
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* FXGL - JavaFX Game Library. The MIT License (MIT).
3+
* Copyright (c) AlmasB ([email protected]).
4+
* See LICENSE for details.
5+
*/
6+
7+
package com.almasb.fxgl.ws;
8+
9+
import com.almasb.fxgl.logging.Logger;
10+
import org.java_websocket.WebSocket;
11+
import org.java_websocket.handshake.ClientHandshake;
12+
import org.java_websocket.server.WebSocketServer;
13+
14+
import java.net.InetSocketAddress;
15+
import java.util.ArrayList;
16+
import java.util.List;
17+
import java.util.Optional;
18+
import java.util.concurrent.ArrayBlockingQueue;
19+
import java.util.concurrent.BlockingQueue;
20+
import java.util.function.Consumer;
21+
22+
/**
23+
* A simple localhost websocket server.
24+
* All methods are internally run in a background thread,
25+
* so they are safe to be called from any thread.
26+
*
27+
* @author Almas Baimagambetov ([email protected])
28+
*/
29+
public final class LocalWebSocketServer extends WebSocketServer {
30+
31+
private static final String POISON_PILL = "62jkasdy732qjkkhs63jASY_HSF";
32+
33+
private final Logger log;
34+
35+
private boolean isLoggingEnabled = true;
36+
37+
private String serverName;
38+
private List<Consumer<String>> messageHandlers = new ArrayList<>();
39+
40+
private SendMessageThread thread;
41+
private WebSocket socket = null;
42+
43+
/**
44+
* Create a server without a name at given port.
45+
*/
46+
public LocalWebSocketServer(int port) {
47+
this("Unnamed", port);
48+
}
49+
50+
/**
51+
* Create a server with the given dev-friendly name at given port.
52+
*/
53+
public LocalWebSocketServer(String serverName, int port) {
54+
super(new InetSocketAddress("localhost", port));
55+
this.serverName = serverName;
56+
57+
log = Logger.get("WSServer " + serverName + ":" + port);
58+
thread = new SendMessageThread(serverName);
59+
}
60+
61+
public boolean isLoggingEnabled() {
62+
return isLoggingEnabled;
63+
}
64+
65+
public void setLoggingEnabled(boolean isLoggingEnabled) {
66+
this.isLoggingEnabled = isLoggingEnabled;
67+
}
68+
69+
/**
70+
* Add a handler for new messages.
71+
*/
72+
public void addMessageHandler(Consumer<String> handler) {
73+
messageHandlers.add(handler);
74+
}
75+
76+
/**
77+
* Remove an existing handler.
78+
*/
79+
public void removeMessageHandler(Consumer<String> handler) {
80+
messageHandlers.remove(handler);
81+
}
82+
83+
/**
84+
* @return last connected socket
85+
*/
86+
public Optional<WebSocket> socket() {
87+
return Optional.ofNullable(socket);
88+
}
89+
90+
/**
91+
* Send a String to the other end of the socket.
92+
*/
93+
public void send(String data) {
94+
if (!isConnected()) {
95+
log.warning("Cannot send <" + data + "> Socket is not connected");
96+
return;
97+
}
98+
99+
try {
100+
thread.messages.put(data);
101+
} catch (Exception e) {
102+
log.warning("Failed to send data to SendMessageThread", e);
103+
}
104+
}
105+
106+
public boolean isConnected() {
107+
return socket != null;
108+
}
109+
110+
@Override
111+
public void onOpen(WebSocket conn, ClientHandshake handshake) {
112+
log.info("Opened connection: " + conn.getRemoteSocketAddress());
113+
114+
socket = conn;
115+
}
116+
117+
@Override
118+
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
119+
log.info("Closed connection, code: " + code);
120+
}
121+
122+
@Override
123+
public void onMessage(WebSocket conn, String message) {
124+
messageHandlers.forEach(h -> h.accept(message));
125+
}
126+
127+
@Override
128+
public void onError(WebSocket conn, Exception ex) {
129+
log.warning("WS error", ex);
130+
}
131+
132+
@Override
133+
public void onStart() {
134+
log.info("Server started successfully");
135+
}
136+
137+
@Override
138+
public void start() {
139+
try {
140+
thread.start();
141+
super.start();
142+
} catch (Exception e) {
143+
log.warning("Failed to start WS server", e);
144+
}
145+
}
146+
147+
@Override
148+
public void stop() {
149+
try {
150+
thread.messages.put(POISON_PILL);
151+
super.stop();
152+
} catch (Exception e) {
153+
log.warning("Failed to stop WS server", e);
154+
}
155+
}
156+
157+
private class SendMessageThread extends Thread {
158+
BlockingQueue<String> messages = new ArrayBlockingQueue<>(10);
159+
160+
SendMessageThread(String name) {
161+
super(name);
162+
}
163+
164+
@Override
165+
public void run() {
166+
while (true) {
167+
try {
168+
var data = messages.take();
169+
170+
if (data.equals(POISON_PILL))
171+
break;
172+
173+
socket.send(data);
174+
175+
} catch (Exception e) {
176+
log.warning("Failed to send data", e);
177+
}
178+
}
179+
}
180+
}
181+
}

pom.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
<module>fxgl</module>
2121
<module>fxgl-test</module>
2222
<module>fxgl-controllerinput</module>
23+
<module>fxgl-intelligence</module>
2324
<module>fxgl-gameplay</module>
2425
<module>fxgl-samples</module>
2526
<module>fxgl-tools</module>
@@ -93,6 +94,8 @@
9394
<kotlin.version>1.8.10</kotlin.version>
9495
<attach.version>4.0.17</attach.version>
9596
<jackson.version>2.14.2</jackson.version>
97+
<websocket.version>1.5.5</websocket.version>
98+
<selenium.version>4.17.0</selenium.version>
9699

97100
<!-- test dependencies -->
98101
<junit.jupiter.version>5.10.0</junit.jupiter.version>

0 commit comments

Comments
 (0)