Skip to content

Commit

Permalink
rework determine handler upgrade to use gross generics properly
Browse files Browse the repository at this point in the history
  • Loading branch information
mcmonkey4eva committed Jun 28, 2023
1 parent 0f87733 commit d39e08b
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 42 deletions.
48 changes: 27 additions & 21 deletions src/main/java/com/denizenscript/denizencore/events/ScriptEvent.java
Expand Up @@ -26,8 +26,8 @@
import com.denizenscript.denizencore.utilities.text.StringHolder;

import java.util.*;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import java.util.regex.Pattern;

/**
Expand All @@ -48,14 +48,14 @@ public ScriptEvent clone() {
}

public ScriptEvent() {
registerOptionalDetermination("cancelled", ElementTag.class, (context, cancelled) -> {
registerOptionalDetermination("cancelled", ElementTag.class, (event, context, cancelled) -> {
if (!cancelled.isBoolean()) {
Debug.echoError("Invalid input '" + cancelled + "' to 'cancelled' determination: must be a boolean.");
return false;
}
this.cancelled = cancelled.asBoolean();
Debug.echoDebug(context, this.cancelled ? "Event cancelled!" : "Event uncancelled!");
cancellationChanged();
event.cancelled = cancelled.asBoolean();
Debug.echoDebug(context, event.cancelled ? "Event cancelled!" : "Event uncancelled!");
event.cancellationChanged();
return true;
});
}
Expand Down Expand Up @@ -167,7 +167,7 @@ public static class InternalEventData {
/**
* Determination handlers, mapped by prefix
*/
public final Map<String, DeterminationHandler<ObjectTag>> determinations = new HashMap<>();
public final Map<String, OptionalDeterminationHandler<? extends ScriptEvent, ObjectTag>> determinations = new HashMap<>();
}

