From 028dd290e6c79b9f15b75023e5d37be701607434 Mon Sep 17 00:00:00 2001 From: Egor Rutkowski Date: Tue, 2 Jul 2024 21:26:20 +0200 Subject: [PATCH] Print und Evaluate aufgeteilt (Das war schmerzhaft). V1.0 --- src/main/java/com/example/Actor.java | 304 +++++++++++++++--- src/main/java/com/example/AkkaMainSystem.java | 11 +- .../java/com/example/PrintAndEvaluate.java | 64 ++++ src/main/java/com/example/SubActor.java | 257 --------------- 4 files changed, 320 insertions(+), 316 deletions(-) create mode 100644 src/main/java/com/example/PrintAndEvaluate.java delete mode 100644 src/main/java/com/example/SubActor.java diff --git a/src/main/java/com/example/Actor.java b/src/main/java/com/example/Actor.java index 7bc9c78..274ab92 100644 --- a/src/main/java/com/example/Actor.java +++ b/src/main/java/com/example/Actor.java @@ -2,16 +2,31 @@ 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; +import akka.actor.typed.javadsl.*; +import java.time.Duration; import java.util.Objects; -import java.util.logging.Logger; public class Actor extends AbstractBehavior { - //TODO: Wartezeit bei der Operation + + + //Timer, um bei den Berechnungen eine Sekunde lang zu warten + TimerScheduler timer; + + Expression expression; + + //Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird + String operationString; + + //Referenz auf den initialen Actor + ActorRef initial; + + //Referenz auf den (potenziellen) OberSubActor. Es ist immer entweder initial oder oberActor null. + ActorRef 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 String leftString; int leftInt; @@ -20,95 +35,278 @@ public class Actor extends AbstractBehavior { String rightString; int rightInt; - //Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird - String operationString; + public interface Message {} - String name; - Expression expression; - public interface Message{} + //Message kommt von dem initialen Actor + public record PrintMessage(ActorRef sender, Expression expression) implements Message{} + public record SubPrintMessage(ActorRef sender, Expression expression, boolean side) implements Message{} - public record PrintAndEvaluate(Expression expression) implements Message{} + //Message kommt von einem Actor + public record EvaluateMessage(ActorRef sender, Expression expression) implements Message{} + public record SubEvaluateMessage(ActorRef sender, Expression expression, boolean side) implements Message{} //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 - 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 context, String name){ + //Nachricht an sich selbst, um nach einer Sekunde Wartezeit das Ergebnis zu berechnen + public record Compute() implements Message{} + + private Actor(ActorContext context, TimerScheduler timer){ super(context); - this.name = name; + this.timer = timer; } - public static Behavior create(String name){ - return Behaviors.setup(context -> new Actor(context, name)); + public static Behavior create(){ + return Behaviors.setup(context -> Behaviors.withTimers(timers -> new Actor(context,timers))); } @Override public Receive createReceive(){ return newReceiveBuilder() - .onMessage(PrintAndEvaluate.class, this::onPrintAndEvaluate) - .onMessage(LeftResponse.class, this::onLeftResponse) - .onMessage(RightResponse.class, this::onRightResponse) + .onMessage(PrintMessage.class, this::onPrintMessage) + .onMessage(SubPrintMessage.class, this::onSubPrintMessage) + .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) .build(); } - private Behavior 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 onPrintMessage(PrintMessage 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 LeftSubActor = getContext().spawnAnonymous(SubActor.create()); - LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),add.left(), true)); - ActorRef RightSubActor = getContext().spawnAnonymous(SubActor.create()); - RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),add.right(), false)); + ActorRef LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),add.left(), true)); + ActorRef RightSubActor = getContext().spawnAnonymous(Actor.create()); + RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),add.right(), false)); } else if (expression instanceof Expression.Sub sub) { this.operationString = "-"; - ActorRef LeftSubActor = getContext().spawnAnonymous(SubActor.create()); - LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),sub.left(), true)); - ActorRef RightSubActor = getContext().spawnAnonymous(SubActor.create()); - RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),sub.right(), false)); + ActorRef LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),sub.left(), true)); + ActorRef RightSubActor = getContext().spawnAnonymous(Actor.create()); + RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),sub.right(), false)); } else if (expression instanceof Expression.Mul mul) { this.operationString = "*"; - ActorRef LeftSubActor = getContext().spawnAnonymous(SubActor.create()); - LeftSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),mul.left(), true)); - ActorRef RightSubActor = getContext().spawnAnonymous(SubActor.create()); - RightSubActor.tell(new SubActor.PrintAndEvaluate(getContext().getSelf(),mul.right(), false)); + ActorRef LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),mul.left(), true)); + ActorRef RightSubActor = getContext().spawnAnonymous(Actor.create()); + RightSubActor.tell(new Actor.SubPrintMessage(getContext().getSelf(),mul.right(), false)); } else if (expression instanceof Expression.Val val) { - logger.info(val.inner() + ""); + initial.tell(new PrintAndEvaluate.StringResponse(String.valueOf(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 Formatierungsvorgang + private Behavior onSubPrintMessage(SubPrintMessage 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 subActorLeft = getContext().spawnAnonymous(Actor.create()); + subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),add.left(), true)); + ActorRef subActorRight = getContext().spawnAnonymous(Actor.create()); + subActorRight.tell(new SubPrintMessage(getContext().getSelf(),add.right(), false)); + } + else if (expression instanceof Expression.Sub sub) { + this.operationString = "-"; + ActorRef subActorLeft = getContext().spawnAnonymous(Actor.create()); + subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),sub.left(), true)); + ActorRef subActorRight = getContext().spawnAnonymous(Actor.create()); + subActorRight.tell(new SubPrintMessage(getContext().getSelf(),sub.right(), false)); + } + else if (expression instanceof Expression.Mul mul) { + this.operationString = "*"; + ActorRef subActorLeft = getContext().spawnAnonymous(Actor.create()); + subActorLeft.tell(new SubPrintMessage(getContext().getSelf(),mul.left(), true)); + ActorRef subActorRight = getContext().spawnAnonymous(Actor.create()); + subActorRight.tell(new SubPrintMessage(getContext().getSelf(),mul.right(), false)); + } else if (expression instanceof Expression.Val val) { + if(side == true){ + oberActor.tell(new Actor.LeftStringResponse(String.valueOf(val.inner()))); + }else{ + oberActor.tell(new Actor.RightStringResponse(String.valueOf(val.inner()))); + } } return this; } - Logger logger = Logger.getLogger(Actor.class.getName()); - private Behavior onLeftResponse(LeftResponse response){ + //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 onLeftStringResponse(LeftStringResponse response){ this.leftString = response.string; - this.leftInt = response.wert; if(this.rightString != null){ - if(operationString.equals("+")){ - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt + rightInt)); - } else if (operationString.equals("-")) { - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt - rightInt)); - }else{ - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt * rightInt)); + 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 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; } - private Behavior onRightResponse(RightResponse response){ - this.rightString = response.string; - this.rightInt = response.wert; - if(this.leftString != null){ - if(operationString.equals("+")){ - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt + rightInt)); - } else if (operationString.equals("-")) { - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt - rightInt)); + //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 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.left(), true)); + ActorRef 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.left(), true)); + ActorRef 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.left(), true)); + ActorRef 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 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),add.left(), true)); + ActorRef 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),sub.left(), true)); + ActorRef 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 LeftSubActor = getContext().spawnAnonymous(Actor.create()); + LeftSubActor.tell(new Actor.SubEvaluateMessage(getContext().getSelf(),mul.left(), true)); + ActorRef 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{ - logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt * rightInt)); + 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 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 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 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; } diff --git a/src/main/java/com/example/AkkaMainSystem.java b/src/main/java/com/example/AkkaMainSystem.java index e9dd534..90c7716 100644 --- a/src/main/java/com/example/AkkaMainSystem.java +++ b/src/main/java/com/example/AkkaMainSystem.java @@ -26,13 +26,12 @@ public class AkkaMainSystem extends AbstractBehavior { } private Behavior onCreate(Create command) { - //#create-actors Expression expression = Expression.generateExpression(6, 9); - Expression testExp = Expression.generateExpression(4,9); - ActorRef computer = this.getContext().spawn(Actor.create("Rechner"), "Rechner"); - computer.tell(new Actor.PrintAndEvaluate(testExp)); - //Vergleich mit dem Output der Berechnung - System.out.println("SOLL: "+testExp.toString()+ " Wert:" +testExp.eval() + " Runtime: " + testExp.runtime()); + //Vergleich mit dem Output der Berechnung zum Testen + System.out.println("SOLL: "+expression+ " Wert:" +expression.eval() + " Runtime: " + expression.runtime() + " Sekunden"); + //#create-actors + ActorRef computer = this.getContext().spawn(PrintAndEvaluate.create("Rechner"), "rechner"); + computer.tell(new PrintAndEvaluate.StartMessage(expression)); return this; } } diff --git a/src/main/java/com/example/PrintAndEvaluate.java b/src/main/java/com/example/PrintAndEvaluate.java new file mode 100644 index 0000000..bab2a20 --- /dev/null +++ b/src/main/java/com/example/PrintAndEvaluate.java @@ -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 { + + 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 context, String name){ + super(context); + this.name = name; + } + + public static Behavior create(String name){ + return Behaviors.setup(context -> new PrintAndEvaluate(context, name)); + } + + @Override + public Receive 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 onStartMessage(StartMessage message){ + //Starten des Formatierungsvorganges + this.getContext().getLog().info("\n Beginn der Ausdrucksformatierung"); + ActorRef 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 computeActor = getContext().spawnAnonymous(Actor.create()); + computeActor.tell(new Actor.EvaluateMessage(getContext().getSelf(), message.expression)); + return this; + } + + //Ausgeben des Ausdruckes als String + private Behavior onStringResponse(StringResponse response){ + this.getContext().getLog().info("\n Formatierter Ausdruck: " + response.string); + return this; + } + + //Ausgeben des berechneten Wertes von dem Ausdruck + private Behavior onIntResponse(IntResponse response){ + this.getContext().getLog().info("\n Ausgerechneter Wert: " + response.wert); + return this; + } +} diff --git a/src/main/java/com/example/SubActor.java b/src/main/java/com/example/SubActor.java deleted file mode 100644 index e6169d7..0000000 --- a/src/main/java/com/example/SubActor.java +++ /dev/null @@ -1,257 +0,0 @@ -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; - -import java.util.Objects; - -public class SubActor extends AbstractBehavior { - //TODO: Wartezeit bei den Operationen - Expression expression; - - //Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird - String operationString; - - //Referenz auf den initialen Actor - ActorRef initial; - - //Referenz auf den (potenziellen) OberSubActor. Es ist immer entweder initial oder oberActor null. - ActorRef 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 sender,Expression expression, Boolean side) implements Message{ } - - //Message kommt von einem anderen SubActor - public record SubPrintAndEvaluate(ActorRef 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{ } - - private SubActor(ActorContext context){ - super(context); - } - - public static Behavior create(){ - return Behaviors.setup(context -> new SubActor(context)); - } - - @Override - public Receive createReceive(){ - return newReceiveBuilder() - .onMessage(PrintAndEvaluate.class, this::onPrintAndEvaluate) - .onMessage(SubPrintAndEvaluate.class, this::onSubPrintAndEvaluate) - .onMessage(LeftResponse.class, this::onLeftResponse) - .onMessage(RightResponse.class, this::onRightResponse) - .build(); - } - - //Die Nachricht von dem initialen Actor wird verarbeitet. - //Dabei wird seine Referenz in @initial gespeichert - public Behavior 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 subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(), add.left(), true)); - ActorRef subActorRight = getContext().spawnAnonymous(SubActor.create()); - subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(), add.right(), false)); - } else if (expression instanceof Expression.Sub sub) { - this.operationString = "-"; - ActorRef subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.left(), true)); - ActorRef subActorRight = getContext().spawnAnonymous(SubActor.create()); - subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.right(), false)); - } else if (expression instanceof Expression.Mul mul) { - this.operationString = "*"; - ActorRef subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.left(), true)); - ActorRef 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 einem SubActor wird verarbeitet. - //Dabei wird seine Referenz in oberActor gespeichert. - public Behavior 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 subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),add.left(), true)); - ActorRef subActorRight = getContext().spawnAnonymous(SubActor.create()); - subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),add.right(), false)); - } - else if (expression instanceof Expression.Sub sub) { - this.operationString = "-"; - ActorRef subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.left(), true)); - ActorRef subActorRight = getContext().spawnAnonymous(SubActor.create()); - subActorRight.tell(new SubPrintAndEvaluate(getContext().getSelf(),sub.right(), false)); - } - else if (expression instanceof Expression.Mul mul) { - this.operationString = "*"; - ActorRef subActorLeft = getContext().spawnAnonymous(SubActor.create()); - subActorLeft.tell(new SubPrintAndEvaluate(getContext().getSelf(),mul.left(), true)); - ActorRef 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 onLeftResponse(LeftResponse response){ - this.leftString = response.string; - this.leftInt = response.wert; - if(this.rightString != null){ - 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; - } - - public Behavior onRightResponse(RightResponse response){ - this.rightString = response.string; - this.rightInt = response.wert; - if(this.leftString != null){ - 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; - } - -}