Commit 4bc45224 authored by Matyáš Latner's avatar Matyáš Latner

#17 Download errors handling

 * reaction to download errors
 * error dialog on loading screen
 * retry of loading
 * internal dialog assets (external are not loaded)
parent 1aa203cb
......@@ -2,6 +2,11 @@ language_system=Systémový jazyk
language_czech=Čeština
language_slovak=Slovenština
system_exit=Konec
system_retry=Znovu
zipassetloader_error=Chyba: Nemohu stáhnout dodatečná data! Zkontrolujte prosím připojení k internetu.
mainmenu_games=Hry
mainmenu_halloffame=Síň slávy
mainmenu_statistics=Statistiky
......
......@@ -2,6 +2,11 @@ language_system=Systémový jazyk
language_czech=Čeština
language_slovak=Slovenčina
system_exit=Koniec
system_retry=Znovu
zipassetloader_error=Chyba: Nemôžem stiahnuť dodatočná dáta! Skontrolujte prosím pripojenie k internetu.
mainmenu_games=Hry
mainmenu_halloffame=Sieň slávy
mainmenu_statistics=Štatistiky
......
......@@ -3,6 +3,11 @@ package cz.nic.tablexia;
import com.badlogic.gdx.Application;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL30;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
import net.engio.mbassy.listener.Handler;
......@@ -24,15 +29,29 @@ import cz.nic.tablexia.screen.AbstractTablexiaScreen;
import cz.nic.tablexia.screen.loader.LoaderScreen;
import cz.nic.tablexia.util.Log;
import cz.nic.tablexia.util.Utility;
import cz.nic.tablexia.util.ui.TablexiaButton;
import cz.nic.tablexia.util.ui.dialog.AbstractButtonDialog;
import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
public class Tablexia extends TablexiaApplication {
private static final String INTERNAL_GFX_ASSETS_PATH = "gfx/";
public static final String ERROR_DIALOG_BACKGROUND_INTERNAL = INTERNAL_GFX_ASSETS_PATH + "dialog_square_borderlines.9.png";
public static final String ERROR_BUTTON_BLUE_UNPRESSED_INTERNAL = INTERNAL_GFX_ASSETS_PATH + "tablexiabutton_blank_blue_unpressed.9.png";
public static final String ERROR_BUTTON_BLUE_PRESSED_INTERNAL = INTERNAL_GFX_ASSETS_PATH + "tablexiabutton_blank_blue_pressed.9.png";
public static final String ERROR_BUTTON_RED_UNPRESSED_INTERNAL = INTERNAL_GFX_ASSETS_PATH + "tablexiabutton_blank_red_unpressed.9.png";
public static final String ERROR_BUTTON_RED_PRESSED_INTERNAL = INTERNAL_GFX_ASSETS_PATH + "tablexiabutton_blank_red_pressed.9.png";
public static final int ERROR_DIALOG_WIDTH = 400;
public static final int ERROR_DIALOG_HEIGHT = 250;
private final SQLConnectionType sqlConnectionType;
private boolean loadingComplete = false;
private MainMenuContainer mainMenuContainer;
private ZipAssetLoader zipAssetLoader;
private Map<String, String> buildChecksums;
private boolean reset;
private boolean errorDialogShown = false;
private ScreenshotListener screenshotListener;
public static class SQLConnectionType {
......@@ -182,8 +201,11 @@ public class Tablexia extends TablexiaApplication {
// load internal assets
if (!ApplicationFontManager.getInstance().update()) return;
if (!ApplicationTextManager.getInstance().update()) return;
// load external assets
if (!zipAssetLoader.update()) return;
if (processLoaderError(zipAssetLoader.getError())) return;
if (!ApplicationAtlasManager.getInstance().update()) return;
if (!ApplicationSoundManager.getInstance().update()) return;
......@@ -192,8 +214,6 @@ public class Tablexia extends TablexiaApplication {
}
}
ScreenshotListener screenshotListener;
/**
* Queues request for screenshot with this listener, it is called after obtaining screenshot.
*
......@@ -237,7 +257,62 @@ public class Tablexia extends TablexiaApplication {
}
//////////////////////////// APPLICATION LOADING COMPLETE EVENT
//////////////////////////// APPLICATION LOADERS
private class LoaderErrorDialog extends AbstractButtonDialog {
public LoaderErrorDialog(float width, float height, DialogTextContent dialogTextContent) {
super((Gdx.graphics.getWidth() / 2) - (width / 2),
(Gdx.graphics.getHeight() / 2) - (height / 2),
width,
height,
new NinePatchDrawable(new NinePatch(new Texture(Gdx.files.internal(ERROR_DIALOG_BACKGROUND_INTERNAL)))),
dialogTextContent);
setModal(true);
createButton(ERROR_BUTTON_BLUE_UNPRESSED_INTERNAL,
ERROR_BUTTON_BLUE_PRESSED_INTERNAL,
ApplicationTextManager.SYSTEM_RETRY,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
zipAssetLoader.reset();
errorDialogShown = false;
hide();
}
});
createButton(ERROR_BUTTON_RED_UNPRESSED_INTERNAL,
ERROR_BUTTON_RED_PRESSED_INTERNAL,
ApplicationTextManager.SYSTEM_EXIT,
new ClickListener() {
@Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.exit();
}
});
}
private void createButton(String unpressed, String pressed, String textKey, ClickListener clickListener) {
TablexiaButton button = new TablexiaButton(new NinePatchDrawable(new NinePatch(new Texture(Gdx.files.internal(unpressed)))),
new NinePatchDrawable(new NinePatch(new Texture(Gdx.files.internal(pressed)))),
null,
ApplicationTextManager.getInstance().getText(textKey));
createButton(button, clickListener);
}
}
private boolean processLoaderError(String loaderError) {
if (loaderError != null && !errorDialogShown) {
new LoaderErrorDialog(ERROR_DIALOG_WIDTH, ERROR_DIALOG_HEIGHT, new DialogTextContent(loaderError)).show(getStage());
errorDialogShown = true;
}
return errorDialogShown;
}
public static class ApplicationLoadingCompleteEvent implements ApplicationEvent {
}
......
......@@ -25,9 +25,14 @@ public class ApplicationTextManager extends TablexiaDataManager<I18NBundle> impl
private static final String APPLICATION_TEXT_RESOURCE_FILE = "text/application/application";
public static final String LANGUAGE_SYSTEM = "language_system";
public static final String LANGUAGE_CZECH = "language_czech";
public static final String LANGUAGE_SLOVAK = "language_slovak";
public static final String SYSTEM_EXIT = "system_exit";
public static final String SYSTEM_RETRY = "system_retry";
public static final String ZIPASSETLOADER_ERROR = "zipassetloader_error";
public static final String LANGUAGE_SYSTEM = "language_system";
public static final String LANGUAGE_CZECH = "language_czech";
public static final String LANGUAGE_SLOVAK = "language_slovak";
private static class ApplicationTextLoader implements AsyncTask<I18NBundle> {
......
......@@ -24,6 +24,7 @@ import cz.nic.tablexia.checksum.Checksum;
import cz.nic.tablexia.loader.IApplicationLoader;
import cz.nic.tablexia.loader.TablexiaAbstractFileManager;
import cz.nic.tablexia.loader.TablexiaDataManager;
import cz.nic.tablexia.loader.application.ApplicationTextManager;
import cz.nic.tablexia.screen.AbstractTablexiaScreen;
import cz.nic.tablexia.util.Log;
......@@ -48,9 +49,25 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
private static boolean downloadResult = false;
private static boolean downloadHasResult = false;
private static Long startTime = null;
private static boolean error = false;
private Locale locale;
private Map<String, String> buildChecksum;
public void load(Locale locale, Map<String, String> buildChecksum) {
this.locale = locale;
this.buildChecksum = buildChecksum;
reset();
}
public void reset() {
error = false;
downloadResult = false;
downloadHasResult = false;
startTime = null;
setAsyncTask(new ZipAssetLoaderTask(locale, buildChecksum));
}
......@@ -87,11 +104,15 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
String assetsPackageName = language + "_" + buildChecksum;
FileHandle assetsPackageFileHandle = TablexiaAbstractFileManager.getFileStoragePathFileHandle(ZIP_FILES_STORAGE_TYPE, assetsPackageName + ZIP_FILE_EXTENSION);
String zipAssetsPackageName = assetsPackageName + ZIP_FILE_EXTENSION;
FileHandle assetsPackageFileHandle = TablexiaAbstractFileManager.getFileStoragePathFileHandle(ZIP_FILES_STORAGE_TYPE, zipAssetsPackageName);
// check current package file and download it if it is necessary
prepareKeyStore();
checkAndDownload(assetsPackageName);
if (!checkAndDownload(assetsPackageName)) {
error(getClass(), String.format("Cannot download assets package: %s", zipAssetsPackageName));
return null;
}
// delete modified or old content
......@@ -108,14 +129,15 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
// extract new content
Log.info(ZipAssetLoader.class, String.format("Extracting new content to: %s", extractDestinationDirectory));
startTimer();
// TODO check full disk situation
unzip(assetsPackageFileHandle, extractDestinationDirectory);
resultTimer("Extract delay");
} else {
Log.err(getClass(), "BUILD CHECKSUM: no build checksum specified for language " + language);
error(getClass(), "BUILD CHECKSUM: no build checksum specified for language " + language);
}
} else {
Log.err(getClass(), "BUILD CHECKSUM: no build checksum specified");
error(getClass(), "BUILD CHECKSUM: no build checksum specified");
}
return null;
......@@ -210,6 +232,7 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
}
private boolean downloadToOutputStream(final String fileName, final OutputStream os) {
downloadHasResult = false;
Net.HttpRequest request = new Net.HttpRequest(Net.HttpMethods.GET);
request.setTimeOut(TABLEXIA_ASSETS_DOWNLOAD_TIMEOUT);
......@@ -236,47 +259,49 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
}
downloadResult = true;
// download complete
synchronized (LOCK) {
LOCK.notify();
}
} catch (IOException e) {
Log.err(ZipAssetLoader.class, "Cannot download file: " + fileName + " !", e);
downloadResult = false;
}
notifyDownload();
}
@Override
public void failed(Throwable t) {
Log.err(ZipAssetLoader.class, "Downloading of file: " + fileName + " Failed!", t);
downloadResult = false;
synchronized (LOCK) {
LOCK.notify();
}
notifyDownload();
}
@Override
public void cancelled() {
Log.info(ZipAssetLoader.class, "Downloading of file: " + fileName + " Canceled!");
downloadResult = false;
synchronized (LOCK) {
LOCK.notify();
}
notifyDownload();
}
});
// wait to download complete
synchronized (LOCK) {
try {
LOCK.wait();
} catch (InterruptedException e) {
Log.err(ZipAssetLoader.class, "Cannot wait to download end!", e);
if (!downloadHasResult) {
try {
LOCK.wait();
} catch (InterruptedException e) {
Log.err(ZipAssetLoader.class, "Cannot wait to download end!", e);
}
}
}
return downloadResult;
}
private void notifyDownload() {
synchronized (LOCK) {
downloadHasResult = true;
LOCK.notify();
}
}
//////////////////////////// EXTRACT
......@@ -347,5 +372,17 @@ public class ZipAssetLoader extends TablexiaDataManager<Void> implements IApplic
Log.debug(ZipAssetLoader.class, String.format("%s: %05f s", message, (System.nanoTime() - startTime) / 1000000000.0));
}
}
//////////////////////////// ERROR
private static void error(Class clazz, String message) {
Log.err(clazz, message);
ApplicationBus.getInstance().post(new AbstractTablexiaScreen.ScreenInfoEvent("Downloading: ", "ERROR")).asynchronously();
error = true;
}
public String getError() {
return error ? ApplicationTextManager.getInstance().getText(ApplicationTextManager.ZIPASSETLOADER_ERROR) : null;
}
}
\ No newline at end of file
......@@ -17,9 +17,9 @@ public class TablexiaButton extends TextButton {
private static final String DEFAULT_BUTTON_TEXT_FONT = ApplicationFontManager.APPLICATION_DEFAULT_FONT_REGULAR;
public enum ButtonType{
BLUE(ApplicationAtlasManager.BUTTON_BLUE_PRESSED, ApplicationAtlasManager.BUTTON_BLUE_UNPRESSED),
GREEN(ApplicationAtlasManager.BUTTON_GREEN_PRESSED, ApplicationAtlasManager.BUTTON_GREEN_UNPRESSED),
RED(ApplicationAtlasManager.BUTTON_RED_PRESSED, ApplicationAtlasManager.BUTTON_RED_UNPRESSED);
BLUE (ApplicationAtlasManager.BUTTON_BLUE_PRESSED, ApplicationAtlasManager.BUTTON_BLUE_UNPRESSED),
GREEN (ApplicationAtlasManager.BUTTON_GREEN_PRESSED, ApplicationAtlasManager.BUTTON_GREEN_UNPRESSED),
RED (ApplicationAtlasManager.BUTTON_RED_PRESSED, ApplicationAtlasManager.BUTTON_RED_UNPRESSED);
public static final String BUTTON_DISABLED = ApplicationAtlasManager.BUTTON_DISABLED;
......@@ -31,26 +31,28 @@ public class TablexiaButton extends TextButton {
this.buttonUnpressedResourceName = buttonUnpressedResourceName;
}
public String getButtonPressedResourceName(){
return buttonPressedResourceName;
public NinePatch getUnpressedDrawable() {
return getNinePatchForName(buttonUnpressedResourceName);
}
public String getButtonUnpressedResourceName() {
return buttonUnpressedResourceName;
public NinePatch getPressedDrawable() {
return getNinePatchForName(buttonPressedResourceName);
}
private NinePatch getNinePatchForName(String name) {
return ApplicationAtlasManager.getInstance().getPatch(name);
}
}
public TablexiaButton(String buttonText, ButtonType buttonType) {
super(buttonText, new TextButton.TextButtonStyle(null, null, null, ApplicationFontManager.getInstance().getFont(DEFAULT_BUTTON_TEXT_FONT)));
NinePatch up = ApplicationAtlasManager.getInstance().getPatch(buttonType.getButtonUnpressedResourceName());
NinePatchDrawable npdUp = new NinePatchDrawable(up);
NinePatch down = ApplicationAtlasManager.getInstance().getPatch(buttonType.getButtonPressedResourceName());
NinePatchDrawable npdDown = new NinePatchDrawable(down);
this(new NinePatchDrawable(buttonType.getUnpressedDrawable()),
new NinePatchDrawable(buttonType.getPressedDrawable()),
new NinePatchDrawable(ApplicationAtlasManager.getInstance().getPatch(buttonType.BUTTON_DISABLED)),
buttonText);
}
NinePatch dis = ApplicationAtlasManager.getInstance().getPatch(buttonType.BUTTON_DISABLED);
NinePatchDrawable npdDis = new NinePatchDrawable(dis);
public TablexiaButton(NinePatchDrawable npdUp, NinePatchDrawable npdDown, NinePatchDrawable npdDis, String buttonText) {
super(buttonText, new TextButton.TextButtonStyle(null, null, null, ApplicationFontManager.getInstance().getFont(DEFAULT_BUTTON_TEXT_FONT)));
TextButton.TextButtonStyle textButtonStyle = new TextButton.TextButtonStyle(npdUp, npdDown, npdDis, ApplicationFontManager.getInstance().getFont(DEFAULT_BUTTON_TEXT_FONT));
textButtonStyle.fontColor = DEFAULT_BUTTON_TEXT_COLOR;
......
package cz.nic.tablexia.util.ui.dialog;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
import cz.nic.tablexia.util.ui.TablexiaButton;
import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
......@@ -9,17 +11,24 @@ import cz.nic.tablexia.util.ui.dialog.text.DialogTextContent;
* Created by Václav Tarantík on 9.4.15.
*/
public abstract class AbstractButtonDialog extends TextDialog {
private static final float BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH = 0.27f;
private static final float BUTTON_HEIGHT_RATIO = 0.5f;
public static final float BUTTON_WIDTH_RATIO_TO_DIALOG_WIDTH = 0.27f;
public static final float BUTTON_HEIGHT_RATIO = 0.5f;
public AbstractButtonDialog(float x, float y, float width, float height, BackGroundType backGroundType, DialogTextContent dialogTextContent) {
super(x, y, width, height, backGroundType, dialogTextContent);
}
public void createButton(String buttonText,TablexiaButton.ButtonType buttonType, ClickListener clickListener){
if(buttonType!=null){
public AbstractButtonDialog(float x, float y, float width, float height, NinePatchDrawable backGroundTypeDrawable, DialogTextContent dialogTextContent) {
super(x, y, width, height, backGroundTypeDrawable, dialogTextContent);
}
public void createButton(String buttonText, TablexiaButton.ButtonType buttonType, ClickListener clickListener){
createButton(new TablexiaButton(buttonText, buttonType), clickListener);
}
TablexiaButton textButton = new TablexiaButton(buttonText,buttonType);
public void createButton(TextButton textButton, ClickListener clickListener){
if(textButton != null){
textButton.addListener(clickListener);
......
......@@ -26,25 +26,37 @@ public class TablexiaDialog extends Dialog {
private boolean hideOnOutsideClick = true;
public enum BackGroundType {
BUBBLE_CLASSIC(ApplicationAtlasManager.DIALOG_BUBBLE_CLASSIC),
BUBBLE_ARROW_DOWN(ApplicationAtlasManager.DIALOG_BUBBLE_ARROW_DOWN),
BUBBLE_ARROW_LEFT(ApplicationAtlasManager.DIALOG_BUBBLE_ARROW_LEFT),
BUBBLE_CLASSIC_CONTINUE_BUTTON(ApplicationAtlasManager.DIALOG_BUBBLE_CLASSIC_CONTINUE_BUTTON),
DIALOG_RECTANGLE(ApplicationAtlasManager.DIALOG_RECTANGLE),
DIALOG_SQUARE(ApplicationAtlasManager.DIALOG_SQUARE),
DIALOG_SQUARE_BORDERLINES(ApplicationAtlasManager.DIALOG_SQUARE_BORDER_LINES);
BUBBLE_CLASSIC (ApplicationAtlasManager.DIALOG_BUBBLE_CLASSIC),
BUBBLE_ARROW_DOWN (ApplicationAtlasManager.DIALOG_BUBBLE_ARROW_DOWN),
BUBBLE_ARROW_LEFT (ApplicationAtlasManager.DIALOG_BUBBLE_ARROW_LEFT),
BUBBLE_CLASSIC_CONTINUE_BUTTON (ApplicationAtlasManager.DIALOG_BUBBLE_CLASSIC_CONTINUE_BUTTON),
DIALOG_RECTANGLE (ApplicationAtlasManager.DIALOG_RECTANGLE),
DIALOG_SQUARE (ApplicationAtlasManager.DIALOG_SQUARE),
DIALOG_SQUARE_BORDERLINES (ApplicationAtlasManager.DIALOG_SQUARE_BORDER_LINES);
private String dialogBackgroundTextureName;
BackGroundType(String dialogBackgroundTextureName) {
this.dialogBackgroundTextureName = dialogBackgroundTextureName;
}
public NinePatchDrawable getDrawable() {
return new NinePatchDrawable(ApplicationAtlasManager.getInstance().getPatch(dialogBackgroundTextureName));
}
}
public TablexiaDialog(float x, float y, float width, float height, BackGroundType backGroundType) {
super("", new DialogStyle(ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(),
Color.BLACK,
new NinePatchDrawable(ApplicationAtlasManager.getInstance().getPatch(backGroundType.dialogBackgroundTextureName)), new SpriteDrawable(new Sprite(ApplicationAtlasManager.getInstance().getColorTexture(ApplicationAtlasManager.COLOR_OVERLAY)))));
this(x, y, width, height, backGroundType.getDrawable());
}
public TablexiaDialog(float x, float y, float width, float height, NinePatchDrawable backgroundTypeDrawable) {
super("",
new DialogStyle(ApplicationFontManager.getInstance().getDefaultApplicationRegularFont(),
Color.BLACK,
backgroundTypeDrawable,
new SpriteDrawable(new Sprite(ApplicationAtlasManager.getInstance().getColorTexture(ApplicationAtlasManager.COLOR_OVERLAY)))));
//TODO MODAL DONT WORK
setModal(true);
setMovable(false);
setResizable(false);
......
......@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.scenes.scene2d.ui.Cell;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
import com.badlogic.gdx.utils.Align;
import cz.nic.tablexia.loader.application.ApplicationFontManager;
......@@ -19,7 +20,11 @@ public class TextDialog extends TablexiaDialog {
private DialogTextContent dialogTextContent;
public TextDialog(float x, float y, float width, float height, BackGroundType backGroundType, DialogTextContent dialogTextContent) {
super(x, y, width, height, backGroundType);
this(x, y, width, height, backGroundType.getDrawable(), dialogTextContent);
}
public TextDialog(float x, float y, float width, float height, NinePatchDrawable backgroundTypeDrawable, DialogTextContent dialogTextContent) {
super(x, y, width, height, backgroundTypeDrawable);
this.dialogTextContent = dialogTextContent;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment