Bump language level to JDK 16 to get records; update example1

This commit is contained in:
Tony Garnock-Jones 2021-04-15 10:49:05 +02:00
parent af611e1b2b
commit d6c8a80995
7 changed files with 77 additions and 38 deletions

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="11" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_16" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

View File

@ -5,6 +5,7 @@ import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Function;
import java.util.logging.Level;
import java.util.logging.Logger;
@ -63,11 +64,11 @@ public class Actor implements Executor {
return new Actor().ref(o);
}
public static Promise<Ref> boot(ThrowingSupplier<IEntity> f) {
public static Promise<Ref> boot(Function<Turn, IEntity> f) {
final Promise<Ref> p = new Promise<>();
final Actor a = new Actor();
a.execute(
() -> p.resolveCalling(() -> a.ref(f.get())),
() -> Turn.forActor(a, t -> p.resolveCalling(() -> a.ref(f.apply(t)))),
() -> p.rejectWith(new ActorTerminated(a)));
return p;
}

View File

@ -114,14 +114,12 @@ public class Turn {
});
}
public Promise<Turn> sync_(Ref peer) {
Promise<Turn> p = new Promise<>();
public void sync_(Ref peer, Consumer<Turn> k) {
this._sync_(peer, this.ref(new Entity() {
public void message_(Turn t, Object _message) {
p.resolveWith(t);
k.accept(t);
}
}));
return p;
}
private void _sync_(Ref peer, Ref callback) {
@ -134,4 +132,16 @@ public class Turn {
this.enqueue(peer.getActor(), t -> peer.getEntity().message_(t, body));
}
}
public void later(long delayMilliseconds, Consumer<Turn> action) {
_actor.later(delayMilliseconds, () -> Turn.forActor(_actor, action));
}
public PeriodicTimer every(long periodMilliseconds, Consumer<Turn> action) {
return every(0, periodMilliseconds, action);
}
public PeriodicTimer every(long initialDelayMilliseconds, long periodMilliseconds, Consumer<Turn> action) {
return _actor.every(initialDelayMilliseconds, periodMilliseconds, () -> Turn.forActor(_actor, action));
}
}

View File

@ -1,6 +1,8 @@
package org.syndicate_lang.actors.example.example1;
public interface IValueHolder<T> {
T get();
void set(T newValue);
import org.syndicate_lang.actors.Ref;
public interface IValueHolder {
record Get(Ref k) implements IValueHolder {}
record Set<T>(T newValue) implements IValueHolder {}
}

View File

@ -1,23 +1,35 @@
package org.syndicate_lang.actors.example.example1;
import org.syndicate_lang.actors.Actor;
import org.syndicate_lang.actors.Entity;
import org.syndicate_lang.actors.Ref;
import org.syndicate_lang.actors.Turn;
public class Main {
public class Main extends Entity {
public static void main(String[] args) throws InterruptedException {
Actor.convenientLogging();
Turn.forActor(new Actor().daemonize(), t -> {
final var vh = Actor.forEntity(new ValueHolder<>("There"));
vh.getActor().daemonize();
final var m = Actor.forEntity(new Main());
m.async(10, (m_, ac) -> m_.run(ac, vh));
final var m = Actor.boot(u -> {
Main main = new Main();
u.later(10, v -> main.run(v, vh));
return main;
});
@SuppressWarnings("unchecked")
IValueHolder<String> vv = vh.syncProxy(IValueHolder.class);
System.out.println("Value: " + vv.get());
vv.set("Second");
System.out.println("Value: " + vv.get());
System.out.println("Underlying: " + Ref.from(vv));
t.message_(vh, new IValueHolder.Get(t.ref(new Entity() {
public void message_(Turn t0, Object v0) {
System.out.println("Value: " + v0);
t0.message_(vh, new IValueHolder.Set<>("Second"));
t0.message_(vh, new IValueHolder.Get(t0.ref(new Entity() {
public void message_(Turn t1, Object v1) {
System.out.println("Value: " + v1);
System.out.println("Cell: " + vh);
}
})));
}
})));
});
Actor.awaitAll();
System.out.println("Overall main returning");
@ -26,15 +38,23 @@ public class Main {
private Actor me;
private int greetingCounter = 0;
public void run(Actor me, Ref<ValueHolder<String>> vh) {
this.me = me;
this.greet((String) vh.syncProxy(IValueHolder.class).get());
vh.syncVoid((v, _ac) -> v.set("World"));
me.every(1000, () -> {
if (greetingCounter >= 3) me.stop();
this.greet(vh.sync((v, _ac) -> v.get()).await());
public void run(Turn t0, Ref vh) {
me = t0.getActor();
t0.message_(vh, new IValueHolder.Get(t0.ref(new Entity() {
public void message_(Turn t1, Object v1) {
Main.this.greet((String) v1);
t1.message_(vh, new IValueHolder.Set<>("World"));
t1.every(1000, t -> {
if (greetingCounter >= 3) t.quit();
t.message_(vh, new IValueHolder.Get(t.ref(new Entity() {
public void message_(Turn t2, Object v2) {
Main.this.greet((String) v2);
}
})));
});
}
})));
}
public void greet(String who) {
me.log().info((greetingCounter++) + ": Hi " + who);

View File

@ -1,17 +1,22 @@
package org.syndicate_lang.actors.example.example1;
public class ValueHolder<T> implements IValueHolder<T> {
import org.syndicate_lang.actors.Entity;
import org.syndicate_lang.actors.Turn;
public class ValueHolder<T> extends Entity {
private T value;
public ValueHolder(T initialValue) {
this.value = initialValue;
}
public T get() {
return this.value;
@Override
public void message_(Turn turn, Object body) {
if (body instanceof IValueHolder.Get op) {
turn.message_(op.k(), this.value);
} else if (body instanceof IValueHolder.Set) {
IValueHolder.Set<T> op = (IValueHolder.Set<T>) body;
this.value = op.newValue();
}
public void set(T newValue) {
this.value = newValue;
}
}

View File

@ -4,6 +4,7 @@
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/java/org/syndicate_lang/actors/example/example2" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />