package StevensLevel.parts; import StevensLevel.EventBusHelper; import StevensLevel.State; import StevensLevel.CorrelationEnsurer; import StevensLevel.events.StevensLevelInteraction; import StevensLevel.listeners.ScreenUpdateListener; import StevensLevel.listeners.StevensLevelInteractionListener; import StevensLevel.listeners.StevensLevelViewListener; import StevensLevel.screens.TaskScreen.Graphs; import StevensLevel.screens.TaskScreen.StevensLevelUpdateViewEvent; import common.condition.DotHueType; import common.condition.DotStyleType; import java.util.Arrays; import java.util.List; import render.GraphStyleSheet; import static StevensLevel.EventBusHelper.*; import StevensLevel.UserKeyInteractionListener; import interaction.ExperimentInteractionListener; import screens.Screen; /** *A single task for a participant in which they must choose between lowering or raising a single distribution until they have deemed that it * has a correlation that is between that of two other distributions. * @author Tristan Goffman(tgoffman@gmail.com) Jul 17, 2011 */ public class Trial extends ExperimentModel implements StevensLevelInteractionListener { //Member variables private final double highCorr; private final double lowCorr; private double adjustedCorr; private int numPoints; private final GraphStyleSheet stylesheet; private int timesRefreshed = 0; //Number of time /** * Builds a Trials consisting of the correlation for several graphs (High, User defined and Low) though this is * just naming, it is entirely possible for user to place highCorr at lower level than lowCorr. NOTE: Refactoring naming to use left/right * might be a better model. * * By default the user defined graph will take the value of highCorr. If a specific value is wished for adjustedCorr (user defined) graph than * the other constructor method should be used. * @param highCorr * @param lowCorr * @param numpts */ public Trial(double highCorr, double lowCorr, double startCorr, int numpts, double stepsize, GraphStyleSheet sheet) { this.highCorr = highCorr; this.lowCorr = lowCorr; this.adjustedCorr = startCorr; this.stylesheet = sheet; setPoints(numpts); setStepSize(stepsize); listen(this, StevensLevelInteractionListener.class); listen(this, ExperimentInteractionListener.class); } public double getStepSize() { return stepSize; } private void refresh() { List<StevensLevelUpdateViewEvent> li = Arrays.asList( this.buildPayload(lowCorr, Graphs.LOW), buildAdjustedPayload(), this.buildPayload(highCorr, Graphs.HIGH)); //Publish updates to be picked up by view for graphs and their points etc.. for (StevensLevelUpdateViewEvent payload : li) { pb(this, StevensLevelViewListener.class).update(payload); } pb(this, ScreenUpdateListener.class).screenUpdated(); } private void setStepSize(double stepSize) { this.stepSize = stepSize; } private double stepSize; public int getPoints() { return numPoints; } private void setPoints(int numPoints) { this.numPoints = numPoints; } /** * Trials at the lowest form are what react to forms of StevensLevel user interaction. Correlation Up and Correlation down * @param highCorr * @param lowCorr * @param startCorr * @param numpts * @param stepsize */ public void step(StevensLevelInteraction in) { if (isRunning()) { double toAdd = 0; switch (in) { case CorrelationUp: toAdd += getStepSize(); break; case CorrelationDown: toAdd -= getStepSize(); break; } double prevCorr = getAdjustedCorr(); setAdjustedCorr(CorrelationEnsurer.ensureCorr(prevCorr + toAdd)); if (prevCorr != getAdjustedCorr()) { //Only send an update to the screen if value has changed to avoid user from getting confused eb().getPublisher(this, UserKeyInteractionListener.class).ignoreUserInteractions(); //upcoming change to screen ignore interactions pb(this, StevensLevelViewListener.class).update(buildAdjustedPayload()); pb(this, ScreenUpdateListener.class).screenUpdated(); } } } public void run() { setState(State.IN_PROGRESS); refresh(); } private StevensLevelUpdateViewEvent buildAdjustedPayload() { return this.buildPayload(adjustedCorr, Graphs.USER_DEFINED); } private StevensLevelUpdateViewEvent buildPayload(double corr, Graphs graph) { return new StevensLevelUpdateViewEvent(corr, getPoints(), graph, stylesheet); } public double getAdjustedCorr() { return adjustedCorr; } private void setAdjustedCorr(double adjustedCorr) { this.adjustedCorr = adjustedCorr; } //Events @Override public void correlationStepUp() { step(StevensLevelInteraction.CorrelationUp); } @Override public void correlationStepDown() { step(StevensLevelInteraction.CorrelationDown); } @Override public void stop() { super.stop(); stoplistening(this, StevensLevelInteractionListener.class); } @Override public void spacebarPlaced(){ timesRefreshed++; refresh(); } @Override public void completeTask(){ //Round deals with this action actually. } public double getHighCorr() { return highCorr; } public double getLowCorr() { return lowCorr; } public GraphStyleSheet getStylesheet() { return stylesheet; } }