diff --git a/src/haxe/ru/m/puzzlez/core/Game.hx b/src/haxe/ru/m/puzzlez/core/Game.hx index b25a3d5..2b4577c 100644 --- a/src/haxe/ru/m/puzzlez/core/Game.hx +++ b/src/haxe/ru/m/puzzlez/core/Game.hx @@ -3,6 +3,7 @@ package ru.m.puzzlez.core; import haxework.geom.Point; import haxework.signal.Signal; import ru.m.puzzlez.core.GameEvent; +import ru.m.puzzlez.core.GameState; import ru.m.puzzlez.core.PartLocation; class Game implements IGame { @@ -22,11 +23,13 @@ class Game implements IGame { } public function start():Void { - signal.emit(GameEvent.START(state)); - if (!state.started) { - shuffle(); - state.started = true; + switch state.status { + case READY: + shuffle(); + state.status = STARTED; + case _: } + signal.emit(START(state)); } 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 y = bound + Math.random() * (state.preset.tableRect.height - part.rect.height - bound * 2); 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 _: } } @@ -73,6 +76,7 @@ class Game implements IGame { part.location = IMAGE; signal.emit(CHANGE(PART_UPDATE(id, part.location))); if (checkIsComplete()) { + state.status = COMPLETE; signal.emit(COMPLETE); } } else { diff --git a/src/haxe/ru/m/puzzlez/core/GameState.hx b/src/haxe/ru/m/puzzlez/core/GameState.hx index d6cf599..89e68d7 100644 --- a/src/haxe/ru/m/puzzlez/core/GameState.hx +++ b/src/haxe/ru/m/puzzlez/core/GameState.hx @@ -1,7 +1,13 @@ package ru.m.puzzlez.core; +enum abstract GameStatus(String) from String to String { + var READY = "ready"; + var STARTED = "started"; + var COMPLETE = "complete"; +} + typedef GameState = { - var started:Bool; + var status:GameStatus; var preset:GamePreset; var parts:Array; } diff --git a/src/haxe/ru/m/puzzlez/core/GameUtil.hx b/src/haxe/ru/m/puzzlez/core/GameUtil.hx index c2de29f..1b6aeed 100644 --- a/src/haxe/ru/m/puzzlez/core/GameUtil.hx +++ b/src/haxe/ru/m/puzzlez/core/GameUtil.hx @@ -3,6 +3,7 @@ package ru.m.puzzlez.core; import haxework.geom.Point; import haxework.geom.Rectangle; import ru.m.puzzlez.core.BoundType; +import ru.m.puzzlez.core.GameState.GameStatus; import ru.m.puzzlez.core.Id; import ru.m.puzzlez.core.Part; import ru.m.puzzlez.core.Side; @@ -125,7 +126,7 @@ class GameUtil { } } return { - started: false, + status: READY, preset: preset, parts: parts, } diff --git a/src/haxe/ru/m/puzzlez/storage/GameStorage.hx b/src/haxe/ru/m/puzzlez/storage/GameStorage.hx index 5ff214d..bb69753 100644 --- a/src/haxe/ru/m/puzzlez/storage/GameStorage.hx +++ b/src/haxe/ru/m/puzzlez/storage/GameStorage.hx @@ -1,28 +1,54 @@ 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.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() { - super('game_1'); + statusData = SharedObject.getLocal('${path}/status'); } 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 { - 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 { - return [for (key in Reflect.fields(so.data)) ImageId.fromString(key)]; + public function list(status:GameStatus = null):Array { + var data:DynamicAccess = statusData.data; + var result:Array = []; + for (k => s in data) { + if (status == null || status == s) { + result.push(k); + } + } + return result; } - public function list():Array { - return [for (id in listIds()) load(id)]; + public function delete(imageId:ImageId):Void { + Reflect.deleteField(statusData.data, imageId); + statusData.flush(); + } + + public function clear():Void { + //ToDo: implement me } } diff --git a/src/haxe/ru/m/puzzlez/view/GameFrame.hx b/src/haxe/ru/m/puzzlez/view/GameFrame.hx index 1e5d912..b84d390 100644 --- a/src/haxe/ru/m/puzzlez/view/GameFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/GameFrame.hx @@ -43,6 +43,8 @@ import ru.m.puzzlez.storage.GameStorage; private function onGameEvent(event:GameEvent):Void { switch event { + case START(state): + storage.save(state); case ACTION(PART_PUT(_, _)): storage.save(game.state); case _: diff --git a/src/haxe/ru/m/puzzlez/view/GameListFrame.hx b/src/haxe/ru/m/puzzlez/view/GameListFrame.hx index c3f2f01..5d6630c 100644 --- a/src/haxe/ru/m/puzzlez/view/GameListFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/GameListFrame.hx @@ -4,11 +4,12 @@ import haxework.view.data.DataView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; import haxework.view.popup.ConfirmView; +import ru.m.puzzlez.core.GameState; import ru.m.puzzlez.core.Id.ImageId; import ru.m.puzzlez.storage.GameStorage; import ru.m.puzzlez.view.PuzzleImageView; -@:template class GameListFrame extends FrameView { +@:template class GameListFrame extends FrameView { public static var ID(default, never) = "game_list"; @@ -17,16 +18,19 @@ import ru.m.puzzlez.view.PuzzleImageView; @:provide var switcher:FrameSwitcher; @:provide var storage:GameStorage; + private var status:GameStatus; + public function new() { super(ID); } - override public function onShow(data:Dynamic):Void { - images.data = storage.listIds(); + override public function onShow(data:GameStatus):Void { + status = data; + images.data = storage.list(status); } 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 { @@ -35,7 +39,7 @@ import ru.m.puzzlez.view.PuzzleImageView; ConfirmView.confirm("Delete state?").then(result -> { if (result) { storage.delete(imageId); - images.data = storage.listIds(); + images.data = storage.list(status); } }); case _: diff --git a/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx index ccc87de..03d8023 100644 --- a/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx @@ -78,7 +78,7 @@ import ru.m.puzzlez.view.PuzzleImageView; } private function start(imageId:ImageId):Void { - var state = gameStorage.read(imageId); + var state = gameStorage.load(imageId); if (state != null) { switcher.change(GameFrame.ID, state); } else { diff --git a/src/haxe/ru/m/puzzlez/view/LoadingWrapper.hx b/src/haxe/ru/m/puzzlez/view/LoadingWrapper.hx index 4cbe48c..ae4dc87 100644 --- a/src/haxe/ru/m/puzzlez/view/LoadingWrapper.hx +++ b/src/haxe/ru/m/puzzlez/view/LoadingWrapper.hx @@ -38,6 +38,7 @@ class LoadingWrapper { case LOADING: overlay = loadingView; case ERROR(error): + L.e("wrapper", "", error); cast(errorView, TextView).text = Std.string(error); overlay = errorView; } diff --git a/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx b/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx index 9e17221..9741542 100644 --- a/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx +++ b/src/haxe/ru/m/puzzlez/view/PuzzleImageView.hx @@ -64,7 +64,7 @@ enum Action { public static function factory(index:Int, imageId:ImageId):PuzzleImageView { var result = new PuzzleImageView(); result.imageId = imageId; - var state = gameStorage.read(imageId); + var state = gameStorage.load(imageId); if (state != null) { var progress = GameUtil.calcProgress(state); result.text = '${progress.complete}/${progress.total}'; diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.hx b/src/haxe/ru/m/puzzlez/view/StartFrame.hx index 13f8d7b..3ea0338 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.hx @@ -1,11 +1,11 @@ package ru.m.puzzlez.view; -import haxe.DynamicAccess; import haxework.view.data.DataView; import haxework.view.form.ButtonView; import haxework.view.frame.FrameSwitcher; import haxework.view.frame.FrameView; import haxework.view.popup.ConfirmView; +import ru.m.puzzlez.core.GameState.GameStatus; import ru.m.puzzlez.source.AssetSource; import ru.m.puzzlez.source.FileSource; import ru.m.puzzlez.source.PixabaySource; @@ -17,6 +17,7 @@ import ru.m.puzzlez.storage.ImageStorage; @:view var sources:DataView, ButtonView>; @:view("load") var loadButton:ButtonView; + @:view("complete") var completeButton:ButtonView; @:provide var storage:ImageStorage; @:provide var switcher:FrameSwitcher; @@ -34,7 +35,8 @@ import ru.m.puzzlez.storage.ImageStorage; } 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):ButtonView { diff --git a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml index fce97f6..07ccd6c 100644 --- a/src/haxe/ru/m/puzzlez/view/StartFrame.yaml +++ b/src/haxe/ru/m/puzzlez/view/StartFrame.yaml @@ -21,11 +21,16 @@ views: - $type: haxework.view.group.HGroupView geometry.width: 100% layout.vAlign: middle + layout.margin: 10 views: - id: load $type: haxework.view.form.ButtonView 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 geometry.width: 100% - $type: haxework.view.form.ButtonView