bdi4jade

Details

diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
index be0f6ef..ea6acd7 100644
--- a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingCapability.java
@@ -22,9 +22,11 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 	private static final long serialVersionUID = -5556551069331273755L;
 
 	private final Map<Goal, GoalAchievementMetadata> gams;
+	private final Map<Goal, Goal> parentGoals;
 
 	public RevertingCapability() {
 		this.gams = new HashMap<>();
+		this.parentGoals = new HashMap<>();
 		setOptionGenerationFunction(new RevertingOptionGenerationFunction(this));
 		this.getMyAgent().addGoalListener(this);
 		this.getBeliefBase().addBeliefListener(this);
@@ -34,6 +36,10 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 		this.gams.put(goal, gam);
 	}
 
+	public void addParentGoal(Goal goal, Goal parent) {
+		this.parentGoals.put(goal, parent);
+	}
+
 	public GoalAchievementMetadata createGoalAchievementMetadata(Goal goal, List<Predicate> reversionTrigger,
 			Boolean rollback, Integer maxExecutedPlans, Integer maxTime) {
 		GoalAchievementMetadata gam = new GoalAchievementMetadata((PredicateGoal<?>) goal, reversionTrigger, rollback,
@@ -48,20 +54,44 @@ public class RevertingCapability extends Capability implements BeliefListener, G
 			Object args = beliefEvent.getArgs();
 			if (args instanceof PredicateGoal<?>) {
 				PredicateGoal<?> goal = (PredicateGoal<?>) args;
+				// TODO Here, get the oldest reversible parent.
 				if (beliefEvent.getBelief() instanceof PredicateBelief<?>) {
 					PredicateBelief<?> belief = (PredicateBelief<?>) beliefEvent.getBelief();
-					if (this.gams.containsKey(goal)) {
-						this.gams.get(goal).trackBeliefChange((Predicate) belief.getName(), belief.getValue());
+					Goal oldestParent = getOldestReversibleParent(goal);
+					if (oldestParent != null) {
+						this.gams.get(oldestParent).trackBeliefChange((Predicate) belief.getName(), belief.getValue());
 					}
 				}
 			}
 		}
 	}
 
+	private Goal getOldestReversibleParent(Goal goal) {
+		Goal parent = null;
+		Goal aux = goal;
+
+		if (this.gams.containsKey(goal)) {
+			parent = goal;
+		}
+
+		while (this.parentGoals.containsKey(aux)) {
+			aux = this.parentGoals.get(aux);
+			if (this.gams.containsKey(aux)) {
+				parent = this.parentGoals.get(aux);
+			}
+		}
+
+		return parent;
+	}
+
 	public Map<Goal, GoalAchievementMetadata> getGoalAchievementMetadata() {
 		return gams;
 	}
 
+	public Map<Goal, Goal> getParentGoals() {
+		return parentGoals;
+	}
+
 	@Override
 	public void goalPerformed(GoalEvent event) {
 		for (GoalAchievementMetadata gam : gams.values()) {
diff --git a/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingPlanBody.java b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingPlanBody.java
new file mode 100644
index 0000000..10bd48a
--- /dev/null
+++ b/bdi-jade-extensions/src/bdi4jade/extension/undo/RevertingPlanBody.java
@@ -0,0 +1,29 @@
+package bdi4jade.extension.undo;
+
+import bdi4jade.goal.Goal;
+import bdi4jade.plan.planbody.BeliefGoalPlanBody;
+
+public abstract class RevertingPlanBody extends BeliefGoalPlanBody {
+
+	private static final long serialVersionUID = -678344739581158097L;
+
+	@Override
+	public boolean dispatchSubgoal(Goal subgoal) {
+		setParentGoal(subgoal);
+		return super.dispatchSubgoal(subgoal);
+	}
+
+	@Override
+	public boolean dispatchSubgoalAndListen(Goal subgoal) {
+		setParentGoal(subgoal);
+		return super.dispatchSubgoalAndListen(subgoal);
+	}
+
+	private void setParentGoal(Goal subgoal) {
+		if (this.getCapability() instanceof RevertingCapability) {
+			RevertingCapability capability = (RevertingCapability) this.getCapability();
+			capability.addParentGoal(subgoal, this.getGoal());
+		}
+	}
+
+}