[update] GameStorage

This commit is contained in:
2020-02-14 16:45:53 +03:00
parent 19f564c996
commit e77259c6df
11 changed files with 78 additions and 27 deletions

View File

@@ -3,6 +3,7 @@ package ru.m.puzzlez.core;
import haxework.geom.Point; import haxework.geom.Point;
import haxework.signal.Signal; import haxework.signal.Signal;
import ru.m.puzzlez.core.GameEvent; import ru.m.puzzlez.core.GameEvent;
import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.PartLocation; import ru.m.puzzlez.core.PartLocation;
class Game implements IGame { class Game implements IGame {
@@ -22,11 +23,13 @@ class Game implements IGame {
} }
public function start():Void { public function start():Void {
signal.emit(GameEvent.START(state)); switch state.status {
if (!state.started) { case READY:
shuffle(); shuffle();
state.started = true; state.status = STARTED;
case _:
} }
signal.emit(START(state));
} }
public function shuffle():Void { public function shuffle():Void {
@@ -37,7 +40,7 @@ class Game implements IGame {
var x = bound + Math.random() * (state.preset.tableRect.width - part.rect.width - bound * 2); var x = bound + Math.random() * (state.preset.tableRect.width - part.rect.width - bound * 2);
var y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2); var y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2);
part.location = TABLE(new Point(x, y)); part.location = TABLE(new Point(x, y));
signal.emit(CHANGE(PART_UPDATE(part.id, part.location))); //signal.emit(CHANGE(PART_UPDATE(part.id, part.location)));
case _: case _:
} }
} }
@@ -73,6 +76,7 @@ class Game implements IGame {
part.location = IMAGE; part.location = IMAGE;
signal.emit(CHANGE(PART_UPDATE(id, part.location))); signal.emit(CHANGE(PART_UPDATE(id, part.location)));
if (checkIsComplete()) { if (checkIsComplete()) {
state.status = COMPLETE;
signal.emit(COMPLETE); signal.emit(COMPLETE);
} }
} else { } else {

View File

@@ -1,7 +1,13 @@
package ru.m.puzzlez.core; package ru.m.puzzlez.core;
enum abstract GameStatus(String) from String to String {
var READY = "ready";
var STARTED = "started";
var COMPLETE = "complete";
}
typedef GameState = { typedef GameState = {
var started:Bool; var status:GameStatus;
var preset:GamePreset; var preset:GamePreset;
var parts:Array<Part>; var parts:Array<Part>;
} }

View File

@@ -3,6 +3,7 @@ package ru.m.puzzlez.core;
import haxework.geom.Point; import haxework.geom.Point;
import haxework.geom.Rectangle; import haxework.geom.Rectangle;
import ru.m.puzzlez.core.BoundType; import ru.m.puzzlez.core.BoundType;
import ru.m.puzzlez.core.GameState.GameStatus;
import ru.m.puzzlez.core.Id; import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Part;
import ru.m.puzzlez.core.Side; import ru.m.puzzlez.core.Side;
@@ -125,7 +126,7 @@ class GameUtil {
} }
} }
return { return {
started: false, status: READY,
preset: preset, preset: preset,
parts: parts, parts: parts,
} }

View File

@@ -1,28 +1,54 @@
package ru.m.puzzlez.storage; package ru.m.puzzlez.storage;
import haxework.storage.SharedObjectStorage; import flash.net.SharedObject;
import haxe.DynamicAccess;
import haxe.Serializer;
import haxe.Unserializer;
import ru.m.puzzlez.core.GameState; import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.Id.ImageId; import ru.m.puzzlez.core.Id;
@:provide class GameStorage extends SharedObjectStorage { @:provide class GameStorage {
private static var path = "game_1";
private var statusData:SharedObject;
public function new() { public function new() {
super('game_1'); statusData = SharedObject.getLocal('${path}/status');
} }
public function save(state:GameState):Void { public function save(state:GameState):Void {
write(state.preset.imageId, state); statusData.setProperty(state.preset.imageId, Std.string(state.status));
statusData.flush();
var gameData = SharedObject.getLocal('${path}/${state.preset.imageId}');
gameData.setProperty("game", Serializer.run(state));
gameData.flush();
} }
public function load(imageId:ImageId):Null<GameState> { public function load(imageId:ImageId):Null<GameState> {
return read(imageId); var gameData = SharedObject.getLocal('${path}/${imageId}');
if (Reflect.hasField(gameData.data, "game")) {
return new Unserializer(Reflect.field(gameData.data, "game")).unserialize();
}
return null;
} }
public function listIds():Array<ImageId> { public function list(status:GameStatus = null):Array<ImageId> {
return [for (key in Reflect.fields(so.data)) ImageId.fromString(key)]; var data:DynamicAccess<GameStatus> = statusData.data;
var result:Array<ImageId> = [];
for (k => s in data) {
if (status == null || status == s) {
result.push(k);
}
}
return result;
} }
public function list():Array<GameState> { public function delete(imageId:ImageId):Void {
return [for (id in listIds()) load(id)]; Reflect.deleteField(statusData.data, imageId);
statusData.flush();
}
public function clear():Void {
//ToDo: implement me
} }
} }

View File

