Skip to content

Commit 2f0afd6

Browse files
author
Kaleidox
committed
introduce interaction api
1 parent befe0fd commit 2f0afd6

17 files changed

Lines changed: 111 additions & 87 deletions

src/main/java/org/comroid/api/text/Translation.java

Lines changed: 16 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
import org.comroid.api.func.util.Debug;
66
import org.comroid.api.info.Log;
77
import org.jetbrains.annotations.NotNull;
8-
import org.jetbrains.annotations.Nullable;
8+
import org.jspecify.annotations.Nullable;
99

1010
import java.io.InputStream;
1111
import java.io.InputStreamReader;
@@ -21,21 +21,25 @@
2121
import java.util.concurrent.ConcurrentHashMap;
2222
import java.util.logging.Level;
2323

24-
@Value
25-
public class Translation {
24+
@lombok.extern.java.Log
25+
public record Translation(Locale locale, ResourceBundle strings) {
2626
public static final Map<String, Translation> LOADED = new ConcurrentHashMap<>();
2727

28-
public static Translation get() {
28+
public static @Nullable Translation get() {
2929
return get(Locale.getDefault());
3030
}
3131

32-
public static Translation get(@NotNull Locale locale) {
33-
return get(ResourceBundle.getBundle("locale", locale, new LangFileResourceBundleControl()));
32+
public static @Nullable Translation get(@NotNull Locale locale) {
33+
try {
34+
return get(ResourceBundle.getBundle("locale", locale, new LangFileResourceBundleControl()));
35+
} catch (MissingResourceException mrEx) {
36+
log.fine(mrEx.getMessage());
37+
return null;
38+
}
3439
}
3540

3641
public static Translation get(@NotNull ResourceBundle strings) {
37-
return LOADED.computeIfAbsent(strings.getLocale().getLanguage(),
38-
k -> new Translation(strings.getLocale(), strings));
42+
return LOADED.computeIfAbsent(strings.getLocale().getLanguage(), k -> new Translation(strings.getLocale(), strings));
3943
}
4044

4145
public static String str(@NotNull String key) {
@@ -44,25 +48,21 @@ public static String str(@NotNull String key) {
4448

4549
public static String str(@NotNull String key, @Nullable String fallback) {
4650
try {
47-
return get(Locale.getDefault()).get(key, fallback);
51+
var translation = get(Locale.getDefault());
52+
return translation == null ? fallback : translation.get(key, fallback);
4853
} catch (MissingResourceException e) {
4954
if (Debug.isDebug()) Log.at(Level.FINE, "Unable to translate key: " + key, e);
5055
else Log.at(Level.FINE, "Unable to translate key: " + key);
5156
return fallback;
5257
}
5358
}
5459

55-
Locale locale;
56-
ResourceBundle strings;
57-
5860
public String get(@NotNull String key) {
5961
return wrapNewlines(strings.getString(key));
6062
}
6163

6264
public String get(@NotNull String key, @Nullable String fallback) {
63-
return wrapNewlines(strings.containsKey(key)
64-
? strings.getString(key)
65-
: Objects.requireNonNullElse(fallback, key));
65+
return wrapNewlines(strings.containsKey(key) ? strings.getString(key) : Objects.requireNonNullElse(fallback, key));
6666
}
6767

6868
private static String wrapNewlines(String raw) {
@@ -100,10 +100,7 @@ public List<String> getFormats(String baseName) {
100100

101101
@Override
102102
@SneakyThrows
103-
public ResourceBundle newBundle(
104-
String baseName, Locale locale, String format, ClassLoader loader,
105-
boolean reload
106-
) {
103+
public ResourceBundle newBundle(String baseName, Locale locale, String format, ClassLoader loader, boolean reload) {
107104
if (!"lang".equals(format)) return null;
108105

109106
var bundleName = toBundleName(baseName, locale);

src/main/java/org/comroid/api/tree/Container.java

Lines changed: 15 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ static Container of(Object... children) {
4949

5050
default <T> Stream<T> streamChildren(@Nullable Class<? super T> type) {
5151
return Stream.concat(getChildren().stream(), streamOwnChildren())
52+
.collect(Streams.expandRecursive(it -> Stream.of(it).flatMap(Streams.cast(Container.class)).flatMap(c -> c.streamChildren(type))))
53+
.distinct()
5254
.flatMap(Streams.cast(type))
5355
.sorted(Comparator.comparing(Object::getClass, Order.COMPARATOR))
5456
.map(Polyfill::uncheckedCast);
@@ -67,18 +69,12 @@ default <T> Wrap<T> child(@Nullable Class<? super T> type) {
6769
}
6870

6971
private static Exception makeException(List<Throwable> errors) {
70-
return new Exception(String.format("%d unexpected %s occurred",
71-
errors.size(),
72-
Polyfill.plural(errors, "exception", "+s")),
73-
null,
74-
true, false) {
75-
};
72+
return new Exception(String.format("%d unexpected %s occurred", errors.size(), Polyfill.plural(errors, "exception", "+s")), null, true, false) {};
7673
}
7774

7875
class Base implements Container, Reloadable {
79-
@Ignore @Getter final Set<Object> children;
80-
@Ignore @Getter
81-
private final AtomicReference<CompletableFuture<Void>> closed = new AtomicReference<>(new CompletableFuture<>());
76+
@Ignore @Getter final Set<Object> children;
77+
@Ignore @Getter private final AtomicReference<CompletableFuture<Void>> closed = new AtomicReference<>(new CompletableFuture<>());
8278

8379
public Base(Object... children) {
8480
this.children = new HashSet<>(Set.of(children));
@@ -96,17 +92,13 @@ public <T> Object addChild(@Nullable T it) {
9692

9793
@Contract("_ -> this")
9894
public Object addChildren(@Nullable Object @NotNull ... children) {
99-
Stream.of(children)
100-
.filter(Objects::nonNull)
101-
.forEach(this.children::add);
95+
Stream.of(children).filter(Objects::nonNull).forEach(this.children::add);
10296
return this;
10397
}
10498

10599
@Override
106100
public int removeChildren(Object @NotNull ... children) {
107-
return (int) Stream.of(children)
108-
.filter(this.children::remove)
109-
.count();
101+
return (int) Stream.of(children).filter(this.children::remove).count();
110102
}
111103

112104
@Override
@@ -124,8 +116,7 @@ public void start() {
124116
@SafeVarargs
125117
@SneakyThrows
126118
protected final <T> void runOnChildren(Class<T> type, ThrowingConsumer<T, Throwable> task, Predicate<T> test, T... extra) {
127-
final List<Throwable> errors = streamChildren(type)
128-
.collect(append(moreMembers().flatMap(cast(type))))
119+
final List<Throwable> errors = streamChildren(type).collect(append(moreMembers().flatMap(cast(type))))
129120
.collect(append(extra))
130121
.filter(Objects::nonNull)
131122
.filter(Predicate.not(this::equals))
@@ -142,24 +133,20 @@ protected final <T> void runOnChildren(Class<T> type, ThrowingConsumer<T, Throwa
142133
})
143134
.distinct()
144135
.toList();
145-
if (errors.isEmpty())
146-
return;
147-
if (errors.size() == 1)
148-
throw errors.get(0);
149-
throw errors.stream().collect(
150-
() -> Container.makeException(errors),
151-
Throwable::addSuppressed,
152-
(l, r) -> Arrays.stream(r.getSuppressed()).forEachOrdered(l::addSuppressed));
136+
if (errors.isEmpty()) return;
137+
if (errors.size() == 1) throw errors.get(0);
138+
throw errors.stream()
139+
.collect(() -> Container.makeException(errors),
140+
Throwable::addSuppressed,
141+
(l, r) -> Arrays.stream(r.getSuppressed()).forEachOrdered(l::addSuppressed));
153142
}
154143

155144
protected Stream<AutoCloseable> moreMembers() {
156145
return Stream.empty();
157146
}
158147

159148
public boolean setClosed(boolean state) {
160-
return Polyfill.updateBoolState(isClosed(), state,
161-
() -> closed.get().complete(null),
162-
() -> closed.set(new CompletableFuture<>()));
149+
return Polyfill.updateBoolState(isClosed(), state, () -> closed.get().complete(null), () -> closed.set(new CompletableFuture<>()));
163150
}
164151

165152
@Override

src/main/java/org/comroid/commands/impl/CommandManager.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ public final Set<CommandCapability> getCapabilities() {
7474
}
7575

7676
@SuppressWarnings("UnusedReturnValue")
77-
public final Set<Node> register(final Object target) {
77+
public Set<Node> register(final Object target) {
7878
var klass = target instanceof Class<?> cls0 ? cls0 : target.getClass();
7979
var groups = new ArrayList<Group>();
8080
var calls = new ArrayList<Call>();
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
@Deprecated
1+
@Deprecated(forRemoval = true)
22
package org.comroid.commands;

src/main/java/org/comroid/interaction/InteractionCore.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public void register(Class<?> target) {
4444

4545
public void register(Object target) {
4646
register(new InstanceRegistry(target));
47+
addChild(target);
4748
}
4849

4950
/// verify minimum required components
@@ -54,6 +55,6 @@ public void register(Object target) {
5455
}
5556

5657
private void verifyComponentExists(Class<?> type) {
57-
component(type).assertion("No component of type %s was found".formatted(type.getCanonicalName()));
58+
child(type).assertion("No component of type %s was found".formatted(type.getCanonicalName()));
5859
}
5960
}

src/main/java/org/comroid/interaction/adapter/jda/DiscordCommandRegistrator.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ public void initialize() {
9292
}
9393

9494
static void initCommandData(InteractionNode node, CommandData data) {
95-
initDefaultPermission(node.getFilterValues(KEY_PERMISSION), data);
95+
initDefaultPermission(node.getDefinitionValues(KEY_PERMISSION), data);
9696
initNsfw(node, data);
9797
}
9898

src/main/java/org/comroid/interaction/adapter/jda/DiscordResponseChain.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public MessageCreateData convertResponse(Response response) {
9595

9696
var message = new MessageCreateBuilder();
9797

98-
if (response.isPlaintext()) message.setContent(response.content());
98+
if (response.isPlaintext()) message.setContent(response.getContent());
9999
else message.addEmbeds(response.toEmbed().build());
100100

101101
return message.build();

src/main/java/org/comroid/interaction/adapter/jda/JdaAdapter.java

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.comroid.interaction.adapter.jda;
22

33
import lombok.Value;
4+
import lombok.experimental.NonFinal;
45
import lombok.experimental.StandardException;
56
import lombok.extern.java.Log;
67
import net.dv8tion.jda.api.JDA;
@@ -29,10 +30,12 @@
2930

3031
import java.util.Arrays;
3132
import java.util.Map;
33+
import java.util.Objects;
3234
import java.util.stream.Stream;
3335

3436
@Log
3537
@Value
38+
@NonFinal
3639
public class JdaAdapter extends Component.Base implements EventListener {
3740
public static final String KEY_CONTEXT = "context.discord";
3841
public static final String CONTEXT_COMMAND = "command";
@@ -76,7 +79,6 @@ public void onEvent(@NonNull GenericEvent generic) {
7679
try {
7780
initContextVariables(event, builder);
7881

79-
params:
8082
if (event instanceof GenericCommandInteractionEvent command) {
8183
// lombok is stupid - find better solution for this shit
8284
//var node = ReflectionHelper.fieldByName(InteractionContext.Builder.class, builder, "node", MethodNode.class);
@@ -164,14 +166,14 @@ private static void autoComplete(InteractionContext context, CommandAutoComplete
164166

165167
event.replyChoices(param.getCompletion()
166168
.stream()
167-
.flatMap(completion -> Stream.concat(Arrays.stream(completion.strings()),
169+
.flatMap(completion -> Stream.concat(Arrays.stream(completion.strings()).map(str -> new Command.Choice(str, str)),
168170
Stream.ofNullable(completion.provider())
169171
.filter(type -> !Completion.Provider.class.equals(type))
170172
.map(Activator::get)
171173
.map(it -> it.createInstance(DataNode.of(Map.of())))
172-
.flatMap(provider -> provider.apply(context, param))
173-
.map(String::valueOf)))
174-
.map(str -> new Command.Choice(str, str))
174+
.flatMap(provider -> provider.findCompletionOptions(context, param, event.getFocusedOption().getValue()))
175+
.map(option -> new Command.Choice(Objects.requireNonNullElse(option.display(), option.key()).toString(),
176+
option.key().toString()))))
175177
.toList()).queue();
176178
}
177179

src/main/java/org/comroid/interaction/adapter/stdio/StreamAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ public void sendResponse(InteractionContext context, String response) {
6565

6666
@Override
6767
public @Nullable String convertResponse(Response response) {
68-
return response.content();
68+
return response.getContent();
6969
}
7070

7171
@Override

src/main/java/org/comroid/interaction/annotation/Completion.java

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,20 @@
33
import lombok.Value;
44
import lombok.experimental.NonFinal;
55
import org.comroid.annotations.Instance;
6+
import org.comroid.api.attr.Described;
67
import org.comroid.api.attr.Named;
78
import org.comroid.api.data.seri.type.EnumValueType;
89
import org.comroid.api.data.seri.type.StandardValueType;
910
import org.comroid.api.data.seri.type.ValueType;
1011
import org.comroid.interaction.model.InteractionContext;
1112
import org.comroid.interaction.node.ParameterNode;
13+
import org.jspecify.annotations.Nullable;
1214

1315
import java.lang.annotation.Annotation;
1416
import java.lang.annotation.Retention;
1517
import java.lang.annotation.RetentionPolicy;
1618
import java.lang.annotation.Target;
1719
import java.util.Arrays;
18-
import java.util.function.BiFunction;
1920
import java.util.stream.Stream;
2021

2122
@Target({ })
@@ -27,16 +28,15 @@
2728
/// additional provider for more completion options
2829
Class<? extends Provider> provider() default Provider.Default.class;
2930

30-
interface Provider extends BiFunction<InteractionContext, ParameterNode, Stream<? extends CharSequence>> {
31-
@Override
32-
Stream<? extends CharSequence> apply(InteractionContext context, ParameterNode parameter);
31+
interface Provider {
32+
Stream<Option> findCompletionOptions(InteractionContext context, ParameterNode parameter, String currentValue);
3333

3434
/// default automated implementation for
35-
enum Default implements Provider {
35+
enum Default implements Provider.OfStrings {
3636
@Instance INSTANCE;
3737

3838
@Override
39-
public Stream<? extends CharSequence> apply(InteractionContext context, ParameterNode parameter) {
39+
public Stream<String> findCompletionValues(InteractionContext context, ParameterNode parameter, String currentValue) {
4040
var type = ValueType.of(parameter.getReflect().getType());
4141

4242
if (StandardValueType.BOOLEAN.equals(type)) return Stream.of("true", "false");
@@ -45,6 +45,25 @@ public Stream<? extends CharSequence> apply(InteractionContext context, Paramete
4545
return Stream.empty();
4646
}
4747
}
48+
49+
interface OfStrings extends Provider {
50+
@Override
51+
default Stream<Option> findCompletionOptions(InteractionContext context, ParameterNode parameter, String currentValue) {
52+
return findCompletionValues(context, parameter, currentValue).map(Option::new);
53+
}
54+
55+
Stream<String> findCompletionValues(InteractionContext context, ParameterNode parameter, String currentValue);
56+
}
57+
}
58+
59+
record Option(CharSequence key, @Nullable CharSequence display) {
60+
public Option(CharSequence value) {
61+
this(value, value);
62+
}
63+
64+
public <X extends Named & Described> Option(X it) {
65+
this(it.getName(), it.getDescription());
66+
}
4867
}
4968

5069
@Value

0 commit comments

Comments
 (0)