refactor: remove unneeded event system

This commit is contained in:
TopchetoEU 2023-12-27 20:10:11 +02:00
parent d5fd6e650e
commit d6ee59363f
Signed by: topchetoeu
GPG Key ID: 6531B8583E5F6ED4
9 changed files with 21 additions and 283 deletions

View File

@ -15,7 +15,6 @@ import me.topchetoeu.jscript.engine.values.ArrayValue;
import me.topchetoeu.jscript.engine.values.NativeFunction;
import me.topchetoeu.jscript.engine.values.ObjectValue;
import me.topchetoeu.jscript.engine.values.Values;
import me.topchetoeu.jscript.events.Observer;
import me.topchetoeu.jscript.exceptions.EngineException;
import me.topchetoeu.jscript.exceptions.InterruptException;
import me.topchetoeu.jscript.exceptions.SyntaxException;
@ -31,21 +30,6 @@ import me.topchetoeu.jscript.permissions.PermissionsManager;
import me.topchetoeu.jscript.permissions.PermissionsProvider;
public class Main {
public static class Printer implements Observer<Object> {
public void next(Object data) {
Values.printValue(null, data);
System.out.println();
}
public void error(RuntimeException err) {
Values.printError(err, null);
}
public void finish() {
engineTask.interrupt();
}
}
static Thread engineTask, debugTask;
static Engine engine = new Engine();
static DebugServer debugServer = new DebugServer();

View File

@ -1,25 +1,27 @@
package me.topchetoeu.jscript.events;
import me.topchetoeu.jscript.exceptions.InterruptException;
public interface Awaitable<T> {
T await() throws FinishedException;
public static interface ResultHandler<T> {
public void onResult(T data);
}
public static interface ErrorHandler {
public void onError(RuntimeException error);
}
default Observable<T> toObservable() {
return sub -> {
var thread = new Thread(() -> {
try {
sub.next(await());
sub.finish();
}
catch (InterruptException | FinishedException e) { sub.finish(); }
catch (RuntimeException e) {
sub.error(e);
}
}, "Awaiter");
thread.start();
T await();
return () -> thread.interrupt();
};
default void handle(ResultHandler<T> onResult, ErrorHandler onError) {
var thread = new Thread(() -> {
try {
onResult.onResult(await());
}
catch (RuntimeException e) {
onError.onError(e);
}
}, "Awaiter");
thread.start();
}
default void handle(ResultHandler<T> onResult) {
handle(onResult, err -> {});
}
}

View File

@ -1,49 +0,0 @@
package me.topchetoeu.jscript.events;
import java.util.HashSet;
public class Event<T> implements Observer<T>, Observable<T> {
private HashSet<Observer<T>> handlers = new HashSet<>();
public Handle on(Observer<T> handler) {
if (handlers == null) {
handler.finish();
return () -> {};
}
handlers.add(handler);
return () -> {
if (handlers == null) return;
handlers.remove(handler);
};
}
public boolean isFinished() {
return handlers == null;
}
public void next(T value) {
if (handlers == null) throw new IllegalStateException("Cannot use a finished event.");
for (var handler : handlers) {
handler.next(value);
}
}
public void error(RuntimeException value) {
if (handlers == null) throw new IllegalStateException("Cannot use a finished event.");
for (var handler : handlers) {
handler.error(value);
}
handlers.clear();
handlers = null;
}
public void finish() {
if (handlers == null) throw new IllegalStateException("Cannot use a finished event.");
for (var handler : handlers) {
handler.finish();
}
handlers.clear();
handlers = null;
}
}

View File

@ -1,7 +0,0 @@
package me.topchetoeu.jscript.events;
public class FinishedException extends RuntimeException {
public FinishedException() {
super("The observable has ended.");
}
}

View File

@ -1,5 +0,0 @@
package me.topchetoeu.jscript.events;
public interface Handle {
void free();
}

View File

@ -1,75 +0,0 @@
package me.topchetoeu.jscript.events;
public interface Observable<T> {
Handle on(Observer<T> val);
default Handle once(Observer<T> observer) {
// Java is fucking retarded
var unhandler = new Handle[1];
var shouldUnsub = new boolean[1];
unhandler[0] = on(new Observer<>() {
public void next(T data) {
observer.next(data);
if (unhandler[0] == null) shouldUnsub[0] = true;
else unhandler[0].free();
}
public void error(RuntimeException err) {
observer.error(err);
if (unhandler[0] == null) shouldUnsub[0] = true;
else unhandler[0].free();
}
public void finish() {
observer.finish();
if (unhandler[0] == null) shouldUnsub[0] = true;
else unhandler[0].free();
}
});
if (shouldUnsub[0]) {
unhandler[0].free();
return () -> {};
}
else return unhandler[0];
}
@SuppressWarnings("unchecked")
default Awaitable<T> toAwaitable() {
return () -> {
var notifier = new Notifier();
var valRef = new Object[1];
var isErrRef = new boolean[1];
once(new Observer<>() {
public void next(T data) {
valRef[0] = data;
notifier.next();
}
public void error(RuntimeException err) {
isErrRef[0] = true;
valRef[0] = err;
notifier.next();
}
public void finish() {
isErrRef[0] = true;
valRef[0] = new FinishedException();
notifier.next();
}
});
notifier.await();
if (isErrRef[0]) throw (RuntimeException)valRef[0];
else return (T)valRef[0];
};
}
default Observable<T> encapsulate() {
return val -> on(val);
}
default <T2> Observable<T2> pipe(Pipe<T, T2> pipe) {
return sub -> on(pipe.apply(sub));
}
default WarmObservable<T> warmUp() {
return new WarmObservable<>(this);
}
}

View File

@ -1,7 +0,0 @@
package me.topchetoeu.jscript.events;
public interface Observer<T> {
public void next(T data);
public default void error(RuntimeException err) {}
public default void finish() { }
}

View File

@ -1,59 +0,0 @@
package me.topchetoeu.jscript.events;
public interface Pipe<T, T2> {
Observer<T> apply(Observer<T2> obs);
// void next(T val, Observer<T2> target);
// default void error(RuntimeException err, Observer<T2> target) {
// target.error(err);
// }
// default void finish(Observer<T2> target) {
// target.finish();
// }
public static interface MapFunc<T1, T2> {
T2 map(T1 val);
}
public static <T1, T2> Pipe<T1, T2> map(MapFunc<T1, T2> func) {
return o -> val -> o.next(func.map(val));
}
public static <T> Pipe<T, T> filter(MapFunc<T, Boolean> func) {
return o -> val -> {
if (func.map(val)) o.next(val);
};
}
public static <T> Pipe<T, T> skip(int n) {
var i = new int[1];
return target -> val -> {
if (i[0] >= n) target.next(val);
else i[0]++;
};
}
public static <T> Pipe<T, T> limit(int n) {
return target -> new Observer<T>() {
private int i;
public void next(T val) {
if (i >= n) target.finish();
else {
target.next(val);
i++;
}
}
public void error(RuntimeException err) {
if (i < n) target.error(err);
}
public void finish() {
if (i < n) target.finish();
}
};
}
public static <T> Pipe<T, T> first() {
return limit(1);
}
public static <T> Pipe<Observable<T>, T> merge() {
return target -> val -> val.on(target);
}
}

View File

@ -1,46 +0,0 @@
package me.topchetoeu.jscript.events;
import java.util.HashSet;
public class WarmObservable<T> implements Observable<T>, Handle {
private HashSet<Observer<T>> observers = new HashSet<>();
private Handle handle;
@Override
public Handle on(Observer<T> val) {
if (observers == null) return () -> {};
observers.add(val);
return () -> observers.remove(val);
}
@Override
public void free() {
if (observers == null) return;
handle.free();
handle = null;
observers = null;
}
public WarmObservable(Observable<T> observable) {
observable.on(new Observer<>() {
public void next(T data) {
for (var obs : observers) obs.next(data);
}
public void error(RuntimeException err) {
for (var obs : observers) obs.error(err);
handle = null;
observers = null;
}
public void finish() {
for (var obs : observers) obs.finish();
handle = null;
observers = null;
}
});
}
@Override
public WarmObservable<T> warmUp() {
return this;
}
}