@@ -43,6 +43,8 @@ import ru.m.puzzlez.storage.GameStorage;
private function onGameEvent(event:GameEvent):Void { private function onGameEvent(event:GameEvent):Void {
switch event { switch event {
case START(state):
storage.save(state);
case ACTION(PART_PUT(_, _)): case ACTION(PART_PUT(_, _)):
storage.save(game.state); storage.save(game.state);
case _: case _:

View File

@@ -4,11 +4,12 @@ import haxework.view.data.DataView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import haxework.view.popup.ConfirmView; import haxework.view.popup.ConfirmView;
import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.Id.ImageId; import ru.m.puzzlez.core.Id.ImageId;
import ru.m.puzzlez.storage.GameStorage; import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.view.PuzzleImageView; import ru.m.puzzlez.view.PuzzleImageView;
@:template class GameListFrame extends FrameView<Dynamic> { @:template class GameListFrame extends FrameView<GameStatus> {
public static var ID(default, never) = "game_list"; public static var ID(default, never) = "game_list";
@@ -17,16 +18,19 @@ import ru.m.puzzlez.view.PuzzleImageView;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide var storage:GameStorage; @:provide var storage:GameStorage;
private var status:GameStatus;
public function new() { public function new() {
super(ID); super(ID);
} }
override public function onShow(data:Dynamic):Void { override public function onShow(data:GameStatus):Void {
images.data = storage.listIds(); status = data;
images.data = storage.list(status);
} }
private function start(id:ImageId):Void { private function start(id:ImageId):Void {
switcher.change(GameFrame.ID, storage.read(id)); switcher.change(GameFrame.ID, storage.load(id));
} }
private function onAction(imageId:ImageId, action:Action):Void { private function onAction(imageId:ImageId, action:Action):Void {
@@ -35,7 +39,7 @@ import ru.m.puzzlez.view.PuzzleImageView;
ConfirmView.confirm("Delete state?").then(result -> { ConfirmView.confirm("Delete state?").then(result -> {
if (result) { if (result) {
storage.delete(imageId); storage.delete(imageId);
images.data = storage.listIds(); images.data = storage.list(status);
} }
}); });
case _: case _:

View File

@@ -78,7 +78,7 @@ import ru.m.puzzlez.view.PuzzleImageView;
} }
private function start(imageId:ImageId):Void { private function start(imageId:ImageId):Void {
var state = gameStorage.read(imageId); var state = gameStorage.load(imageId);
if (state != null) { if (state != null) {
switcher.change(GameFrame.ID, state); switcher.change(GameFrame.ID, state);
} else { } else {

View File

@@ -38,6 +38,7 @@ class LoadingWrapper {
case LOADING: case LOADING:
overlay = loadingView; overlay = loadingView;
case ERROR(error): case ERROR(error):
L.e("wrapper", "", error);
cast(errorView, TextView).text = Std.string(error); cast(errorView, TextView).text = Std.string(error);
overlay = errorView; overlay = errorView;
} }

View File

@@ -64,7 +64,7 @@ enum Action {
public static function factory(index:Int, imageId:ImageId):PuzzleImageView { public static function factory(index:Int, imageId:ImageId):PuzzleImageView {
var result = new PuzzleImageView(); var result = new PuzzleImageView();
result.imageId = imageId; result.imageId = imageId;
var state = gameStorage.read(imageId); var state = gameStorage.load(imageId);
if (state != null) { if (state != null) {
var progress = GameUtil.calcProgress(state); var progress = GameUtil.calcProgress(state);
result.text = '${progress.complete}/${progress.total}'; result.text = '${progress.complete}/${progress.total}';

View File

@@ -1,11 +1,11 @@
package ru.m.puzzlez.view; package ru.m.puzzlez.view;
import haxe.DynamicAccess;
import haxework.view.data.DataView; import haxework.view.data.DataView;
import haxework.view.form.ButtonView; import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView; import haxework.view.frame.FrameView;
import haxework.view.popup.ConfirmView; import haxework.view.popup.ConfirmView;
import ru.m.puzzlez.core.GameState.GameStatus;
import ru.m.puzzlez.source.AssetSource; import ru.m.puzzlez.source.AssetSource;
import ru.m.puzzlez.source.FileSource; import ru.m.puzzlez.source.FileSource;
import ru.m.puzzlez.source.PixabaySource; import ru.m.puzzlez.source.PixabaySource;
@@ -17,6 +17,7 @@ import ru.m.puzzlez.storage.ImageStorage;
@:view var sources:DataView<ImageListSource<Dynamic>, ButtonView>; @:view var sources:DataView<ImageListSource<Dynamic>, ButtonView>;
@:view("load") var loadButton:ButtonView; @:view("load") var loadButton:ButtonView;
@:view("complete") var completeButton:ButtonView;
@:provide var storage:ImageStorage; @:provide var storage:ImageStorage;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@@ -34,7 +35,8 @@ import ru.m.puzzlez.storage.ImageStorage;
} }
override public function onShow(data:Dynamic):Void { override public function onShow(data:Dynamic):Void {
loadButton.text = 'Load (${gameStorage.list().length})'; loadButton.text = 'Resume (${gameStorage.list(STARTED).length})';
completeButton.text = 'Complete (${gameStorage.list(COMPLETE).length})';
} }
private function sourceViewFactory(index:Int, source:ImageListSource<Dynamic>):ButtonView { private function sourceViewFactory(index:Int, source:ImageListSource<Dynamic>):ButtonView {

View File

@@ -21,11 +21,16 @@ views:
- $type: haxework.view.group.HGroupView - $type: haxework.view.group.HGroupView
geometry.width: 100% geometry.width: 100%
layout.vAlign: middle layout.vAlign: middle
layout.margin: 10
views: views:
- id: load - id: load
$type: haxework.view.form.ButtonView $type: haxework.view.form.ButtonView
text: Load text: Load
+onPress: ~switcher.change('game_list') +onPress: ~switcher.change('game_list', 'started')
- id: complete
$type: haxework.view.form.ButtonView
text: Complete
+onPress: ~switcher.change('game_list', 'complete')
- $type: haxework.view.SpriteView - $type: haxework.view.SpriteView
geometry.width: 100% geometry.width: 100%
- $type: haxework.view.form.ButtonView - $type: haxework.view.form.ButtonView