Print und Evaluate aufgeteilt (Das war schmerzhaft). V1.0
This commit is contained in:
parent
2fca2c201c
commit
808d952198
|
@ -2,20 +2,31 @@ package com.example;
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef;
|
import akka.actor.typed.ActorRef;
|
||||||
import akka.actor.typed.Behavior;
|
import akka.actor.typed.Behavior;
|
||||||
import akka.actor.typed.javadsl.AbstractBehavior;
|
|
||||||
import akka.actor.typed.javadsl.ActorContext;
|
|
||||||
import akka.actor.typed.javadsl.Behaviors;
|
|
||||||
import akka.actor.typed.javadsl.Receive;
|
|
||||||
import akka.actor.typed.javadsl.*;
|
import akka.actor.typed.javadsl.*;
|
||||||
|
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
public class Actor extends AbstractBehavior<Actor.Message> {
|
public class Actor extends AbstractBehavior<Actor.Message> {
|
||||||
|
|
||||||
//Timer für die Berechnung
|
|
||||||
final TimerScheduler<Message> timer;
|
//Timer, um bei den Berechnungen eine Sekunde lang zu warten
|
||||||
|
TimerScheduler<Message> timer;
|
||||||
|
|
||||||
|
Expression expression;
|
||||||
|
|
||||||
|
//Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird
|
||||||
|
String operationString;
|
||||||
|
|
||||||
|
//Referenz auf den initialen Actor
|
||||||
|
ActorRef<PrintAndEvaluate.Message> initial;
|
||||||
|
|
||||||
|
//Referenz auf den (potenziellen) OberSubActor. Es ist immer entweder initial oder oberActor null.
|
||||||
|
ActorRef<Actor.Message> oberActor;
|
||||||
|
|
||||||
|
//Linke Seite: true, Rechte Seite: false um zu wissen, ob dieser Actor ein linkes oder rechtes Kind ist.
|
||||||
|
boolean side;
|
||||||
|
|
||||||
//Zurückgegebener String & Integer von der linken Seite
|
//Zurückgegebener String & Integer von der linken Seite
|
||||||
String leftString;
|
String leftString;
|
||||||
int leftInt;
|
int leftInt;
|
||||||
|
@ -24,103 +35,278 @@ public class Actor extends AbstractBehavior<Actor.Message> {
|
||||||
String rightString;
|
String rightString;
|
||||||
int rightInt;
|
int rightInt;
|
||||||
|
|
||||||
//Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird
|
public interface Message {}
|
||||||
String operationString;
|
|
||||||
|
|
||||||
String name;
|
//Message kommt von dem initialen Actor
|
||||||
Expression expression;
|
public record PrintMessage(ActorRef<PrintAndEvaluate.Message> sender, Expression expression) implements Message{}
|
||||||
public interface Message{}
|
public record SubPrintMessage(ActorRef<Actor.Message> sender, Expression expression, boolean side) implements Message{}
|
||||||
|
|
||||||
public record Compute() implements Message{}
|
//Message kommt von einem Actor
|
||||||
|
public record EvaluateMessage(ActorRef<com.example.PrintAndEvaluate.Message> sender, Expression expression) implements Message{}
|
||||||
public record PrintAndEvaluate(Expression expression) implements Message{}
|
public record SubEvaluateMessage(ActorRef<Actor.Message> sender, Expression expression, boolean side) implements Message{}
|
||||||
|
|
||||||
//Antwort von dem linken Kind
|
//Antwort von dem linken Kind
|
||||||
public record LeftResponse(String string, int wert) implements Message{}
|
public record LeftStringResponse(String string) implements Message{}
|
||||||
|
public record LeftIntResponse(int wert) implements Message{}
|
||||||
|
|
||||||
//Antwort von dem rechten Kind
|
//Antwort von dem rechten Kind
|
||||||
public record RightResponse(String string, int wert) implements Message{}
|
public record RightStringResponse(String string) implements Message{}
|
||||||
|
public record RightIntResponse(int wert) implements Message{}
|
||||||
|
|
||||||
private Actor(ActorContext<Message> context, String name, TimerScheduler<Message> timer){
|
//Nachricht an sich selbst, um nach einer Sekunde Wartezeit das Ergebnis zu berechnen
|
||||||
|
public record Compute() implements Message{}
|
||||||
|
|
||||||
|
private Actor(ActorContext<Actor.Message> context, TimerScheduler<Message> timer){
|
||||||
super(context);
|
super(context);
|
||||||
this.name = name;
|
|
||||||
this.timer = timer;
|
this.timer = timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Behavior<Actor.Message> create(String name){
|
public static Behavior<Actor.Message> create(){
|
||||||
return Behaviors.setup(context -> Behaviors.withTimers(timers -> new Actor(context, name, timers)));
|
return Behaviors.setup(context -> Behaviors.withTimers(timers -> new Actor(context,timers)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Receive<Actor.Message> createReceive(){
|
public Receive<Actor.Message> createReceive(){
|
||||||
return newReceiveBuilder()
|
return newReceiveBuilder()
|
||||||
.onMessage(PrintAndEvaluate.class, this::onPrintAndEvaluate)
|
.onMessage(PrintMessage.class, this::onPrintMessage)
|
||||||
.onMessage(LeftResponse.class, this::onLeftResponse)
|
.onMessage(SubPrintMessage.class, this::onSubPrintMessage)
|
||||||
.onMessage(RightResponse.class, this::onRightResponse)
|
.onMessage(LeftStringResponse.class, this::onLeftStringResponse)
|
||||||
|
.onMessage(RightStringResponse.class, this::onRightStringResponse)
|
||||||
|
.onMessage(EvaluateMessage.class, this::onEvaluateMessage)
|
||||||
|
.onMessage(SubEvaluateMessage.class, this::onSubEvaluateMessage)
|
||||||
|
.onMessage(LeftIntResponse.class, this::onLeftIntResponse)
|
||||||
|
.onMessage(RightIntResponse.class, this::onRightIntResponse)
|
||||||
.onMessage(Compute.class, this::onComputeMessage)
|
.onMessage(Compute.class, this::onComputeMessage)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private Behavior<Message> onPrintAndEvaluate(PrintAndEvaluate message){
|
//Die Nachricht von dem initialen Actor wird verarbeitet und, falls nötig (kein Val), weitere Actors erstellt.
|
||||||
|
//Dabei wird seine Referenz in @initial gespeichert und diese ist für den Formatierungsvorgang
|
||||||
|
private Behavior<Message> onPrintMessage(PrintMessage message){
|
||||||
|
this.initial = message.sender;
|
||||||
this.expression = message.expression;
|
this.expression = message.expression;
|
||||||
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
||||||
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
||||||
this.operationString = "+";
|
this.operationString = "+";
|
||||||
ActorRef<SubActor.Message> LeftSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),add.left(), true));
|
LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),add.left(), true));
|
||||||
ActorRef<SubActor.Message> RightSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),add.right(), false));
|
RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),add.right(), false));
|
||||||
}
|
}
|
||||||
else if (expression instanceof Expression.Sub sub) {
|
else if (expression instanceof Expression.Sub sub) {
|
||||||
this.operationString = "-";
|
this.operationString = "-";
|
||||||
ActorRef<SubActor.Message> LeftSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),sub.left(), true));
|
LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),sub.left(), true));
|
||||||
ActorRef<SubActor.Message> RightSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),sub.right(), false));
|
RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),sub.right(), false));
|
||||||
}
|
}
|
||||||
else if (expression instanceof Expression.Mul mul) {
|
else if (expression instanceof Expression.Mul mul) {
|
||||||
this.operationString = "*";
|
this.operationString = "*";
|
||||||
ActorRef<SubActor.Message> LeftSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),mul.left(), true));
|
LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),mul.left(), true));
|
||||||
ActorRef<SubActor.Message> RightSubActor = getContext().spawnAnonymous(SubActor.create());
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),mul.right(), false));
|
RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),mul.right(), false));
|
||||||
} else if (expression instanceof Expression.Val val) {
|
} else if (expression instanceof Expression.Val val) {
|
||||||
logger.info(val.inner() + "");
|
initial.tell(new PrintAndEvaluate.StringResponse(String.valueOf(val.inner())));
|
||||||
}
|
}
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger logger = Logger.getLogger(Actor.class.getName());
|
//Nachricht von dem Actor, von welchem dieser Actor erstellt wurde, wird verarbeitet und,
|
||||||
|
//falls nötig (kein Val), weitere SubActors erstellt.
|
||||||
//Antwort von dem rechten Kind. Wenn beide Seiten geantwortet haben, wird eine Sekunde gewartet und dann das Ergebnis
|
//Dabei wird seine Referenz in oberActor gespeichert und diese Funktion ist für den Formatierungsvorgang
|
||||||
//berechnet in Compute()
|
private Behavior<Message> onSubPrintMessage(SubPrintMessage message){
|
||||||
private Behavior<Message> onLeftResponse(LeftResponse response){
|
this.oberActor = message.sender;
|
||||||
this.leftString = response.string;
|
this.expression = message.expression;
|
||||||
this.leftInt = response.wert;
|
this.side = message.side;
|
||||||
if(this.rightString != null){
|
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
||||||
this.timer.startSingleTimer(new Compute(),Duration.ofSeconds(1));
|
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
||||||
|
this.operationString = "+";
|
||||||
|
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(Actor.create());
|
||||||
|
subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),add.left(), true));
|
||||||
|
ActorRef<Message> subActorRight = getContext().spawnAnonymous(Actor.create());
|
||||||
|
subActorRight.tell(new SubPrintMessage(getContext().getSelf(),add.right(), false));
|
||||||
}
|
}
|
||||||
return this;
|
else if (expression instanceof Expression.Sub sub) {
|
||||||
|
this.operationString = "-";
|
||||||
|
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(Actor.create());
|
||||||
|
subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),sub.left(), true));
|
||||||
|
ActorRef<Message> subActorRight = getContext().spawnAnonymous(Actor.create());
|
||||||
|
subActorRight.tell(new SubPrintMessage(getContext().getSelf(),sub.right(), false));
|
||||||
}
|
}
|
||||||
|
else if (expression instanceof Expression.Mul mul) {
|
||||||
//Antwort von dem rechten Kind. Wenn beide Seiten geantwortet haben, wird eine Sekunde gewartet und dann das Ergebnis
|
this.operationString = "*";
|
||||||
//berechnet in Compute()
|
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(Actor.create());
|
||||||
private Behavior<Message> onRightResponse(RightResponse response){
|
subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),mul.left(), true));
|
||||||
this.rightString = response.string;
|
ActorRef<Message> subActorRight = getContext().spawnAnonymous(Actor.create());
|
||||||
this.rightInt = response.wert;
|
subActorRight.tell(new SubPrintMessage(getContext().getSelf(),mul.right(), false));
|
||||||
if(this.leftString != null){
|
} else if (expression instanceof Expression.Val val) {
|
||||||
this.timer.startSingleTimer(new Compute(),Duration.ofSeconds(1));
|
if(side == true){
|
||||||
}
|
oberActor.tell(new Actor.LeftStringResponse(String.valueOf(val.inner())));
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Behavior<Message> onComputeMessage(Compute response){
|
|
||||||
if(operationString.equals("+")){
|
|
||||||
logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt + rightInt));
|
|
||||||
} else if (operationString.equals("-")) {
|
|
||||||
logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt - rightInt));
|
|
||||||
}else{
|
}else{
|
||||||
logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt * rightInt));
|
oberActor.tell(new Actor.RightStringResponse(String.valueOf(val.inner())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Antwort von dem linken Teilkind wird empfangen, verarbeitet und an den nächsthöheren Actor geschickt, falls von beiden Teilkindern
|
||||||
|
//bereits eine Antwort erhalten wurde. Hier für den Formatierungsvorgang.
|
||||||
|
private Behavior<Message> onLeftStringResponse(LeftStringResponse response){
|
||||||
|
this.leftString = response.string;
|
||||||
|
if(this.rightString != null){
|
||||||
|
if(this.initial != null){
|
||||||
|
initial.tell(new PrintAndEvaluate.StringResponse("(" + leftString + operationString + rightString +")"));
|
||||||
|
}else {
|
||||||
|
if(side == true){
|
||||||
|
oberActor.tell(new Actor.LeftStringResponse("(" + leftString + operationString + rightString +")"));
|
||||||
|
}else {
|
||||||
|
oberActor.tell(new Actor.RightStringResponse("(" + leftString + operationString + rightString +")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
//Antwort von dem rechten Teilkind wird empfangen, verarbeitet und an den nächsthöheren Actor geschickt, falls von beiden Teilkindern
|
||||||
|
//bereits eine Antwort erhalten wurde. Hier für den Formatierungsvorgang.
|
||||||
|
private Behavior<Message> onRightStringResponse(RightStringResponse response) {
|
||||||
|
this.rightString = response.string;
|
||||||
|
if (this.leftString != null) {
|
||||||
|
if (this.initial != null) {
|
||||||
|
initial.tell(new PrintAndEvaluate.StringResponse("(" + leftString + operationString + rightString + ")"));
|
||||||
|
} else {
|
||||||
|
if (side == true) {
|
||||||
|
oberActor.tell(new Actor.LeftStringResponse("(" + leftString + operationString + rightString + ")"));
|
||||||
|
} else {
|
||||||
|
oberActor.tell(new Actor.RightStringResponse("(" + leftString + operationString + rightString + ")"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Die Nachricht von dem initialen Actor wird verarbeitet und, falls nötig (kein Val), weitere Actors erstellt.
|
||||||
|
//Dabei wird seine Referenz in @initial gespeichert und diese ist für den Rechenvorgang
|
||||||
|
private Behavior<Message> onEvaluateMessage(EvaluateMessage message){
|
||||||
|
this.initial = message.sender;
|
||||||
|
this.expression = message.expression;
|
||||||
|
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
||||||
|
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
||||||
|
this.operationString = "+";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.right(), false));
|
||||||
|
}
|
||||||
|
else if (expression instanceof Expression.Sub sub) {
|
||||||
|
this.operationString = "-";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.right(), false));
|
||||||
|
}
|
||||||
|
else if (expression instanceof Expression.Mul mul) {
|
||||||
|
this.operationString = "*";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.right(), false));
|
||||||
|
} else if (expression instanceof Expression.Val val) {
|
||||||
|
initial.tell(new PrintAndEvaluate.IntResponse(val.inner()));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Nachricht von dem Actor, von welchem dieser Actor erstellt wurde, wird verarbeitet und,
|
||||||
|
//falls nötig (kein Val), weitere SubActors erstellt.
|
||||||
|
//Dabei wird seine Referenz in oberActor gespeichert und diese Funktion ist für den Rechenvorgang
|
||||||
|
private Behavior<Message> onSubEvaluateMessage(SubEvaluateMessage message){
|
||||||
|
this.oberActor = message.sender;
|
||||||
|
this.expression = message.expression;
|
||||||
|
this.side = message.side;
|
||||||
|
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
||||||
|
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
||||||
|
this.operationString = "+";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.right(), false));
|
||||||
|
}
|
||||||
|
else if (expression instanceof Expression.Sub sub) {
|
||||||
|
this.operationString = "-";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.right(), false));
|
||||||
|
}
|
||||||
|
else if (expression instanceof Expression.Mul mul) {
|
||||||
|
this.operationString = "*";
|
||||||
|
ActorRef<Actor.Message> LeftSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.left(), true));
|
||||||
|
ActorRef<Actor.Message> RightSubActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
RightSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.right(), false));
|
||||||
|
} else if (expression instanceof Expression.Val val) {
|
||||||
|
if(side == true){
|
||||||
|
oberActor.tell(new LeftIntResponse(val.inner()));
|
||||||
|
}else{
|
||||||
|
oberActor.tell(new RightIntResponse(val.inner()));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Antwort von dem linken Teilkind wird empfangen. Falls von beiden Teilkindern bereits eine Antwort erhalten wurde,
|
||||||
|
//wird eine Sekunde lang gewartet und die Lösung des (Teil-)Ausdrucks berechnet.
|
||||||
|
private Behavior<Message> onLeftIntResponse(LeftIntResponse response){
|
||||||
|
this.leftInt = response.wert;
|
||||||
|
if(this.rightInt != 0){
|
||||||
|
timer.startSingleTimer(new Compute(), Duration.ofSeconds(1));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Antwort von dem rechten Teilkind wird empfangen. Falls von beiden Teilkindern bereits eine Antwort erhalten wurde,
|
||||||
|
//wird eine Sekunde lang gewartet und die Lösung des (Teil-)Ausdrucks berechnet.
|
||||||
|
private Behavior<Message> onRightIntResponse(RightIntResponse response){
|
||||||
|
this.rightInt = response.wert;
|
||||||
|
if(this.leftInt != 0){
|
||||||
|
timer.startSingleTimer(new Compute(), Duration.ofSeconds(1));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Hier wird die Lösung des (Teil-)Ausdrucks berechnet und an den nächsthöheren Actor oder, falls nicht vorhanden,
|
||||||
|
//an PrintAndEvaluate gesendet.
|
||||||
|
private Behavior<Message> onComputeMessage(Compute response) {
|
||||||
|
if (oberActor != null) {
|
||||||
|
//side == true bedeutet, dass dieser Actor das linke Kind ist und es wird LeftResponse geschickt
|
||||||
|
if (side == true) {
|
||||||
|
if (operationString.equals("+")) {
|
||||||
|
oberActor.tell(new LeftIntResponse(leftInt + rightInt));
|
||||||
|
} else if (operationString.equals("-")) {
|
||||||
|
oberActor.tell(new LeftIntResponse(leftInt - rightInt));
|
||||||
|
} else {
|
||||||
|
oberActor.tell(new LeftIntResponse(leftInt * rightInt));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (operationString.equals("+")) {
|
||||||
|
oberActor.tell(new RightIntResponse(leftInt + rightInt));
|
||||||
|
} else if (operationString.equals("-")) {
|
||||||
|
oberActor.tell(new RightIntResponse(leftInt - rightInt));
|
||||||
|
} else {
|
||||||
|
oberActor.tell(new RightIntResponse(leftInt * rightInt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (operationString.equals("+")) {
|
||||||
|
initial.tell(new PrintAndEvaluate.IntResponse(leftInt + rightInt));
|
||||||
|
} else if (operationString.equals("-")) {
|
||||||
|
initial.tell(new PrintAndEvaluate.IntResponse(leftInt - rightInt));
|
||||||
|
} else {
|
||||||
|
initial.tell(new PrintAndEvaluate.IntResponse(leftInt * rightInt));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,12 +26,12 @@ public class AkkaMainSystem extends AbstractBehavior<AkkaMainSystem.Create> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Behavior<Create> onCreate(Create command) {
|
private Behavior<Create> onCreate(Create command) {
|
||||||
//#create-actors
|
|
||||||
Expression expression = Expression.generateExpression(6, 9);
|
Expression expression = Expression.generateExpression(6, 9);
|
||||||
ActorRef<Actor.Message> computer = this.getContext().spawn(Actor.create("Rechner"), "Rechner");
|
//Vergleich mit dem Output der Berechnung zum Testen
|
||||||
computer.tell(new Actor.PrintAndEvaluate(expression));
|
System.out.println("SOLL: "+expression+ " Wert:" +expression.eval() + " Runtime: " + expression.runtime() + " Sekunden");
|
||||||
//Vergleich mit dem Output der Berechnung
|
//#create-actors
|
||||||
System.out.println("SOLL: "+expression+ " Wert:" +expression.eval() + " Runtime: " + expression.runtime());
|
ActorRef<PrintAndEvaluate.Message> computer = this.getContext().spawn(PrintAndEvaluate.create("Rechner"), "rechner");
|
||||||
|
computer.tell(new PrintAndEvaluate.StartMessage(expression));
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,64 @@
|
||||||
|
package com.example;
|
||||||
|
|
||||||
|
import akka.actor.typed.ActorRef;
|
||||||
|
import akka.actor.typed.Behavior;
|
||||||
|
import akka.actor.typed.javadsl.AbstractBehavior;
|
||||||
|
import akka.actor.typed.javadsl.ActorContext;
|
||||||
|
import akka.actor.typed.javadsl.Behaviors;
|
||||||
|
import akka.actor.typed.javadsl.Receive;
|
||||||
|
|
||||||
|
public class PrintAndEvaluate extends AbstractBehavior<PrintAndEvaluate.Message> {
|
||||||
|
|
||||||
|
String name;
|
||||||
|
public interface Message{}
|
||||||
|
|
||||||
|
public record StringResponse(String string) implements Message{}
|
||||||
|
|
||||||
|
public record StartMessage(Expression expression) implements Message{}
|
||||||
|
|
||||||
|
public record IntResponse(int wert) implements Message{}
|
||||||
|
|
||||||
|
private PrintAndEvaluate(ActorContext<PrintAndEvaluate.Message> context, String name){
|
||||||
|
super(context);
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Behavior<PrintAndEvaluate.Message> create(String name){
|
||||||
|
return Behaviors.setup(context -> new PrintAndEvaluate(context, name));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Receive<PrintAndEvaluate.Message> createReceive(){
|
||||||
|
return newReceiveBuilder()
|
||||||
|
.onMessage(StartMessage.class, this::onStartMessage)
|
||||||
|
.onMessage(StringResponse.class, this::onStringResponse)
|
||||||
|
.onMessage(IntResponse.class, this::onIntResponse)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Mit dieser Message wird der PrintAndEvaluate Aktor in Gang gesetzt
|
||||||
|
private Behavior<Message> onStartMessage(StartMessage message){
|
||||||
|
//Starten des Formatierungsvorganges
|
||||||
|
this.getContext().getLog().info("\n Beginn der Ausdrucksformatierung");
|
||||||
|
ActorRef<Actor.Message> printActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
printActor.tell(new Actor.PrintMessage(getContext().getSelf(),message.expression));
|
||||||
|
|
||||||
|
//Starten des Berechnungsvorganges
|
||||||
|
this.getContext().getLog().info("\n Beginn der Berechnung");
|
||||||
|
ActorRef<Actor.Message> computeActor = getContext().spawnAnonymous(Actor.create());
|
||||||
|
computeActor.tell(new Actor.EvaluateMessage(getContext().getSelf(), message.expression));
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ausgeben des Ausdruckes als String
|
||||||
|
private Behavior<Message> onStringResponse(StringResponse response){
|
||||||
|
this.getContext().getLog().info("\n Formatierter Ausdruck: " + response.string);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
//Ausgeben des berechneten Wertes von dem Ausdruck
|
||||||
|
private Behavior<Message> onIntResponse(IntResponse response){
|
||||||
|
this.getContext().getLog().info("\n Ausgerechneter Wert: " + response.wert);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,218 +0,0 @@
|
||||||
package com.example;
|
|
||||||
|
|
||||||
import akka.actor.typed.ActorRef;
|
|
||||||
import akka.actor.typed.Behavior;
|
|
||||||
import akka.actor.typed.javadsl.*;
|
|
||||||
|
|
||||||
import java.time.Duration;
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
public class SubActor extends AbstractBehavior<SubActor.Message> {
|
|
||||||
|
|
||||||
|
|
||||||
//Timer, um bei den Berechnungen eine Sekunde lang zu warten
|
|
||||||
TimerScheduler<Message> timer;
|
|
||||||
|
|
||||||
Expression expression;
|
|
||||||
|
|
||||||
//Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird
|
|
||||||
String operationString;
|
|
||||||
|
|
||||||
//Referenz auf den initialen Actor
|
|
||||||
ActorRef<Actor.Message> initial;
|
|
||||||
|
|
||||||
//Referenz auf den (potenziellen) OberSubActor. Es ist immer entweder initial oder oberActor null.
|
|
||||||
ActorRef<SubActor.Message> oberActor;
|
|
||||||
|
|
||||||
//Linke Seite: true, Rechte Seite: false um zu wissen welche Seite des Ausdrucks berechnet wird.
|
|
||||||
boolean side;
|
|
||||||
|
|
||||||
//Zurückgegebener String & Integer von der linken Seite
|
|
||||||
String leftString;
|
|
||||||
int leftInt;
|
|
||||||
|
|
||||||
//Zurückgegebener String & Integer von der rechten Seite
|
|
||||||
String rightString;
|
|
||||||
int rightInt;
|
|
||||||
|
|
||||||
public interface Message {}
|
|
||||||
|
|
||||||
//Message kommt von dem initialen Actor
|
|
||||||
public record PrintAndEvaluate(ActorRef<Actor.Message> sender,Expression expression, Boolean side) implements Message{ }
|
|
||||||
|
|
||||||
//Message kommt von einem anderen SubActor
|
|
||||||
public record SubPrintAndEvaluate(ActorRef<SubActor.Message> sender,Expression expression, Boolean side) implements Message{ }
|
|
||||||
|
|
||||||
//Antwort von dem linken Kind
|
|
||||||
public record LeftResponse(String string, int wert) implements Message{ }
|
|
||||||
|
|
||||||
//Antwort von dem rechten Kind
|
|
||||||
public record RightResponse(String string, int wert) implements Message{ }
|
|
||||||
|
|
||||||
//Nachricht an sich selbst, um nach einer Sekunde Wartezeit das Ergebnis zu berechnen
|
|
||||||
public record Compute() implements Message{}
|
|
||||||
|
|
||||||
private SubActor(ActorContext<SubActor.Message> context, TimerScheduler<Message> timer){
|
|
||||||
super(context);
|
|
||||||
this.timer = timer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Behavior<SubActor.Message> create(){
|
|
||||||
return Behaviors.setup(context -> Behaviors.withTimers(timers -> new SubActor(context,timers)));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Receive<SubActor.Message> createReceive(){
|
|
||||||
return newReceiveBuilder()
|
|
||||||
.onMessage(PrintAndEvaluate.class, this::onPrintAndEvaluate)
|
|
||||||
.onMessage(SubPrintAndEvaluate.class, this::onSubPrintAndEvaluate)
|
|
||||||
.onMessage(LeftResponse.class, this::onLeftResponse)
|
|
||||||
.onMessage(RightResponse.class, this::onRightResponse)
|
|
||||||
.onMessage(Compute.class, this::onComputeMessage)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
//Die Nachricht von dem initialen Actor wird verarbeitet.
|
|
||||||
//Dabei wird seine Referenz in @initial gespeichert
|
|
||||||
public Behavior<Message> onPrintAndEvaluate(PrintAndEvaluate message) {
|
|
||||||
this.initial = message.sender;
|
|
||||||
this.expression = message.expression;
|
|
||||||
this.side = message.side;
|
|
||||||
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
|
||||||
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
|
||||||
this.operationString = "+";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(), add.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(), add.right(), false));
|
|
||||||
} else if (expression instanceof Expression.Sub sub) {
|
|
||||||
this.operationString = "-";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.right(), false));
|
|
||||||
} else if (expression instanceof Expression.Mul mul) {
|
|
||||||
this.operationString = "*";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.right(), false));
|
|
||||||
} else if (expression instanceof Expression.Val val) {
|
|
||||||
if(side == true){
|
|
||||||
initial.tell(new Actor.LeftResponse(String.valueOf(val.inner()), val.inner()));
|
|
||||||
}else{
|
|
||||||
initial.tell(new Actor.RightResponse(String.valueOf(val.inner()), val.inner()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Nachricht von dem SubActor, von welchem dieser SubActor erstellt wurde, wird verarbeitet.
|
|
||||||
//Dabei wird seine Referenz in oberActor gespeichert.
|
|
||||||
public Behavior<Message> onSubPrintAndEvaluate(SubPrintAndEvaluate message){
|
|
||||||
this.oberActor = message.sender;
|
|
||||||
this.expression = message.expression;
|
|
||||||
this.side = message.side;
|
|
||||||
//Wenn initial nur Val übergeben wird → einfach ausgeben ansonsten UnterActors erstellen
|
|
||||||
if (Objects.requireNonNull(expression) instanceof Expression.Add add) {
|
|
||||||
this.operationString = "+";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),add.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),add.right(), false));
|
|
||||||
}
|
|
||||||
else if (expression instanceof Expression.Sub sub) {
|
|
||||||
this.operationString = "-";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.right(), false));
|
|
||||||
}
|
|
||||||
else if (expression instanceof Expression.Mul mul) {
|
|
||||||
this.operationString = "*";
|
|
||||||
ActorRef<Message> subActorLeft = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.left(), true));
|
|
||||||
ActorRef<Message> subActorRight = getContext().spawnAnonymous(SubActor.create());
|
|
||||||
subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.right(), false));
|
|
||||||
} else if (expression instanceof Expression.Val val) {
|
|
||||||
if(side == true){
|
|
||||||
oberActor.tell(new SubActor.LeftResponse(String.valueOf(val.inner()), val.inner()));
|
|
||||||
}else{
|
|
||||||
oberActor.tell(new SubActor.RightResponse(String.valueOf(val.inner()), val.inner()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Behavior<Message> onLeftResponse(LeftResponse response){
|
|
||||||
this.leftString = response.string;
|
|
||||||
this.leftInt = response.wert;
|
|
||||||
if(this.rightString != null){
|
|
||||||
timer.startSingleTimer(new Compute(), Duration.ofSeconds(1));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Behavior<Message> onRightResponse(RightResponse response){
|
|
||||||
this.rightString = response.string;
|
|
||||||
this.rightInt = response.wert;
|
|
||||||
if(this.leftString != null){
|
|
||||||
timer.startSingleTimer(new Compute(), Duration.ofSeconds(1));
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Behavior<Message> onComputeMessage(Compute response) {
|
|
||||||
if (oberActor != null) {
|
|
||||||
//side == true bedeutet, dass dieser Actor das linke Kind ist und es wird LeftResponse geschickt
|
|
||||||
if (side == true) {
|
|
||||||
if (operationString.equals("+")) {
|
|
||||||
oberActor.tell(new LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt + rightInt));
|
|
||||||
} else if (operationString.equals("-")) {
|
|
||||||
oberActor.tell(new LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt - rightInt));
|
|
||||||
} else {
|
|
||||||
oberActor.tell(new LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt * rightInt));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (operationString.equals("+")) {
|
|
||||||
oberActor.tell(new RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt + rightInt));
|
|
||||||
} else if (operationString.equals("-")) {
|
|
||||||
oberActor.tell(new RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt - rightInt));
|
|
||||||
} else {
|
|
||||||
oberActor.tell(new RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt * rightInt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (side == true) {
|
|
||||||
if (operationString.equals("+")) {
|
|
||||||
initial.tell(new Actor.LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt + rightInt));
|
|
||||||
} else if (operationString.equals("-")) {
|
|
||||||
initial.tell(new Actor.LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt - rightInt));
|
|
||||||
} else {
|
|
||||||
initial.tell(new Actor.LeftResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt * rightInt));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (operationString.equals("+")) {
|
|
||||||
initial.tell(new Actor.RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt + rightInt));
|
|
||||||
} else if (operationString.equals("-")) {
|
|
||||||
initial.tell(new Actor.RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt - rightInt));
|
|
||||||
} else {
|
|
||||||
initial.tell(new Actor.RightResponse("(" + leftString + operationString + rightString + ")",
|
|
||||||
leftInt * rightInt));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue