diff --git a/src/main/java/com/example/Actor.java b/src/main/java/com/example/Actor.java new file mode 100644 index 0000000..d0e55de --- /dev/null +++ b/src/main/java/com/example/Actor.java @@ -0,0 +1,127 @@ +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 { + + //Timer für die Berechnung + final TimerScheduler timer; + //Zurückgegebener String & Integer von der linken Seite + String leftString; + int leftInt; + + //Zurückgegebener String & Integer von der rechten Seite + String rightString; + int rightInt; + + //Zeichen für die Operation (Add, Sub, Mul) welche benutzt wird + String operationString; + + String name; + Expression expression; + public interface Message{} + + public record Compute() implements Message{} + + public record PrintAndEvaluate(Expression expression) 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 Actor(ActorContext context, String name, TimerScheduler timer){ + super(context); + this.name = name; + this.timer = timer; + } + + public static Behavior create(String name){ + return Behaviors.setup(context -> Behaviors.withTimers(timers -> new Actor(context, name, timers))); + } + + @Override + public Receive createReceive(){ + return newReceiveBuilder() + .onMessage(PrintAndEvaluate.class, this::onPrintAndEvaluate) + .onMessage(LeftResponse.class, this::onLeftResponse) + .onMessage(RightResponse.class, this::onRightResponse) + .onMessage(Compute.class, this::onComputeMessage) + .build(); + } + + private Behavior onPrintAndEvaluate(PrintAndEvaluate message){ + 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)); + } + 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)); + } + 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)); + } else if (expression instanceof Expression.Val val) { + logger.info(val.inner() + ""); + } + return this; + } + + Logger logger = Logger.getLogger(Actor.class.getName()); + + //Antwort von dem rechten Kind. Wenn beide Seiten geantwortet haben, wird eine Sekunde gewartet und dann das Ergebnis + //berechnet in Compute() + private Behavior onLeftResponse(LeftResponse response){ + this.leftString = response.string; + this.leftInt = response.wert; + if(this.rightString != null){ + this.timer.startSingleTimer(new Compute(),Duration.ofSeconds(1)); + } + return this; + } + + //Antwort von dem rechten Kind. Wenn beide Seiten geantwortet haben, wird eine Sekunde gewartet und dann das Ergebnis + //berechnet in Compute() + private Behavior onRightResponse(RightResponse response){ + this.rightString = response.string; + this.rightInt = response.wert; + if(this.leftString != null){ + this.timer.startSingleTimer(new Compute(),Duration.ofSeconds(1)); + } + return this; + } + + private Behavior 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{ + logger.info("(" + leftString + operationString + rightString + ") Wert: " + (leftInt * rightInt)); + } + return this; + } +}