199 lines
5.9 KiB
Java
199 lines
5.9 KiB
Java
/*
|
|
* Copyright (C) 2015 Hippo Seven
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package com.hippo.scene;
|
|
|
|
import android.os.Bundle;
|
|
import android.support.annotation.NonNull;
|
|
import android.support.annotation.Nullable;
|
|
import android.view.View;
|
|
|
|
import com.hippo.util.Log;
|
|
|
|
import java.util.Stack;
|
|
|
|
class SceneManager {
|
|
|
|
private static final String TAG = SceneManager.class.getSimpleName();
|
|
|
|
private Stack<Scene> mSceneStack = new Stack<>();
|
|
private StageActivity mStageActivity;
|
|
|
|
private Scene mLegacyScene;
|
|
|
|
// Should only be called by SceneApplication
|
|
SceneManager() {
|
|
}
|
|
|
|
void setStageActivity(StageActivity stageActivity) {
|
|
mStageActivity = stageActivity;
|
|
}
|
|
|
|
StageActivity getStageActivity() {
|
|
return mStageActivity;
|
|
}
|
|
|
|
// TODO check previousState state
|
|
void startScene(@NonNull Class sceneClass, @Nullable Announcer announcer,
|
|
@Nullable Curtain curtain) {
|
|
Scene scene;
|
|
try {
|
|
scene = (Scene) sceneClass.newInstance();
|
|
} catch (InstantiationException e) {
|
|
throw new IllegalStateException("Can't instance " + sceneClass.getName());
|
|
} catch (IllegalAccessException e) {
|
|
throw new IllegalStateException("The constructor of " +
|
|
sceneClass.getName() + " is not visible");
|
|
} catch (ClassCastException e) {
|
|
throw new IllegalStateException(sceneClass.getName() + " can not cast to scene");
|
|
}
|
|
scene.setCurtain(curtain);
|
|
|
|
Scene previousState = getTopState();
|
|
mSceneStack.push(scene);
|
|
|
|
if (curtain != null) {
|
|
curtain.setPreviousScene(previousState);
|
|
}
|
|
|
|
if (previousState != null) {
|
|
previousState.pause();
|
|
scene.setState(Scene.SCENE_STATE_PAUSE);
|
|
}
|
|
|
|
scene.setState(Scene.SCENE_STATE_CREATE);
|
|
scene.create(null);
|
|
|
|
if (curtain != null && previousState != null) {
|
|
scene.setState(Scene.SCENE_STATE_OPEN);
|
|
curtain.open(scene, previousState);
|
|
// Set state run by curtain
|
|
} else {
|
|
scene.setState(Scene.SCENE_STATE_RUN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* End legacy scene close animation at once
|
|
*
|
|
* @return True if legacy scene exist and its curtain animation is running
|
|
*/
|
|
boolean endLegacyScene() {
|
|
if (mLegacyScene != null) {
|
|
boolean result = mLegacyScene.endCurtainAnimation();
|
|
mLegacyScene = null;
|
|
return result;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void finishScene(@NonNull Scene scene) {
|
|
int index = getSceneIndex(scene);
|
|
if (index >= 0 && index < mSceneStack.size()) {
|
|
|
|
endLegacyScene();
|
|
|
|
// Scene state might be SCENE_STATE_RUN, SCENE_STATE_OPEN, SCENE_STATE_PAUSE
|
|
if (index == 0) {
|
|
// It is the last scene, just finish the activity
|
|
mSceneStack.remove(index);
|
|
scene.destroy();
|
|
scene.setState(Scene.SCENE_STATE_DESTROY);
|
|
getStageActivity().finish();
|
|
} else {
|
|
// TODO check scene state
|
|
|
|
mSceneStack.remove(index);
|
|
Scene previousState = getTopState();
|
|
|
|
// If Scene is CLOSE
|
|
|
|
if (previousState != null) {
|
|
previousState.resume();
|
|
scene.setState(Scene.SCENE_STATE_RUN);
|
|
}
|
|
|
|
scene.destroy();
|
|
|
|
Curtain curtain = scene.getCurtain();
|
|
if (curtain != null && previousState != null && curtain.isPreviousScene(previousState)) {
|
|
scene.setState(Scene.SCENE_STATE_CLOSE);
|
|
mLegacyScene = scene;
|
|
curtain.close(previousState, scene);
|
|
// detachFromeStage by curtain
|
|
} else {
|
|
scene.setState(Scene.SCENE_STATE_DESTROY);
|
|
scene.detachFromeStage();
|
|
}
|
|
|
|
// Switch stage bar
|
|
View stageBarContent = scene.onCreateStageBar();
|
|
getStageActivity().getStageBar().updateContent(stageBarContent);
|
|
}
|
|
} else {
|
|
Log.e(TAG, "The scene is not in stage");
|
|
}
|
|
}
|
|
|
|
void removeLegacyScene(Scene scene) {
|
|
if (mLegacyScene == scene) {
|
|
mLegacyScene = null;
|
|
}
|
|
}
|
|
|
|
private int getSceneIndex(@NonNull Scene scene) {
|
|
int size = mSceneStack.size();
|
|
while (--size >= 0) {
|
|
if (scene.equals(mSceneStack.get(size))) {
|
|
return size;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
boolean onBackPressed() {
|
|
Scene scene = getTopState();
|
|
if (scene != null) {
|
|
scene.onBackPressed();
|
|
return true;
|
|
} else {
|
|
Log.w(TAG, "There is no scene in the stage");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private Scene getTopState() {
|
|
if (!mSceneStack.isEmpty()) {
|
|
return mSceneStack.peek();
|
|
} else {
|
|
return null;
|
|
}
|
|
}
|
|
|
|
protected void onSaveInstanceState(Bundle outState) {
|
|
for (Scene scene : mSceneStack) {
|
|
scene.saveInstanceState(outState);
|
|
}
|
|
}
|
|
|
|
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
|
|
for (Scene scene : mSceneStack) {
|
|
// Recreate
|
|
scene.create(savedInstanceState);
|
|
scene.restoreInstanceState(savedInstanceState);
|
|
}
|
|
}
|
|
}
|