[add] GameStorage

This commit is contained in:
2020-02-04 21:34:18 +03:00
parent a3fef53956
commit 8f934ba365
21 changed files with 181 additions and 66 deletions

View File

@@ -11,8 +11,8 @@ class Game implements IGame {
private var partsById:Map<Int, Part>;
public function new(preset:GamePreset) {
state = GameUtil.buildState(preset);
public function new(state:GameState) {
this.state = state;
partsById = new Map();
for (part in state.parts) {
partsById[part.id] = part;
@@ -23,7 +23,10 @@ class Game implements IGame {
public function start():Void {
signal.emit(GameEvent.START(state));
if (!state.started) {
shuffle();
state.started = true;
}
}
public function shuffle():Void {

View File

@@ -1,6 +1,7 @@
package ru.m.puzzlez.core;
typedef GameState = {
var started:Bool;
var preset:GamePreset;
var parts:Array<Part>;
}

View File

@@ -125,6 +125,7 @@ class GameUtil {
}
}
return {
started: false,
preset: preset,
parts: parts,
}

View File

@@ -78,9 +78,16 @@ class Render extends SpriteView implements IRender {
this.state = state;
for (part in state.parts) {
var partView = PartView.factory(part);
partView.position = part.rect.topLeft;
parts.set(part.id, partView);
switch part.location {
case TABLE(point):
partView.position = point;
tableView.addChild(partView);
case IMAGE:
partView.complete();
imageView.addChild(partView);
case _:
}
}
imageView.x = state.preset.imageRect.x;
@@ -105,7 +112,9 @@ class Render extends SpriteView implements IRender {
parts[result.part.id].image = result.image;
progress.setProgress(++i, state.parts.length);
}).endThen(function(_) {
content.removeChild(progress.content);
if (progress.content.parent != null) {
progress.content.parent.removeChild(progress.content);
}
});
}

View File

@@ -1,4 +1,4 @@
package ru.m.puzzlez.storage;
package ru.m.puzzlez.source;
import flash.display.BitmapData;
import openfl.Assets;

View File

@@ -1,4 +1,4 @@
package ru.m.puzzlez.storage;
package ru.m.puzzlez.source;
import flash.display.BitmapData;
import flash.net.SharedObject;

View File

@@ -0,0 +1,24 @@
package ru.m.puzzlez.source;
import haxework.storage.SharedObjectStorage;
import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.Id.ImageId;
@:provide class GameStorage extends SharedObjectStorage {
public function new() {
super('game_1');
}
public function save(state:GameState):Void {
write(state.preset.image, state);
}
public function load(imageId:ImageId):Null<GameState> {
return read(imageId);
}
public function list():Array<ImageId> {
return [for (key in Reflect.fields(so.data)) ImageId.fromString(key)];
}
}

View File

@@ -1,4 +1,4 @@
package ru.m.puzzlez.storage;
package ru.m.puzzlez.source;
import flash.display.BitmapData;
import promhx.Promise;

View File

@@ -1,4 +1,4 @@
package ru.m.puzzlez.storage;
package ru.m.puzzlez.source;
import flash.display.BitmapData;
import haxework.net.ImageLoader;

View File

@@ -13,6 +13,10 @@ import promhx.Deferred;
import promhx.Promise;
import Reflect;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.source.AssetSource;
import ru.m.puzzlez.source.FileSource;
import ru.m.puzzlez.source.IImageSource;
import ru.m.puzzlez.source.PixabaySource;
@:provide class ImageStorage {

View File

@@ -3,25 +3,30 @@ package ru.m.puzzlez.view;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import ru.m.puzzlez.core.Game;
import ru.m.puzzlez.core.GamePreset;
import ru.m.puzzlez.core.GameEvent;
import ru.m.puzzlez.core.GameState;
import ru.m.puzzlez.core.IGame;
import ru.m.puzzlez.core.PartLocation;
import ru.m.puzzlez.render.IRender;
import ru.m.puzzlez.source.GameStorage;
@:template class GameFrame extends FrameView<GamePreset> {
@:template class GameFrame extends FrameView<GameState> {
public static var ID = "game";
@:view private var render:IRender;
private var game:IGame;
@:provide var switcher:FrameSwitcher;
@:provide var storage:GameStorage;
public function new() {
super(ID);
}
override public function onShow(preset:GamePreset):Void {
override public function onShow(state:GameState):Void {
onHide();
game = new Game(preset);
game = new Game(state);
game.signal.connect(render.onGameEvent);
game.signal.connect(onGameEvent);
render.signal.connect(game.signal.emit);
game.start();
}
@@ -35,7 +40,15 @@ import ru.m.puzzlez.render.IRender;
}
}
private function onGameEvent(event:GameEvent):Void {
switch event {
case CHANGE(PART_UPDATE(_, IMAGE)):
storage.save(game.state);
case _:
}
}
private function back():Void {
switcher.change(ImagesFrame.ID);
switcher.change(ImageListFrame.ID);
}
}

View File

@@ -0,0 +1,34 @@
package ru.m.puzzlez.view;
import haxework.view.data.DataView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.source.GameStorage;
@:template class GameListFrame extends FrameView<Dynamic> {
public static var ID(default, never) = "game_list";
@:view var images:DataView<ImageId, PuzzleImageView>;
@:provide var switcher:FrameSwitcher;
@:provide var storage:GameStorage;
public function new() {
super(ID);
}
override public function onShow(data:Dynamic):Void {
images.data = storage.list();
}
private function start(image:ImageId):Void {
var state = storage.load(image);
switcher.change(GameFrame.ID, state);
}
private function back():Void {
switcher.change(StartFrame.ID);
}
}

View File

@@ -0,0 +1,20 @@
---
style: frame
views:
- id: images
$type: haxework.view.data.DataView
layout:
$type: haxework.view.layout.TailLayout
margin: 5
vAlign: middle
geometry.stretch: true
factory: ~ru.m.puzzlez.view.PuzzleImageView.factory
+onDataSelect: ~start
geometry.margin: 5
overflow.y: scroll
- $type: haxework.view.form.ButtonView
text: Back
geometry.position: absolute
geometry.hAlign: right
geometry.vAlign: top
+onPress: ~back()

View File

@@ -1,49 +1,16 @@
package ru.m.puzzlez.view;
import haxework.view.group.GroupView;
import haxework.view.data.DataView;
import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import haxework.view.ImageView;
import haxework.view.utils.DrawUtil;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.FileUtil;
import ru.m.puzzlez.storage.FileSource;
import ru.m.puzzlez.source.FileSource;
import ru.m.puzzlez.storage.ImageStorage;
class PuzzleImageView extends GroupView {
public var imageId(null, set):ImageId;
private function set_imageId(value:ImageId):ImageId {
if (imageId != value) {
imageId = value;
loading.promise = imageStorage.resolve(imageId, true).then(function(data) image.image = data);
}
return imageId;
}
private var image:ImageView;
private var loading:LoadingWrapper;
@:provide var imageStorage:ImageStorage;
public function new() {
super();
style = "view";
image = new ImageView();
image.geometry.stretch = true;
image.stretch = false;
image.fillType = COVER;
addView(image);
loading = new LoadingWrapper(this);
}
}
@:template class ImagesFrame extends FrameView<ImageListSource<Dynamic>> {
public static var ID = "images";
@:template class ImageListFrame extends FrameView<ImageListSource<Dynamic>> {
public static var ID = "image_list";
@:view var images:DataView<ImageId, PuzzleImageView>;
@:view var select:ButtonView;
@@ -71,12 +38,6 @@ class PuzzleImageView extends GroupView {
//images.data = [];
}
private function imageViewFactory(index:Int, imageId:ImageId):PuzzleImageView {
var result = new PuzzleImageView();
result.imageId = imageId;
return result;
}
private function selectFile():Void {
FileUtil.browse().then(function(data:FileContent) {
var fileSource:FileSource = cast source.source;

View File

@@ -8,7 +8,7 @@ views:
margin: 5
vAlign: middle
geometry.stretch: true
factory: ~imageViewFactory
factory: ~ru.m.puzzlez.view.PuzzleImageView.factory
+onDataSelect: ~start
geometry.margin: 5
overflow.y: scroll

View File

@@ -1,6 +1,6 @@
package ru.m.puzzlez.view;
import ru.m.puzzlez.storage.IImageSource;
import ru.m.puzzlez.source.IImageSource;
typedef ImageListSource<T> = {
var source:IImageSource<T>;

View File

@@ -47,10 +47,10 @@ import ru.m.puzzlez.storage.ImageStorage;
}
private function start():Void {
switcher.change(GameFrame.ID, imageView.preset);
switcher.change(GameFrame.ID, GameUtil.buildState(imageView.preset));
}
private function back():Void {
switcher.change(ImagesFrame.ID);
switcher.change(ImageListFrame.ID);
}
}

View File

@@ -0,0 +1,41 @@
package ru.m.puzzlez.view;
import haxework.view.group.GroupView;
import haxework.view.ImageView;
import haxework.view.utils.DrawUtil;
import ru.m.puzzlez.core.Id;
import ru.m.puzzlez.storage.ImageStorage;
class PuzzleImageView extends GroupView {
public var imageId(null, set):ImageId;
private function set_imageId(value:ImageId):ImageId {
if (imageId != value) {
imageId = value;
loading.promise = imageStorage.resolve(imageId, true).then(function(data) image.image = data);
}
return imageId;
}
private var image:ImageView;
private var loading:LoadingWrapper;
@:provide var imageStorage:ImageStorage;
public function new() {
super();
style = "view";
image = new ImageView();
image.geometry.stretch = true;
image.stretch = false;
image.fillType = COVER;
addView(image);
loading = new LoadingWrapper(this);
}
public static function factory(index:Int, imageId:ImageId):PuzzleImageView {
var result = new PuzzleImageView();
result.imageId = imageId;
return result;
}
}

View File

@@ -6,6 +6,7 @@ views:
style: dark
factory:
_start_: {$class: ru.m.puzzlez.view.StartFrame}
_images_: {$class: ru.m.puzzlez.view.ImagesFrame}
_game_list_: {$class: ru.m.puzzlez.view.GameListFrame}
_image_list_: {$class: ru.m.puzzlez.view.ImageListFrame}
_preset_: {$class: ru.m.puzzlez.view.PresetFrame}
_game_: {$class: ru.m.puzzlez.view.GameFrame}

View File

@@ -4,10 +4,10 @@ import haxework.view.data.DataView;
import haxework.view.form.ButtonView;
import haxework.view.frame.FrameSwitcher;
import haxework.view.frame.FrameView;
import ru.m.puzzlez.storage.AssetSource;
import ru.m.puzzlez.storage.FileSource;
import ru.m.puzzlez.source.AssetSource;
import ru.m.puzzlez.source.FileSource;
import ru.m.puzzlez.storage.ImageStorage;
import ru.m.puzzlez.storage.PixabaySource;
import ru.m.puzzlez.source.PixabaySource;
@:template class StartFrame extends FrameView<Dynamic> {
public static var ID = "start";
@@ -34,6 +34,6 @@ import ru.m.puzzlez.storage.PixabaySource;
}
private function load(source:ImageListSource<Dynamic>):Void {
switcher.change(ImagesFrame.ID, source);
switcher.change(ImageListFrame.ID, source);
}
}

View File

@@ -18,3 +18,6 @@ views:
+onDataSelect: ~load
geometry.margin: 5
overflow.y: scroll
- $type: haxework.view.form.ButtonView
text: Load
+onPress: ~switcher.change('game_list')