0

as an exercise I have been given the core of some functions and I have to implements those missing. We're working on Scheduler and Actions :

Action class :

public abstract class Action {
    private ActionState state;


public Action() {
    this.state = ActionState.READY;
}

/**
 * make one step if the action is in state READY
 * @throws ActionFinishedException if the state is FINISHED
 */
public void doStep() throws ActionFinishedException{
    if (this.isFinished()) {
        throw new ActionFinishedException("Action is finished");
    }
    if (this.state == ActionState.READY) {
        this.state = ActionState.IN_PROGRESS;
    }
    this.makeOneStep();
    if (this.stopCondition()) {
        this.state = ActionState.FINISHED;
    }
}

protected abstract void makeOneStep() throws ActionFinishedException;
protected abstract boolean stopCondition();

/**
 * @return the state
 */
protected ActionState getState() {
    return this.state;
}

/**
 * @return true if the state is FINISHED, false otherwise
 */
public boolean isFinished() {
    return this.state == ActionState.FINISHED;
}

}

Scheduler class :

public abstract class Scheduler extends Action {
protected List<Action> theActions;

public Scheduler() {
    this.theActions = new ArrayList<Action>();
}


@Override
protected void makeOneStep() throws ActionFinishedException {
    Action action = this.nextAction();
    action.doStep();
    if (action.isFinished()) {
        this.removeAction(action);
    }
}

protected List<Action> actions() {
    return this.theActions;
}

public abstract void removeAction(Action action);

protected abstract Action nextAction();

public void addAction(Action action) throws ActionFinishedException, SchedulerStartedException {
    if (this.getState() != ActionState.READY) {
        throw new SchedulerStartedException("Can't add when scheduler is in progress");
    }
    if (action.isFinished()) {
        throw new ActionFinishedException("Can't add an already finished action");
    } else {
        this.theActions.add(action);
    }
}

@Override
protected boolean stopCondition() {
    return this.theActions.isEmpty();
}

}

I'm having trouble implementing nextAction() since the signature that was given doesn't take any parameters I can't access the next element using .get(index+1) and creating an iterator seems like a lot for such a minor task

I'm implementing nextAction() in fairScheduler class :

public class FairScheduler extends Scheduler {

    @Override
    /** removes a given action from the scheduler
     * @param action the action to remove
     */
    public void removeAction(Action action) {
        this.theActions.remove(action);
    }

    /** returns the nextAction in the scheduler, 
     * if the current action is the last element of the scheduler
     * the first action of the scheduler is returned instead
     * 
     * @return an Action, the next in the scheduler from given index
     */
    @Override
    protected Action nextAction() {
        return null;
    }

}
8
  • In which class are you implementing nextAction() method? Commented Oct 28, 2018 at 15:08
  • Initialize ListIterator in constructor as ListIterator<Action> iter = theActions.listIterator(); Commented Oct 28, 2018 at 15:11
  • I added it in the post Commented Oct 28, 2018 at 15:12
  • Can you add new variable to class? Commented Oct 28, 2018 at 15:16
  • Yes I can implement FairScheduler in any way I want, I just need to stick by the signature of nextAction() Commented Oct 28, 2018 at 15:19

2 Answers 2

1

You can use a static variable to keep track of index. If you have same actions/no. of actions for all the scheduler instance, then you can use static variable is to maintain same copy of index variable between multiple FairScheduler class instances.

public class FairScheduler extends Scheduler {

    private static int index = 0;

    @Override
    /** removes a given action from the scheduler
     * @param action the action to remove
     */
    public void removeAction(Action action) {
        this.theActions.remove(action);
    }

    /** returns the nextAction in the scheduler, 
     * if the current action is the last element of the scheduler
     * the first action of the scheduler is returned instead
     * 
     * @return an Action, the next in the scheduler from given index
     */
    @Override
    protected Action nextAction() {
        if (!theActions.isEmpty()) {
            if (index >= theActions.size()){
                index = 0;
            }
            return theActions.get(index++);
        }
    }

}
Sign up to request clarification or add additional context in comments.

2 Comments

Why do you want to maintain the same index between different instances, they might not have the same actions and/or same number of actions?
I don't know the exact functionality of the code, so I assumed he might need to keep same actions for all the schedulers. It was just a suggestion. Edited the answer.
0

To me it looks like you can do this like FIFO or LIFO

FIFO

@Override
public void removeAction(Action action) {
    if (!theActions.isEmpty() && action.isFinished()) {
        theActions.remove(action);
    }
}

@Override
public Action nextAction() {
    if (!theActions.isEmpty()) {
        return theActions.get(0);
    }
}

And for LIFO you do the same but use the last item of the list.

2 Comments

The thing is in the end I need to have a Scheduler which is composed of multiple actions that take some step(s) to be finished (can be more than 1) so an action isn't removed from the scheduler after being executed
@Rémy.W I updated my answer slightly but from your comment it looks to me like the requirements has changed a lot compared to your question. Will all steps of one action be taken in a row or might several actions be active so to speak at the same time?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.