From b60e49c0b2d5493902f7696ab813d512bd7070ea Mon Sep 17 00:00:00 2001 From: shmyga Date: Thu, 12 Mar 2020 17:25:41 +0300 Subject: [PATCH] [add] FileStorage --- src/haxe/ru/m/data/DataStorage.hx | 15 +++++-- src/haxe/ru/m/data/IDataSource.hx | 4 +- src/haxe/ru/m/puzzlez/core/GameState.hx | 3 -- src/haxe/ru/m/puzzlez/core/GameUtil.hx | 1 - src/haxe/ru/m/puzzlez/source/AssetSource.hx | 14 ++++--- src/haxe/ru/m/puzzlez/source/FileSource.hx | 42 +++++--------------- src/haxe/ru/m/puzzlez/storage/FileStorage.hx | 19 +++++++++ src/haxe/ru/m/puzzlez/storage/GameStorage.hx | 2 +- src/haxe/ru/m/puzzlez/view/ImageListFrame.hx | 11 ++--- 9 files changed, 55 insertions(+), 56 deletions(-) create mode 100644 src/haxe/ru/m/puzzlez/storage/FileStorage.hx diff --git a/src/haxe/ru/m/data/DataStorage.hx b/src/haxe/ru/m/data/DataStorage.hx index e26bf67..9978d3b 100644 --- a/src/haxe/ru/m/data/DataStorage.hx +++ b/src/haxe/ru/m/data/DataStorage.hx @@ -34,6 +34,12 @@ class DefaultConverter extends Converter { } } +class EmptyConverter extends Converter { + public function new() { + super(item -> item, data -> data); + } +} + class MetaBuilder extends DefaultConverter { private var builder:D -> DataMeta; @@ -51,7 +57,7 @@ typedef DataMeta = Filter; typedef IdValue = {id:I, meta:DataMeta}; -class DataStorage implements IDataManager implements IDataIndex { +class DataStorage implements IDataManager implements IDataIndex { inline private static var DATA_KEY = "item"; @@ -89,7 +95,7 @@ class DataStorage implements IDataManager implements IDataInd private function checkFilter(filter:Null, meta:DataMeta):Bool { if (filter != null) { for (k => v in filter) { - if (meta.get(k) != v) { + if (meta.exists(k) && meta.get(k) != v) { return false; } } @@ -163,11 +169,12 @@ class DataStorage implements IDataManager implements IDataInd } public function save(item:D):Promise { - var stringId = serializeId(item.id); + var meta = metaBuilder.build(item); + var stringId = meta.get("id"); var itemData = SharedObject.getLocal('${name}/${stringId}'); itemData.setProperty(DATA_KEY, serialize(item)); itemData.flush(); - indexData.setProperty(stringId, metaBuilder.serialize(metaBuilder.build(item))); + indexData.setProperty(stringId, metaBuilder.serialize(meta)); indexData.flush(); return Promise.promise(item); } diff --git a/src/haxe/ru/m/data/IDataSource.hx b/src/haxe/ru/m/data/IDataSource.hx index 86d4f46..3ecf95b 100644 --- a/src/haxe/ru/m/data/IDataSource.hx +++ b/src/haxe/ru/m/data/IDataSource.hx @@ -23,12 +23,12 @@ interface IDataIndex { public function getIndexPage(page:Page):Promise>; } -interface IDataSource { +interface IDataSource { public function getPage(page:Page):Promise>; public function get(id:I):Promise; } -interface IDataManager extends IDataSource { +interface IDataManager extends IDataSource { public function save(item:D):Promise; public function delete(id:I):Promise; } diff --git a/src/haxe/ru/m/puzzlez/core/GameState.hx b/src/haxe/ru/m/puzzlez/core/GameState.hx index 8a16e7a..89e68d7 100644 --- a/src/haxe/ru/m/puzzlez/core/GameState.hx +++ b/src/haxe/ru/m/puzzlez/core/GameState.hx @@ -1,7 +1,5 @@ package ru.m.puzzlez.core; -import ru.m.puzzlez.core.Id; - enum abstract GameStatus(String) from String to String { var READY = "ready"; var STARTED = "started"; @@ -9,7 +7,6 @@ enum abstract GameStatus(String) from String to String { } typedef GameState = { - var id:ImageId; 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 cddc55f..c90c112 100644 --- a/src/haxe/ru/m/puzzlez/core/GameUtil.hx +++ b/src/haxe/ru/m/puzzlez/core/GameUtil.hx @@ -129,7 +129,6 @@ class GameUtil { } } return { - id: preset.imageId, status: READY, preset: preset, parts: parts, diff --git a/src/haxe/ru/m/puzzlez/source/AssetSource.hx b/src/haxe/ru/m/puzzlez/source/AssetSource.hx index d9baedf..bfea133 100644 --- a/src/haxe/ru/m/puzzlez/source/AssetSource.hx +++ b/src/haxe/ru/m/puzzlez/source/AssetSource.hx @@ -12,7 +12,7 @@ class AssetSource implements IImageSource { public var id(default, never):SourceId = ID; - private var data:Promise>; + private var data:Array; public function new() { } @@ -22,11 +22,15 @@ class AssetSource implements IImageSource { } public function getIndexPage(page:Page):Promise> { - throw "Implement Me"; - /*if (data == null) { - data = Promise.promise(resolveData()); + if (data == null) { + data = resolveData(); } - return data;*/ + // ToDo: pagination + return Promise.promise({ + page: page, + total: data.length, + data: data, + }); } public function loadImage(id:ImageId, preview:Bool = false):Promise { diff --git a/src/haxe/ru/m/puzzlez/source/FileSource.hx b/src/haxe/ru/m/puzzlez/source/FileSource.hx index c1193a6..e992ecd 100644 --- a/src/haxe/ru/m/puzzlez/source/FileSource.hx +++ b/src/haxe/ru/m/puzzlez/source/FileSource.hx @@ -1,61 +1,37 @@ package ru.m.puzzlez.source; import flash.display.BitmapData; -import flash.net.SharedObject; -import haxe.crypto.Md5; -import haxe.DynamicAccess; import haxe.io.Bytes; import promhx.Promise; import ru.m.data.IDataSource; import ru.m.puzzlez.core.Id; +import ru.m.puzzlez.storage.FileStorage; class FileSource implements IImageSource { public static var ID:SourceId = "file"; public var id(default, never):SourceId = ID; - private var listData:SharedObject; + private var storage:FileStorage; public function new() { - listData = SharedObject.getLocal('${id}_list'); + storage = new FileStorage(); } public function getIndexPage(page:Page):Promise> { - throw "Implement Me"; - //return Promise.promise([for (key in Reflect.fields(listData.data)) ImageId.fromString(key)]); + return storage.getIndexPage(page).then(data -> ({page: data.page, total: data.total, data: data.data.map(item -> new ImageId(id, item))})); } public function loadImage(id:ImageId, preview:Bool = false):Promise { - var fileData = SharedObject.getLocal(id); - var bytes = null; - try { - bytes = Bytes.ofHex(Reflect.field(fileData.data, "image")); - } catch (error:Dynamic) { - var result = new Promise(); - result.reject(error); - return result; - } - return ImageUtil.bytesToImage(bytes); + return storage.get(id.id).pipe(ImageUtil.bytesToImage); } - public function append(data:Bytes):ImageId { - var name = Md5.make(data).toHex(); - var imageId = new ImageId(id, name); - var fileData = SharedObject.getLocal(imageId); - fileData.setProperty("image", data.toHex()); - fileData.flush(); - listData.setProperty(imageId, true); - listData.flush(); - return imageId; + public function append(data:Bytes):Promise { + return storage.save(data); } - public function remove(id:ImageId):Void { - var fileData = SharedObject.getLocal(id); - fileData.clear(); - fileData.flush(); - var access:DynamicAccess = listData.data; - access.remove(id); - listData.flush(); + public function remove(id:ImageId):Promise { + return storage.delete(id.id); } public function clean():Void { diff --git a/src/haxe/ru/m/puzzlez/storage/FileStorage.hx b/src/haxe/ru/m/puzzlez/storage/FileStorage.hx new file mode 100644 index 0000000..ca23025 --- /dev/null +++ b/src/haxe/ru/m/puzzlez/storage/FileStorage.hx @@ -0,0 +1,19 @@ +package ru.m.puzzlez.storage; + +import haxe.crypto.Md5; +import haxe.io.Bytes; +import ru.m.data.DataStorage; + +class FileStorage extends DataStorage { + inline private static var NAME = "file"; + inline private static var VERSION = 1; + + public function new() { + super( + '${NAME}/${VERSION}', + new MetaBuilder(item -> ["id" => Md5.make(item).toHex(), "date" => Date.now().toString()]), + new EmptyConverter(), + new Converter(item -> item.toHex(), data -> Bytes.ofHex(data)) + ); + } +} diff --git a/src/haxe/ru/m/puzzlez/storage/GameStorage.hx b/src/haxe/ru/m/puzzlez/storage/GameStorage.hx index f8505ec..1cc7a90 100644 --- a/src/haxe/ru/m/puzzlez/storage/GameStorage.hx +++ b/src/haxe/ru/m/puzzlez/storage/GameStorage.hx @@ -11,7 +11,7 @@ import ru.m.data.DataStorage; public function new() { super( '${NAME}/${VERSION}', - new MetaBuilder(item -> ["status" => item.status, "date" => Date.now().toString()]), + new MetaBuilder(item -> ["id" => item.preset.imageId, "status" => item.status, "date" => Date.now().toString()]), new Converter(id -> id.toString(), data -> ImageId.fromString(data)) ); } diff --git a/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx index d8a4fbd..69b00d8 100644 --- a/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx +++ b/src/haxe/ru/m/puzzlez/view/ImageListFrame.hx @@ -40,7 +40,7 @@ import ru.m.puzzlez.view.PuzzleImageView; public function new() { super(ID); - page = {index: 0, count: 6}; + page = {index: 0, count: 6, order: [{key: "date", reverse: true}]}; loading = new LoadingWrapper(imagesView); } @@ -67,8 +67,7 @@ import ru.m.puzzlez.view.PuzzleImageView; private function selectFile():Void { FileUtil.browse().then((data:FileContent) -> { var fileSource:FileSource = cast source.source; - var imageId = fileSource.append(data.content); - refresh(); + fileSource.append(data.content).then(_ -> refresh()); }); } @@ -79,16 +78,14 @@ import ru.m.puzzlez.view.PuzzleImageView; if (fileSource != null) { ConfirmView.confirm("Delete image?").then(result -> { if (result) { - fileSource.remove(imageId); - refresh(); + fileSource.remove(imageId).then(_ -> refresh()); } }); } case CLEAN: ConfirmView.confirm("Delete state?").then(result -> { if (result) { - gameStorage.delete(imageId); - refresh(); + gameStorage.delete(imageId).then(_ -> refresh()); } }); }