From 367456a546b356eda5625dd0c59ce1ae3cf27970 Mon Sep 17 00:00:00 2001
From: Manuel Krombholz <s3866577@msx.tu-dresden.de>
Date: Mon, 15 Feb 2021 21:13:25 +0100
Subject: [PATCH] Added state transfer and sync as Rule

---
 eraser-base/src/main/jastadd/Item.jrag        | 72 +++++++++++++++----
 eraser-base/src/main/jastadd/Rules.jrag       |  7 ++
 .../inf/st/eraser/ControllingItemTest.java    | 13 ++++
 3 files changed, 79 insertions(+), 13 deletions(-)

diff --git a/eraser-base/src/main/jastadd/Item.jrag b/eraser-base/src/main/jastadd/Item.jrag
index 6ccdfb49..5c03824f 100644
--- a/eraser-base/src/main/jastadd/Item.jrag
+++ b/eraser-base/src/main/jastadd/Item.jrag
@@ -397,25 +397,71 @@ aspect ItemHandling {
     addControlling(item);
   }
 
-
-  
   private Rule Item.createControllerRule(Item controllerItem, Item controlledItem) {
-    Rule rule = new Rule();
+        Rule rule = new Rule();
+
+        ItemStateChangeCondition condition = new ItemStateChangeCondition();
+        condition.setItem(controllerItem);
+        rule.addCondition(condition);
 
-    ItemStateChangeCondition condition = new ItemStateChangeCondition();
-    condition.setItem(controllerItem);
-    rule.addCondition(condition);
+        SetStateFromTriggeringItemAction action = new SetStateFromTriggeringItemAction();
+        action.setAffectedItem(controlledItem);
+        rule.addAction(action);
+        rule.activateFor(controllerItem);
+
+        return rule;
 
-    SetStateFromTriggeringItemAction action = new SetStateFromTriggeringItemAction();
-    action.setAffectedItem(controlledItem);
-    rule.addAction(action);
-    rule.activateFor(controllerItem);
-    
-    return rule;
-    
   }
+
+  public void Item.removeControlling(Item controlledItem) {
+    JastAddList<Rule> rules = getRoot().getRules();
+    HashMap<Rule, Item> removeMap = new HashMap<Rule, Item>();
+    for (Rule rule : rules) {
+      // check if rule has one ItemStateChangeCondition with controllerItem
+      int size = 0;
+      Condition lastCondition = null;
+      for (Condition condition : rule.getConditions()) {
+        size++;
+        lastCondition = condition;
+      }
+
+      // check condition pattern
+      if (size!=1)
+        continue;
+      if (!(lastCondition instanceof ItemStateChangeCondition))
+        continue;
+      Item controlling = ((ItemStateChangeCondition) lastCondition).getItem();
+
+      // check if action has one SetStateFromTriggeringItemAction
+      size = 0;
+      Action lastAction = null;
+      for (Action action : rule.getActions()) {
+        size++;
+        lastAction = action;
+      }
+
+      // check action pattern
+      if (size!=1)
+        continue;
+      if (!(lastAction instanceof SetStateFromTriggeringItemAction))
+        continue;
+      if (((SetStateFromTriggeringItemAction)lastAction).getAffectedItem() != controlledItem)
+        continue;
+
+        removeMap.put(rule,controlling);
+    }
+    for (Rule rule : removeMap.keySet()) {
+      rule.deactivateFor(removeMap.get(rule));
+      int idx = rules.getIndexOfChild(rule);
+      rules.removeChild(idx);
+    }
+
+  }
+
   
 
+
+
   //--- copyStateTo ---
   protected abstract void Item.copyStateTo(Item stateReceiver);
   protected void ItemWithBooleanState.copyStateTo(Item stateReceiver) {
diff --git a/eraser-base/src/main/jastadd/Rules.jrag b/eraser-base/src/main/jastadd/Rules.jrag
index 464b3d3d..26c18ae2 100644
--- a/eraser-base/src/main/jastadd/Rules.jrag
+++ b/eraser-base/src/main/jastadd/Rules.jrag
@@ -43,6 +43,13 @@ aspect Rules {
     itemObserver.addTriggeredRule(this);
   }
 
+  public void Rule.deactivateFor(Item item) {
+    if (item.hasItemObserver()) {
+        item.getItemObserver().removeTriggeredRule(this);
+    }
+
+  }
+
   private static java.util.concurrent.ScheduledExecutorService Rule.executor = java.util.concurrent.Executors.newScheduledThreadPool(4);
 
   /**
diff --git a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java
index 289ee0ec..e9ebe848 100644
--- a/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java
+++ b/eraser-base/src/test/java/de/tudresden/inf/st/eraser/ControllingItemTest.java
@@ -32,6 +32,19 @@ public class ControllingItemTest {
     assertEquals(5, item1.getState(), DELTA);
     assertEquals(5, item2.getState(), DELTA, "Item was not controlled correctly");
   }
+  @Test
+  public void testRemoveControlling() {
+    ModelAndItem mai = TestUtils.createModelAndItem(0, true);
+    NumberItem controlledItem = mai.item;
+    NumberItem controllingItem = TestUtils.addItemTo(mai.model, 4, true);
+    controllingItem.addControlling(controlledItem);
+    controllingItem.removeControlling(controlledItem);
+
+    controllingItem.setState(8);
+
+    assertEquals(8, controllingItem.getState(), DELTA);
+    assertEquals(0, controlledItem.getState(), DELTA, "Item was still controlled although the controlling was removed");
+  }
 
   @Test
   public void testOneToManyNumber() {
-- 
GitLab