Skip to content

Commit

Permalink
process steps in order instead of looping over them all each time
Browse files Browse the repository at this point in the history
  • Loading branch information
snopoke committed Sep 13, 2023
1 parent d5daca1 commit 3d366f1
Showing 1 changed file with 64 additions and 65 deletions.
129 changes: 64 additions & 65 deletions src/main/java/org/commcare/formplayer/services/MenuSessionFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.util.List;
import java.util.Optional;
import java.util.Vector;

/**
Expand Down Expand Up @@ -62,14 +63,17 @@ public class MenuSessionFactory {
*/
@Trace
public void rebuildSessionFromFrame(MenuSession menuSession, CaseSearchHelper caseSearchHelper) throws CommCareSessionException, RemoteInstanceFetcher.RemoteInstanceException {
Vector<StackFrameStep> steps = menuSession.getSessionWrapper().getFrame().getSteps();
List<StackFrameStep> steps = menuSession.getSessionWrapper().getFrame().getSteps().stream().filter(
step -> !step.getType().equals(SessionFrame.STATE_MARK)
).toList();
menuSession.resetSession();
EntityScreenContext entityScreenContext = new EntityScreenContext();
Screen screen = menuSession.getNextScreen(false, entityScreenContext);
int processedStepsCount = 0;
boolean needsFullInit = false;
while (screen != null) {
String currentStep = null;
while (screen != null && processedStepsCount < steps.size()) {
String input = null;
StackFrameStep currentStep = steps.get(processedStepsCount);
if (screen instanceof MenuScreen) {
if (menuSession.autoAdvanceMenu(screen, storageFactory.getPropertyManager().isAutoAdvanceMenu())) {
screen = menuSession.getNextScreen(needsFullInit, entityScreenContext);
Expand All @@ -78,12 +82,10 @@ public void rebuildSessionFromFrame(MenuSession menuSession, CaseSearchHelper ca

MenuDisplayable[] options = ((MenuScreen)screen).getMenuDisplayables();
for (int i = 0; i < options.length; i++) {
for (StackFrameStep step : steps) {
if (step.getId().equals(options[i].getCommandID())) {
currentStep = String.valueOf(i);
// final step, needs to init fully to show to screen
needsFullInit = ++processedStepsCount == steps.size();
}
if (currentStep.getId().equals(options[i].getCommandID())) {
input = String.valueOf(i);
// final step, needs to init fully to show to screen
needsFullInit = ++processedStepsCount == steps.size();
}
}
} else if (screen instanceof EntityScreen) {
Expand All @@ -92,84 +94,81 @@ public void rebuildSessionFromFrame(MenuSession menuSession, CaseSearchHelper ca
SessionDatum neededDatum = entityScreen.getSession().getNeededDatum();
Vector<Action> actions = entityScreen.getShortDetail().getCustomActions(entityScreen.getEvalContext());
outer:
for (StackFrameStep step : steps) {
if (step.getType().equals(SessionFrame.STATE_DATUM_VAL) && step.getId().equals(neededDatum.getDataId())) {
if (entityScreen.referencesContainStep(step.getValue())) {
currentStep = step.getValue();
needsFullInit = ++processedStepsCount == steps.size();
}
break;
} else if (step.getType().equals(SessionFrame.STATE_COMMAND_ID) && !actions.isEmpty()) {
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (action.getStackOperations() != null) {
for (StackOperation operation : action.getStackOperations()) {
List<StackFrameStep> commandSteps = operation.getStackFrameSteps().stream()
.filter(s -> s.getType().equals(SessionFrame.STATE_COMMAND_ID)).toList();
for (StackFrameStep s : commandSteps) {
String value = s.evaluateValue(entityScreen.getEvalContext());
if (value.equals(step.getId())) {
currentStep = "action " + i;
needsFullInit = ++processedStepsCount == steps.size();
break outer;
}
}
if (currentStep.getType().equals(SessionFrame.STATE_DATUM_VAL) && currentStep.getId().equals(neededDatum.getDataId())) {
if (entityScreen.referencesContainStep(currentStep.getValue())) {
input = currentStep.getValue();
needsFullInit = ++processedStepsCount == steps.size();
}
} else if (currentStep.getType().equals(SessionFrame.STATE_COMMAND_ID) && !actions.isEmpty()) {
// this is messy and gross, but we need to find the action that corresponds to this step
for (int i = 0; i < actions.size(); i++) {
Action action = actions.get(i);
if (action.getStackOperations() != null) {
for (StackOperation operation : action.getStackOperations()) {
Optional<StackFrameStep> commandStep = operation.getStackFrameSteps().stream()
.filter(s -> s.getType().equals(SessionFrame.STATE_COMMAND_ID)).findFirst();
if (commandStep.isEmpty()) {
continue;
}
String value = commandStep.get().evaluateValue(entityScreen.getEvalContext());
if (value.equals(currentStep.getId())) {
input = "action " + i;
needsFullInit = ++processedStepsCount == steps.size();
break outer;
}
}
}
}
}

// Only init subscreen if we are not going to auto-launch a different screen
String nextInput = currentStep == null ? "" : currentStep;
String nextInput = input == null ? "" : input;
entityScreen.evaluateAutoLaunch(nextInput);
if (entityScreen.getAutoLaunchAction() == null) {
entityScreen.initListSubScreen();
}

if (currentStep != null && currentStep != NEXT_SCREEN && entityScreen.shouldBeSkipped()) {
menuSession.handleInput(currentStep, needsFullInit, true, false, entityScreenContext);
if (input != null && input != NEXT_SCREEN && entityScreen.shouldBeSkipped()) {
menuSession.handleInput(input, needsFullInit, true, false, entityScreenContext);
screen = menuSession.getNextScreen(needsFullInit, entityScreenContext);
continue;
}
} else if (screen instanceof QueryScreen) {
QueryScreen queryScreen = (QueryScreen)screen;
RemoteQueryDatum neededDatum = (RemoteQueryDatum) menuSession.getSessionWrapper().getNeededDatum();
for (StackFrameStep step : steps) {
if (step.getId().equals(neededDatum.getDataId())) {
URI uri = null;
try {
uri = new URI(step.getValue());
} catch (URISyntaxException e) {
e.printStackTrace();
throw new CommCareSessionException("Query URL format error: " + e.getMessage(), e);
}
ImmutableMultimap.Builder<String, String> dataBuilder = ImmutableMultimap.builder();
step.getExtras().forEach((key, value) -> dataBuilder.put(key, (String) value));
try {
ExternalDataInstance searchDataInstance = caseSearchHelper.getRemoteDataInstance(
queryScreen.getQueryDatum().getDataId(),
queryScreen.getQueryDatum().useCaseTemplate(),
uri.toURL(),
dataBuilder.build(),
false
);
queryScreen.updateSession(searchDataInstance, dataBuilder.build());
screen = menuSession.getNextScreen(needsFullInit, entityScreenContext);
currentStep = NEXT_SCREEN;
break;
} catch (InvalidStructureException | IOException | XmlPullParserException | UnfullfilledRequirementsException e) {
e.printStackTrace();
throw new CommCareSessionException("Query response format error: " + e.getMessage(), e);
}
if (currentStep.getId().equals(neededDatum.getDataId())) {
URI uri = null;
try {
uri = new URI(currentStep.getValue());
} catch (URISyntaxException e) {
e.printStackTrace();
throw new CommCareSessionException("Query URL format error: " + e.getMessage(), e);
}
ImmutableMultimap.Builder<String, String> dataBuilder = ImmutableMultimap.builder();
currentStep.getExtras().forEach((key, value) -> dataBuilder.put(key, (String) value));
try {
ExternalDataInstance searchDataInstance = caseSearchHelper.getRemoteDataInstance(
queryScreen.getQueryDatum().getDataId(),
queryScreen.getQueryDatum().useCaseTemplate(),
uri.toURL(),
dataBuilder.build(),
false
);
queryScreen.updateSession(searchDataInstance, dataBuilder.build());
needsFullInit = ++processedStepsCount == steps.size();
screen = menuSession.getNextScreen(needsFullInit, entityScreenContext);
input = NEXT_SCREEN;
} catch (InvalidStructureException | IOException | XmlPullParserException | UnfullfilledRequirementsException e) {
e.printStackTrace();
throw new CommCareSessionException("Query response format error: " + e.getMessage(), e);
}
}
}
if (currentStep == null) {
if (input == null) {
break;
} else if (currentStep != NEXT_SCREEN) {
menuSession.handleInput(currentStep, needsFullInit, true, false, entityScreenContext);
menuSession.addSelection(currentStep);
} else if (input != NEXT_SCREEN) {
menuSession.handleInput(input, needsFullInit, true, false, entityScreenContext);
menuSession.addSelection(input);
screen = menuSession.getNextScreen(needsFullInit, entityScreenContext);
}
}
Expand Down

0 comments on commit 3d366f1

Please sign in to comment.