Skip to content

Commit ef8ebb9

Browse files
committed
Events: Initial commit.
1 parent 5f02652 commit ef8ebb9

File tree

6 files changed

+228
-1
lines changed

6 files changed

+228
-1
lines changed

Events/README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# Casterlabs Commons/Events
2+
3+
This package has helpers for creating event-based systems.
4+
5+
## Examples
6+
7+
Simple event:
8+
9+
```java
10+
SingleEventProvider<String> ep = new SingleEventProvider<>();
11+
12+
int taskId = ep.on((location) -> {
13+
System.out.printf("Hello %s!\n", location);
14+
});
15+
16+
ep.fireEvent("world");
17+
ep.off(taskId);
18+
```
19+
20+
Advanced usage of MultiEventProvider:
21+
22+
```java
23+
public class CoffeeMachineMonitor extends MultiEventProvider<CoffeeEventType, CoffeeEvent> {
24+
25+
public static enum CoffeeEventType {
26+
// ...
27+
}
28+
29+
// CoffeeEvent, CoffeeBrewErrorEvent, etc...
30+
31+
}
32+
```
33+
34+
```java
35+
CoffeeMachineMonitor mon = new CoffeeMachineMonitor();
36+
37+
ep.on(CoffeeEventType.BREW_FINISHED, () -> {
38+
System.out.println("Brew finished!");
39+
});
40+
41+
ep.on(CoffeeEventType.BREW_ERROR, (e) -> {
42+
CoffeeBrewErrorEvent ev = (CoffeeBrewErrorEvent) e;
43+
System.out.printf("Error whilst brewing: %s\n", e.getMessage());
44+
});
45+
```
46+
47+
## Adding to your project
48+
49+
Replace `_VERSION` with the latest version or commit in this repo and make sure to add the [Repository](https://github.com/Casterlabs/Commons#Repository) to your build system.
50+
51+
<details>
52+
<summary>Maven</summary>
53+
54+
```xml
55+
<dependency>
56+
<groupId>co.casterlabs.Commons</groupId>
57+
<artifactId>Async</artifactId>
58+
<version>_VERSION</version>
59+
</dependency>
60+
```
61+
</details>
62+
63+
<details>
64+
<summary>Gradle</summary>
65+
66+
```gradle
67+
dependencies {
68+
implementation 'co.casterlabs:Commons.Async:_VERSION'
69+
}
70+
```
71+
</details>
72+
73+
<details>
74+
<summary>SBT</summary>
75+
76+
```
77+
libraryDependencies += "co.casterlabs.Commons" % "Async" % "_VERSION"
78+
```
79+
</details>
80+
81+
<details>
82+
<summary>Leiningen</summary>
83+
84+
```
85+
:dependencies [[co.casterlabs.Commons/Async "_VERSION"]]
86+
```
87+
</details>

Events/pom.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<artifactId>Events</artifactId>
4+
5+
<parent>
6+
<groupId>co.casterlabs</groupId>
7+
<artifactId>Commons</artifactId>
8+
<version>1.0.0</version>
9+
<relativePath>../pom.xml</relativePath>
10+
</parent>
11+
</project>
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package co.casterlabs.commons.events;
2+
3+
import java.util.HashMap;
4+
import java.util.HashSet;
5+
import java.util.Map;
6+
import java.util.Set;
7+
import java.util.function.Consumer;
8+
9+
import org.jetbrains.annotations.Nullable;
10+
11+
import lombok.NonNull;
12+
13+
public class MultiEventProvider<E extends Enum<?>, T> {
14+
private Map<E, Map<Integer, Consumer<T>>> listenerSections = new HashMap<>();
15+
private Set<Integer> allListeners = new HashSet<>();
16+
17+
/* on */
18+
19+
public synchronized int on(@NonNull E type, @NonNull Consumer<T> listener) {
20+
int id = listener.hashCode();
21+
Map<Integer, Consumer<T>> listenerSection = this.listenerSections.get(type);
22+
23+
if (listenerSection == null) {
24+
listenerSection = new HashMap<>();
25+
this.listenerSections.put(type, listenerSection);
26+
}
27+
28+
listenerSection.put(id, listener);
29+
this.allListeners.add(id);
30+
31+
return id;
32+
}
33+
34+
public synchronized int on(@NonNull E type, @NonNull Runnable listener) {
35+
return this.on(type, (aVoid) -> listener.run());
36+
}
37+
38+
/* off */
39+
40+
public synchronized void off(@NonNull Consumer<T> listener) {
41+
this.off(listener.hashCode());
42+
}
43+
44+
public synchronized void off(@NonNull Runnable listener) {
45+
this.off(listener.hashCode());
46+
}
47+
48+
public synchronized void off(int id) {
49+
this.allListeners.remove(id);
50+
51+
for (Map<Integer, Consumer<T>> listenerSection : this.listenerSections.values()) {
52+
listenerSection.remove(id);
53+
}
54+
}
55+
56+
/* Firing */
57+
58+
public synchronized void fireEvent(@NonNull E type, @Nullable T data) {
59+
Map<Integer, Consumer<T>> listenerSection = this.listenerSections.get(type);
60+
61+
if (listenerSection != null) {
62+
for (Consumer<T> listener : listenerSection.values()) {
63+
try {
64+
listener.accept(data);
65+
} catch (Throwable t) {
66+
System.err.println("An exception occurred whilst firing event:");
67+
t.printStackTrace();
68+
}
69+
}
70+
}
71+
}
72+
73+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package co.casterlabs.commons.events;
2+
3+
import java.util.HashMap;
4+
import java.util.Map;
5+
import java.util.function.Consumer;
6+
7+
import org.jetbrains.annotations.Nullable;
8+
9+
import lombok.NonNull;
10+
11+
public class SingleEventProvider<T> {
12+
private Map<Integer, Consumer<T>> listeners = new HashMap<>();
13+
14+
/* on */
15+
16+
public synchronized int on(@NonNull Consumer<T> listener) {
17+
int id = listener.hashCode();
18+
this.listeners.put(id, listener);
19+
20+
return id;
21+
}
22+
23+
public synchronized int on(@NonNull Runnable listener) {
24+
return this.on((aVoid) -> listener.run());
25+
}
26+
27+
/* off */
28+
29+
public synchronized void off(@NonNull Consumer<T> listener) {
30+
this.off(listener.hashCode());
31+
}
32+
33+
public synchronized void off(@NonNull Runnable listener) {
34+
this.off(listener.hashCode());
35+
}
36+
37+
public synchronized void off(int id) {
38+
this.listeners.remove(id);
39+
}
40+
41+
/* Firing */
42+
43+
public synchronized void fireEvent(@Nullable T data) {
44+
for (Consumer<T> listener : this.listeners.values()) {
45+
try {
46+
listener.accept(data);
47+
} catch (Throwable t) {
48+
System.err.println("An exception occurred whilst firing event:");
49+
t.printStackTrace();
50+
}
51+
}
52+
}
53+
54+
}

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ We sort out the different utils into distinct packages, allowing you to pull in
99
Select a subproject to get started.
1010

1111
[Platform](/Platform/) &bull; OS & CPU arch detection.
12-
[Async](/Async/) &bull; Threading & async helpers.
12+
[Async](/Async/) &bull; Threading & async helpers.
13+
[Events](/Events/) &bull; Event helpers.
1314

1415
## Repository
1516

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
<modules>
99
<module>Platform</module>
1010
<module>Async</module>
11+
<module>Events</module>
1112
</modules>
1213

1314
<properties>

0 commit comments

Comments
 (0)