87 lines
2.5 KiB
Java
87 lines
2.5 KiB
Java
package org.syndicate_lang.actors;
|
|
|
|
import java.lang.reflect.Proxy;
|
|
import java.util.function.Consumer;
|
|
import java.util.function.Function;
|
|
|
|
public class Remote<T> {
|
|
private final Actor _actor;
|
|
private final T _target;
|
|
|
|
public Remote(Actor actor, T target) {
|
|
this._actor = actor;
|
|
this._target = target;
|
|
}
|
|
|
|
public Actor getActor() {
|
|
return _actor;
|
|
}
|
|
|
|
public void async(Consumer<T> f) {
|
|
this._actor.execute(() -> f.accept(this._target));
|
|
}
|
|
|
|
public void async(long delayMilliseconds, Consumer<T> f) {
|
|
this._actor.later(delayMilliseconds, () -> f.accept(this._target));
|
|
}
|
|
|
|
public Promise<?> syncVoid(Consumer<T> f) {
|
|
return this.sync((t) -> {
|
|
f.accept(t);
|
|
return null;
|
|
});
|
|
}
|
|
|
|
public Promise<?> syncVoid(long delayMilliseconds, Consumer<T> f) {
|
|
return this.sync(delayMilliseconds, (t) -> {
|
|
f.accept(t);
|
|
return null;
|
|
});
|
|
}
|
|
|
|
public<R> Promise<R> sync(Function<T, R> f) {
|
|
Promise<R> p = new Promise<>();
|
|
this._actor.execute(
|
|
() -> p.resolveWith(f.apply(this._target)),
|
|
() -> p.rejectWith(this._actor.getExitReason()));
|
|
return p;
|
|
}
|
|
|
|
public<R> Promise<R> sync(long delayMilliseconds, Function<T, R> f) {
|
|
Promise<R> p = new Promise<>();
|
|
this._actor.later(
|
|
delayMilliseconds,
|
|
() -> p.resolveWith(f.apply(this._target)),
|
|
() -> p.rejectWith(this._actor.getExitReason()));
|
|
return p;
|
|
}
|
|
|
|
private<I> void checkTargetInstance(Class<I> c) {
|
|
if (!c.isInstance(this._target)) {
|
|
throw new IllegalArgumentException("target is not an instance of " + c);
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public<I> I syncProxy(Class<I> c) {
|
|
checkTargetInstance(c);
|
|
return (I) Proxy.newProxyInstance(c.getClassLoader(), new Class[] { c }, new SyncProxy<>(this));
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public<I> I asyncProxy(Class<I> c) {
|
|
checkTargetInstance(c);
|
|
return (I) Proxy.newProxyInstance(c.getClassLoader(), new Class[] { c }, new AsyncProxy<>(this));
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
public static<I, T extends I> Remote<T> from(I proxy) {
|
|
return ((AbstractProxy<T>) Proxy.getInvocationHandler(proxy)).ref();
|
|
}
|
|
|
|
@Override
|
|
public String toString() {
|
|
return this.getClass().getSimpleName() + "(" + this._actor.getName() + "::" + this._target + ")";
|
|
}
|
|
}
|