Skip to content

Commit

Permalink
Added LinkedAction and tests
Browse files Browse the repository at this point in the history
  • Loading branch information
retrodaredevil committed Jan 26, 2019
1 parent f3045d6 commit f165013
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 1 deletion.
22 changes: 22 additions & 0 deletions src/main/java/me/retrodaredevil/action/Actions.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,28 @@ public static ActionChooser createActionChooser(WhenDone whenDone){
public static ActionChooser createActionChooserRecyclable(WhenDone whenDone){
return new DefaultActionChooser(true, whenDone);
}

// region Linked Actions

/**
* @param action The action to run while the returned action is running
* @param nextAction The next action
* @return A LinkedAction that runs the passed action that will have nextAction as its next action.
*/
public static LinkedAction createLinkedAction(Action action, Action nextAction){
return new LinkedActionWrapper(action, nextAction);
}

/**
* Creates an {@link Action} that will update the passed action. When the action is done, if it is a {@link LinkedAction},
* it will be replaced by the {@link Action} from {@link LinkedAction#getNextAction()}
* @param action The action or linked action to update
* @return An {@link Action} that will update the passed action. Cannot be recycled
*/
public static Action createLinkedActionRunner(Action action, WhenDone whenDone, boolean immediatelyDoNextWhenDone){
return new LinkedActionRunner(whenDone, immediatelyDoNextWhenDone, action);
}
// endregion


static abstract class Builder<T extends Builder> {
Expand Down
5 changes: 5 additions & 0 deletions src/main/java/me/retrodaredevil/action/LinkedAction.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.retrodaredevil.action;

public interface LinkedAction extends Action {
Action getNextAction();
}
83 changes: 83 additions & 0 deletions src/main/java/me/retrodaredevil/action/LinkedActionRunner.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package me.retrodaredevil.action;

import java.util.Collection;
import java.util.Collections;

class LinkedActionRunner extends SimpleAction implements SingleActiveActionHolder {

private Action action;
private final WhenDone whenDone;
private final boolean immediatelyDoNextWhenDone;

public LinkedActionRunner(WhenDone whenDone, boolean immediatelyDoNextWhenDone, Action action) {
super(false);
this.action = action;
this.whenDone = whenDone;
this.immediatelyDoNextWhenDone = immediatelyDoNextWhenDone;
}

@Override
public Action getActiveAction() {
return action;
}

@Override
public Collection<? extends Action> getActiveActions() {
final Action action = this.action;
if(action == null){
return Collections.emptySet();
}
return Collections.singleton(action);
}

@Override
protected void onUpdate() {
super.onUpdate();
updateAction();
}
private void updateAction(){
boolean done = false;
if(action != null){
action.update();
if(action.isDone()){
final Action nextAction;
if(action instanceof LinkedAction){
nextAction = ((LinkedAction) action).getNextAction();
} else {
nextAction = null;
}
if(nextAction == null){
if(whenDone.isClearActiveWhenActiveDone()){
endCurrent();
}
done = true;
} else {
action.end();
action = nextAction;
if(immediatelyDoNextWhenDone){
updateAction();
}
}
}
} else {
done = true;
}
if(whenDone.isBeDoneWhenActiveDone()) {
setDone(done);
} else {
setDone(false);
}
}

@Override
protected void onEnd(boolean peacefullyEnded) {
super.onEnd(peacefullyEnded);
endCurrent();
}
private void endCurrent(){
if(action != null && action.isActive()){
action.end();
action = null;
}
}
}
42 changes: 42 additions & 0 deletions src/main/java/me/retrodaredevil/action/LinkedActionWrapper.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package me.retrodaredevil.action;

import java.util.Objects;

class LinkedActionWrapper implements LinkedAction {

private final Action action;
private final Action nextAction;

LinkedActionWrapper(Action action, Action nextAction) {
this.action = Objects.requireNonNull(action);
this.nextAction = nextAction;
if(action.isActive()){
throw new IllegalArgumentException("action cannot be active!");
}
}

@Override
public Action getNextAction() {
return nextAction;
}

@Override
public void update() {
action.update();
}

@Override
public void end() {
action.end();
}

@Override
public boolean isDone() {
return action.isDone();
}

@Override
public boolean isActive() {
return action.isActive();
}
}
2 changes: 1 addition & 1 deletion src/main/java/me/retrodaredevil/action/WhenDone.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Can be used with the factory methods {@link Actions#createActionChooser(WhenDone)} and {@link Actions#createActionChooserRecyclable(WhenDone)}
*/
public enum WhenDone {
/** When the active action is done, this will keep going like nothing happened*/
/** When the active action is done, this will keep going like nothing happened. NOT RECOMMENDED*/
DO_NOTHING(false, false),

/** When the active action is done, it will be ended and cleared*/
Expand Down
48 changes: 48 additions & 0 deletions src/test/java/me/retrodaredevil/action/test/LinkedActionTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package me.retrodaredevil.action.test;

import me.retrodaredevil.action.*;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

final class LinkedActionTest {
@Test
void testLinkedActionRunner(){
final int[] value = {0};
final Action set1 = Actions.createRunOnce(() -> value[0] = 1);
final Action set2 = Actions.createRunOnce(() -> value[0] = 2);
final Action set3 = Actions.createRunOnce(() -> value[0] = 3);

final Action runner = Actions.createLinkedActionRunner(
Actions.createLinkedAction(set1, Actions.createLinkedAction(set2, set3)),
WhenDone.CLEAR_ACTIVE_AND_BE_DONE,
false
);

assertEquals(0, value[0]);
assertFalse(runner.isActive());

runner.update();
assertEquals(1, value[0]);
assertFalse(set1.isActive());
assertTrue(runner.isActive());
assertFalse(runner.isDone());

runner.update();
assertEquals(2, value[0]);
assertFalse(set1.isActive());
assertFalse(set2.isActive()); // it should have started and ended
assertTrue(runner.isActive());
assertFalse(runner.isDone());

runner.update();
assertEquals(3, value[0]);
assertFalse(set2.isActive());
assertFalse(set3.isActive());
assertTrue(runner.isActive());

assertTrue(runner.isDone());
runner.end();
}

}

0 comments on commit f165013

Please sign in to comment.