Skip to content
This repository has been archived by the owner on Jan 13, 2025. It is now read-only.

Commit

Permalink
reset rules when a higher priority rule triggers. allow the finished …
Browse files Browse the repository at this point in the history
…action for a rule to bump the newly action for that rule.
  • Loading branch information
dejabot committed Oct 7, 2024
1 parent 5957272 commit 11efd71
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 3 deletions.
4 changes: 4 additions & 0 deletions src/main/java/com/team766/framework3/Rule.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ public String getName() {
return currentTriggerType;
}

/* package */ void reset() {
currentTriggerType = TriggerType.NONE;
}

/* package */ void evaluate() {
if (predicate.getAsBoolean()) {
currentTriggerType =
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/com/team766/framework3/RuleEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ public final void run() {
+ "; mechanism "
+ mechanism.getName()
+ " already reserved by higher priority rule.");
rule.reset();
continue ruleLoop;
}
// see if a previously triggered rule is still using the mechanism
Expand All @@ -123,11 +124,24 @@ public final void run() {
log(
Severity.INFO,
"RULE CONFLICT! Ignoring rule: "
+ rule
+ rule.getName()
+ "; mechanism "
+ mechanism.getName()
+ " already being used in CommandScheduler by higher priority rule.");
rule.reset();
continue ruleLoop;
} else if (rule != existingRule) {
// new rule takes priority
// reset existing rule
log(
Severity.INFO,
"Pre-empting rule: "
+ existingRule.getName()
+ "; mechanism "
+ mechanism.getName()
+ " will now be reserved by higher priority rule "
+ rule.getName());
existingRule.reset();
}
}
}
Expand Down
172 changes: 170 additions & 2 deletions src/test/java/com/team766/framework3/RuleEngineTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,45 @@ public void testRunNonConflictingRules() {
step(); // 3
}

@Test
public void testFinishedProcedureBumpsNewlyProcedureForSameRule() {
RuleEngine myRules =
new RuleEngine() {
{
addRule(
Rule.create("fm1_p0", new PeriodicPredicate(4))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p0", 2, Set.of(fm1)))
.withFinishedTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procfin_p0",
1,
Set.of(fm1, fm2))));
}
};

myRules.run();

// check that the expected Procedure is scheduled
Command cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procnew_p0"));

step(); // 0

// next iteration - check that the original procedure is new bumped by the finished procedure for the same rule
myRules.run();

cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procfin_p0"));

step(); // 1
}

@Test
public void testRunRulePriorities() {
// create simple RuleEngine with two rules with conflicting actions
Expand Down Expand Up @@ -189,7 +228,6 @@ public void testRunRulePriorities() {

@Test
public void testRunHigherPriorityRuleStillBeingRun() {
// create a simple RuleEngine with two non-conflicting rules
RuleEngine myRules =
new RuleEngine() {
{
Expand Down Expand Up @@ -261,7 +299,6 @@ public void testRunHigherPriorityRuleStillBeingRun() {

@Test
public void testRunLowerPriorityRuleBumped() {
// create a simple RuleEngine with two non-conflicting rules
RuleEngine myRules =
new RuleEngine() {
{
Expand Down Expand Up @@ -301,4 +338,135 @@ public void testRunLowerPriorityRuleBumped() {

step(); // 1
}

@Test
public void testRuleResetIgnoredLowerPriorityRule() {
RuleEngine myRules =
new RuleEngine() {
{
addRule(
Rule.create("fm1_p0", new PeriodicPredicate(4))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p0", 2, Set.of(fm1))));
addRule(
Rule.create("fm1_p1", new PeriodicPredicate(4))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p1", 1, Set.of(fm1)))
.withFinishedTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procfin_p1", 1, Set.of(fm2))));
}
};

myRules.run();

// check that the expected Procedure is scheduled
Command cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procnew_p0"));

step(); // 0

myRules.run();

cmd = CommandScheduler.getInstance().requiring(fm2);
assertNull(cmd);

step();
}

@Test
public void testRuleResetIgnoredLowerPriorityRuleHigherPriorityRulePreviouslyScheduled() {
RuleEngine myRules =
new RuleEngine() {
{
addRule(
Rule.create("fm1_p0", new PeriodicPredicate(4))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p0", 2, Set.of(fm1))));
addRule(
Rule.create("fm1_p1", new PeriodicPredicate(4, 1))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p1", 1, Set.of(fm1)))
.withFinishedTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procfin_p1", 1, Set.of(fm2))));
}
};

myRules.run();

// check that the expected Procedure is scheduled
Command cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procnew_p0"));

step(); // 0

// next iteration - even with the second rule firing, the procedure from the first rule
// should continue
// executing, since the first rule is higher priority
myRules.run();
cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procnew_p0"));
step(); // 1

// next iteration - the second rule's finished procedure should *not* execute
myRules.run();
cmd = CommandScheduler.getInstance().requiring(fm2);
assertNull(cmd);
step(); // 2
}

@Test
public void testRuleResetBumpedLowerPriorityRule() {
RuleEngine myRules =
new RuleEngine() {
{
addRule(
Rule.create("fm1_p0", new PeriodicPredicate(4, 1))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p0", 2, Set.of(fm1))));
addRule(
Rule.create("fm1_p1", new PeriodicPredicate(4))
.withNewlyTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procnew_p1", 2, Set.of(fm1)))
.withFinishedTriggeringProcedure(
() ->
new FakeProcedure(
"fm1procfin_p1", 2, Set.of(fm2))));
}
};

myRules.run();

// check that the expected Procedure is scheduled
Command cmd = CommandScheduler.getInstance().requiring(fm1);
assertNotNull(cmd);
assertTrue(cmd.getName().endsWith("fm1procnew_p1"));

step(); // 0

myRules.run();

cmd = CommandScheduler.getInstance().requiring(fm2);
assertNull(cmd);

step();
}
}

0 comments on commit 11efd71

Please sign in to comment.