/**
Expand Down Expand Up @@ -651,26 +651,26 @@ public static boolean isDefaultDetermination(ObjectTag determination) {
return false;
}

public final <T extends ObjectTag> void registerOptionalDetermination(String prefix, Class<T> inputType, DeterminationHandler<T> handler) {
eventData.determinations.put(prefix != null ? CoreUtilities.toLowerCase(prefix) : null, (context, objectTag) -> {
T converted = objectTag.asType(inputType, context);
public final <TEvent extends ScriptEvent, TType extends ObjectTag> void registerOptionalDetermination(String prefix, Class<TType> inputType, OptionalDeterminationHandler<TEvent, TType> handler) {
eventData.determinations.put(prefix != null ? CoreUtilities.toLowerCase(prefix) : null, (evt, context, objectTag) -> {
TType converted = objectTag.asType(inputType, context);
if (converted == null) {
Debug.echoError("Invalid input to '" + prefix + "' determination: '" + objectTag.debuggable() + "<W>' isn't a valid " + DebugInternals.getClassNameOpti(inputType) + '.');
return false;
}
return handler.handle(context, converted);
return handler.handle((TEvent) evt, context, converted);
});
}

public final <T extends ObjectTag> void registerDetermination(String prefix, Class<T> inputType, BiConsumer<TagContext, T> handler) {
registerOptionalDetermination(prefix, inputType, (context, determination) -> {
handler.accept(context, determination);
public final <TEvent extends ScriptEvent, TType extends ObjectTag> void registerDetermination(String prefix, Class<TType> inputType, DeterminationHandler<TEvent, TType> handler) {
this.<TEvent, TType>registerOptionalDetermination(prefix, inputType, (evt, context, determination) -> {
handler.handle(evt, context, determination);
return true;
});
}

public final void registerTextDetermination(String determination, Runnable handler) {
registerDetermination(determination, ObjectTag.class, (context, objectTag) -> handler.run());
public final <TEvent extends ScriptEvent> void registerTextDetermination(String determination, Consumer<TEvent> handler) {
this.<TEvent, ObjectTag>registerDetermination(determination, ObjectTag.class, (evt, context, objectTag) -> handler.accept(evt));
}

@Deprecated(forRemoval = true)
Expand All @@ -687,22 +687,28 @@ public boolean handleDetermination(ScriptPath path, String prefix, ObjectTag val
modifiedValue = new ElementTag(true);
}
if (modifiedPrefix != null) {
DeterminationHandler<ObjectTag> determinationHandler = eventData.determinations.get(CoreUtilities.toLowerCase(modifiedPrefix));
OptionalDeterminationHandler determinationHandler = eventData.determinations.get(CoreUtilities.toLowerCase(modifiedPrefix));
if (determinationHandler != null) {
return determinationHandler.handle(getTagContext(path), modifiedValue);
return determinationHandler.handle(this, getTagContext(path), modifiedValue);
}
}
DeterminationHandler<ObjectTag> defaultHandler = eventData.determinations.get(null);
OptionalDeterminationHandler defaultHandler = eventData.determinations.get(null);
if (defaultHandler != null) {
return defaultHandler.handle(getTagContext(path), value);
return defaultHandler.handle(this, getTagContext(path), value);
}
return applyDetermination(path, prefix != null ? new ElementTag(prefix + ':' + value) : value);
}

@FunctionalInterface
public interface DeterminationHandler<T extends ObjectTag> {
public interface OptionalDeterminationHandler<TEvent extends ScriptEvent, TType extends ObjectTag> {

boolean handle(TagContext context, T value);
boolean handle(TEvent event, TagContext context, TType value);
}

@FunctionalInterface
public interface DeterminationHandler<TEvent extends ScriptEvent, TType extends ObjectTag> {

void handle(TEvent event, TagContext context, TType value);
}

public ScriptEntryData getScriptEntryData() {
Expand Down
Expand Up @@ -55,7 +55,7 @@ public CustomScriptEvent() {
instance = this;
registerCouldMatcher("custom event");
registerSwitches("id", "data");
registerDetermination("output", ObjectTag.class, (context, output) -> determinations.addObject(output));
this.<CustomScriptEvent, ObjectTag>registerDetermination("output", ObjectTag.class, (evt, context, output) -> evt.determinations.addObject(output));
}

@Override
Expand Down
Expand Up @@ -153,39 +153,39 @@ public WebserverWebRequestScriptEvent() {
instance = this;
registerCouldMatcher("webserver web request");
registerSwitches("port", "path", "method", "has_response");
registerOptionalDetermination("code", ElementTag.class, (context, code) -> {
this.<WebserverWebRequestScriptEvent, ElementTag>registerOptionalDetermination("code", ElementTag.class, (evt, context, code) -> {
if (!code.isInt()) {
Debug.echoError("Invalid code '" + code + "': not an number");
return false;
}
response.code = code.asInt();
evt.response.code = code.asInt();
return true;
});
registerDetermination("headers", MapTag.class, (context, headers) -> {
this.<WebserverWebRequestScriptEvent, MapTag>registerDetermination("headers", MapTag.class, (evt, context, headers) -> {
for (Map.Entry<StringHolder, ObjectTag> header : headers.map.entrySet()) {
exchange.getResponseHeaders().set(header.getKey().str, header.getValue().toString());
evt.exchange.getResponseHeaders().set(header.getKey().str, header.getValue().toString());
}
});
registerResponseDetermination("raw_text_content", ElementTag.class, (context, rawText) -> {
response.rawContent = rawText.asString().getBytes(StandardCharsets.UTF_8);
registerResponseDetermination("raw_text_content", ElementTag.class, (evt, context, rawText) -> {
evt.response.rawContent = rawText.asString().getBytes(StandardCharsets.UTF_8);
return true;
});
registerResponseDetermination("raw_binary_content", BinaryTag.class, (context, rawBinary) -> {
response.rawContent = rawBinary.data;
registerResponseDetermination("raw_binary_content", BinaryTag.class, (evt, context, rawBinary) -> {
evt.response.rawContent = rawBinary.data;
return true;
});
registerResponseDetermination("file", ElementTag.class, (context, file) -> handleFileDetermination(false, false, file.asString(), context));
registerResponseDetermination("parsed_file", ElementTag.class, (context, file) -> handleFileDetermination(false, true, file.asString(), context));
registerResponseDetermination("cached_file", ElementTag.class, (context, file) -> handleFileDetermination(true, false, file.asString(), context));
registerResponseDetermination("cached_parsed_file", ElementTag.class, (context, file) -> handleFileDetermination(true, true, file.asString(), context));
registerResponseDetermination("parsed_cached_file", ElementTag.class, (context, file) -> handleFileDetermination(true, true, file.asString(), context));
registerResponseDetermination("file", ElementTag.class, (evt, context, file) -> evt.handleFileDetermination(false, false, file.asString(), context));
registerResponseDetermination("parsed_file", ElementTag.class, (evt, context, file) -> evt.handleFileDetermination(false, true, file.asString(), context));
registerResponseDetermination("cached_file", ElementTag.class, (evt, context, file) -> evt.handleFileDetermination(true, false, file.asString(), context));
registerResponseDetermination("cached_parsed_file", ElementTag.class, (evt, context, file) -> evt.handleFileDetermination(true, true, file.asString(), context));
registerResponseDetermination("parsed_cached_file", ElementTag.class, (evt, context, file) -> evt.handleFileDetermination(true, true, file.asString(), context));
}
public <T extends ObjectTag> void registerResponseDetermination(String prefix, Class<T> inputType, DeterminationHandler<T> handler) {
registerOptionalDetermination(prefix, inputType, (context, determination) -> {
if (!response.hasResponse) {
response.hasResponse = true;
return handler.handle(context, determination);

public <T extends ObjectTag> void registerResponseDetermination(String prefix, Class<T> inputType, OptionalDeterminationHandler<WebserverWebRequestScriptEvent, T> handler) {
this.<WebserverWebRequestScriptEvent, T>registerOptionalDetermination(prefix, inputType, (event, context, determination) -> {
if (!event.response.hasResponse) {
event.response.hasResponse = true;
return handler.handle(event, context, determination);
}
return false;
});
Expand Down Expand Up @@ -214,7 +214,7 @@ public static byte[] readFileContent(File f) throws IOException {
input.close();
return result;
}

public boolean handleFileDetermination(boolean cache, boolean parse, String determination, TagContext context) {
response.hasResponse = true;
File root = new File(DenizenCore.implementation.getDataFolder(), CoreConfiguration.webserverRoot);
Expand Down

0 comments on commit d39e08b

Please sign in to comment.