Skip to content

Commit

Permalink
refactoring/#31-state-pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinokurov Kirill committed Apr 15, 2019
1 parent a6d7d8c commit 0db0cb6
Show file tree
Hide file tree
Showing 13 changed files with 288 additions and 24 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,67 @@
package my.neomer.sixtyseconds.core;

import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.Nullable;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ForwardPipeline<T> implements Pipeline<T> {
public class ForwardPipeline<T extends Parcelable> implements Pipeline<T> {

private static final String TAG = "ForwardPipeline";

//region Parcelable

protected ForwardPipeline(Parcel in) {
int listCount = in.readInt();
for (int i = 0; i < listCount; ++i) {
Class<?> elementClass = (Class<?>) in.readSerializable();
if (elementClass != null) {
ClassLoader classLoader = elementClass.getClassLoader();
if (classLoader != null) {
list.add((T) in.readParcelable(classLoader));
} else {
Log.e(TAG, "Element class has no ClassLoader!");
}
} else {
Log.e(TAG, "elementClass is null!");
}
}

idx = in.readInt();
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(list.size());
for (T item : list) {
Class<?> itemClass = item.getClass();
dest.writeSerializable(itemClass);
dest.writeParcelable((Parcelable) item, 0);
}
dest.writeInt(idx);
}

public static final Parcelable.Creator<ForwardPipeline> CREATOR = new Parcelable.Creator<ForwardPipeline>() {
public ForwardPipeline createFromParcel(Parcel in) {
return new ForwardPipeline(in);
}

public ForwardPipeline[] newArray(int size) {
return new ForwardPipeline[size];
}
};

//endregion


protected List<T> list = new ArrayList<>();
protected int idx = 0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package my.neomer.sixtyseconds.core;

import android.os.Parcelable;
import android.support.annotation.Nullable;

public class InfinitePipeline<T> extends ForwardPipeline<T> {
public class InfinitePipeline<T extends Parcelable> extends ForwardPipeline<T> {

public InfinitePipeline() {
}
Expand Down
3 changes: 2 additions & 1 deletion app/src/main/java/my/neomer/sixtyseconds/core/Pipeline.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package my.neomer.sixtyseconds.core;

import android.os.Parcelable;
import android.support.annotation.Nullable;

public interface Pipeline<T> {
public interface Pipeline<T extends Parcelable> extends Parcelable {

@Nullable T current();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,50 @@

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.v4.app.FragmentActivity;

import java.io.Serializable;

import my.neomer.sixtyseconds.model.Answer;
import my.neomer.sixtyseconds.model.Question;

public class BaseGameContext extends ViewModel implements Serializable {
public class BaseGameContext extends ViewModel implements Parcelable {

//region Parcelable

protected BaseGameContext(Parcel in) {
}

public static final Creator<BaseGameContext> CREATOR = new Creator<BaseGameContext>() {
@Override
public BaseGameContext createFromParcel(Parcel in) {
return new BaseGameContext(in);
}

@Override
public BaseGameContext[] newArray(int size) {
return new BaseGameContext[size];
}
};


@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {

}

//endregion

public BaseGameContext() {

}

private final MutableLiveData<Question> question = new MutableLiveData<>();
private final MutableLiveData<Answer> answer = new MutableLiveData<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,15 @@

import android.os.Parcel;
import android.support.annotation.NonNull;
import android.util.Log;

import my.neomer.sixtyseconds.core.Pipeline;
import my.neomer.sixtyseconds.states.IState;
import my.neomer.sixtyseconds.states.IStateFinishListener;

public abstract class BaseGameMode implements IGameMode, IStateFinishListener {

private static final String LOG_TAG = "BaseGameMode";
private BaseGameContext gameContext;
private Pipeline<IState> statePipeline;

Expand Down Expand Up @@ -56,7 +58,13 @@ private void runState(@NonNull IState state) {
//region Parcelable

protected BaseGameMode(Parcel in) {
gameContext = (BaseGameContext) in.readSerializable();
gameContext = (BaseGameContext) in.readParcelable(BaseGameContext.class.getClassLoader());
Class<?> pipelineClass = (Class<?>) in.readSerializable();
if (pipelineClass != null) {
statePipeline = in.readParcelable(pipelineClass.getClassLoader());
} else {
Log.e(LOG_TAG, "Class de-serialization failed!");
}
}

protected BaseGameMode() {
Expand All @@ -70,7 +78,9 @@ public int describeContents() {

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeSerializable(gameContext);
dest.writeParcelable(gameContext, 0);
dest.writeSerializable(statePipeline.getClass());
dest.writeParcelable(statePipeline, 0);
}

//endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,38 +4,33 @@
import android.os.Parcelable;

import my.neomer.sixtyseconds.core.InfinitePipeline;
import my.neomer.sixtyseconds.core.Pipeline;
import my.neomer.sixtyseconds.states.IState;
import my.neomer.sixtyseconds.states.QuestionReceivingState;
import my.neomer.sixtyseconds.states.QuestionState;

public class SinglePlayerWithRatesGameMode extends BaseGameMode {

//region Parcelable

@Override
public void writeToParcel(Parcel dest, int flags) {

}

protected SinglePlayerWithRatesGameMode(Parcel in) {
super(in);

}


public static final Creator<IGameMode> CREATOR = new Creator<IGameMode>() {
public static final Parcelable.Creator<SinglePlayerWithRatesGameMode> CREATOR = new Parcelable.Creator<SinglePlayerWithRatesGameMode>() {

@Override
public IGameMode createFromParcel(Parcel in) {
return new SinglePlayerWithRatesGameMode(in);
public SinglePlayerWithRatesGameMode createFromParcel(Parcel source) {
return new SinglePlayerWithRatesGameMode(source);
}

@Override
public BaseGameMode[] newArray(int size) {
return new BaseGameMode[size];
public SinglePlayerWithRatesGameMode[] newArray(int size) {
return new SinglePlayerWithRatesGameMode[size];
}
};


//endregion

/**
Expand All @@ -44,8 +39,12 @@ public BaseGameMode[] newArray(int size) {
public SinglePlayerWithRatesGameMode() {
super(new SinglePlayerWithRatesContext(),
new InfinitePipeline<IState>(
new QuestionReceivingState()
new QuestionReceivingState(),
new QuestionState()

));
}



}
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package my.neomer.sixtyseconds.states;

import android.os.AsyncTask;
import android.os.Parcel;
import android.support.v4.app.FragmentActivity;

import org.xml.sax.ErrorHandler;

import java.util.concurrent.TimeUnit;

import my.neomer.sixtyseconds.gamemodes.BaseGameContext;
Expand All @@ -18,6 +21,14 @@
*/
public abstract class BaseEscalationState extends BaseState {

//region Parcelable

protected BaseEscalationState(Parcel in) {
super(in);
}

//endregion

private EscalationTimer escalationTimer;

public BaseEscalationState(int escalationTime) {
Expand All @@ -31,11 +42,30 @@ protected final void StartTimer()
escalationTimer.execute();
}

protected final void PauseTimer() { escalationTimer.pause(); }

protected final void ProceedTimer() { escalationTimer.proceed(); }

protected final void CancelTimer()
{
escalationTimer.cancel(true);
}

@Override
public void pause() {
PauseTimer();
}

@Override
public void proceed() {
ProceedTimer();
}

@Override
public void start() {
StartTimer();
}

protected abstract void onTick(int time);
protected abstract void onFinish();
protected abstract void onCancel();
Expand All @@ -44,6 +74,7 @@ static class EscalationTimer extends AsyncTask<Void, Integer, Void>
{
private int escalationTime;
private BaseEscalationState state;
private volatile boolean pause = false;

EscalationTimer(BaseEscalationState state, int escalationTime) {
this.escalationTime = escalationTime;
Expand All @@ -68,12 +99,22 @@ protected void onCancelled() {
super.onCancelled();
}

void proceed() {
pause = false;
}

void pause() {
pause = true;
}

@Override
protected Void doInBackground(Void... voids) {
for (int time = this.escalationTime; time > 0; --time) {
try {
publishProgress(time);
TimeUnit.SECONDS.sleep(1);
do {
TimeUnit.SECONDS.sleep(1);
} while (pause);
} catch (InterruptedException e) {
return null;
}
Expand Down
27 changes: 27 additions & 0 deletions app/src/main/java/my/neomer/sixtyseconds/states/BaseState.java
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
package my.neomer.sixtyseconds.states;

import android.os.Parcel;

import butterknife.ButterKnife;
import my.neomer.sixtyseconds.gamemodes.BaseGameContext;

public abstract class BaseState implements IState {

//region Parcelable

protected BaseState(Parcel in) {
gameContext = (BaseGameContext) in.readSerializable();
stateFinishListener = (IStateFinishListener) in.readSerializable();
}

@Override
public int describeContents() {
return 0;
}

@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeParcelable(getGameContext(), 0);
dest.writeSerializable(stateFinishListener);
}

//endregion

private BaseGameContext gameContext;
private IStateFinishListener stateFinishListener;

public BaseState() {

}

@Override
public void prepareState(BaseGameContext gameContext, IStateFinishListener stateFinishListener) {
ButterKnife.bind(gameContext.getActivity());
Expand All @@ -29,4 +55,5 @@ public void finish() {
stateFinishListener.onFinish(this);
}
}

}
Loading

0 comments on commit 0db0cb6

Please sign in to comment.