[update] GameStorage
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 _:
|
||||||
|
|||||||
@@ -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 _:
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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}';
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user