[update] add CacheStorage; improve PresetFrame
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "puzzlez",
|
"name": "puzzlez",
|
||||||
"version": "0.3.2",
|
"version": "0.3.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"dateformat": "^3.0.3",
|
"dateformat": "^3.0.3",
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
package ru.m;
|
package ru.m;
|
||||||
|
|
||||||
@:enum abstract Platform(String) from String to String {
|
enum abstract Platform(String) from String to String {
|
||||||
var ANDROID = "android";
|
var ANDROID = "android";
|
||||||
var LINUX = "linux";
|
var LINUX = "linux";
|
||||||
var WINDOWS = "windows";
|
var WINDOWS = "windows";
|
||||||
|
var FLASH = "flash";
|
||||||
|
var HTML5 = "html5";
|
||||||
|
var UNKNOWN = "unknown";
|
||||||
}
|
}
|
||||||
|
|
||||||
class Device {
|
class Device {
|
||||||
@@ -17,8 +20,12 @@ class Device {
|
|||||||
return LINUX;
|
return LINUX;
|
||||||
#elseif windows
|
#elseif windows
|
||||||
return WINDOWS;
|
return WINDOWS;
|
||||||
|
#elseif flash
|
||||||
|
return FLASH;
|
||||||
|
#elseif html5
|
||||||
|
return HTML5;
|
||||||
#else
|
#else
|
||||||
return null;
|
return UNKNOWN;
|
||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ class PuzzlezApp extends App {
|
|||||||
// ToDo: fix @:provide macro
|
// ToDo: fix @:provide macro
|
||||||
GameStorage;
|
GameStorage;
|
||||||
ImageStorage;
|
ImageStorage;
|
||||||
|
Const.init();
|
||||||
L.push(new TraceLogger());
|
L.push(new TraceLogger());
|
||||||
updater = new Updater(Const.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
|
updater = new Updater(Const.VERSION, "https://shmyga.ru/repo/puzzlez/packages.json");
|
||||||
var app = new PuzzlezApp(new PuzzlezTheme(), openfl.Assets.getBitmapData("resources/icon.png"));
|
var app = new PuzzlezApp(new PuzzlezTheme(), openfl.Assets.getBitmapData("resources/icon.png"));
|
||||||
|
|||||||
@@ -56,5 +56,12 @@ class PuzzlezTheme extends Theme {
|
|||||||
register(new Style("button.red", [
|
register(new Style("button.red", [
|
||||||
"skin.color" => 0xcc0000,
|
"skin.color" => 0xcc0000,
|
||||||
], "button"));
|
], "button"));
|
||||||
|
|
||||||
|
register(new Style("label.header", [
|
||||||
|
"font.size" => 36,
|
||||||
|
"geometry.hAlign" => HAlign.CENTER,
|
||||||
|
"geometry.margin.top" => 10,
|
||||||
|
"geometry.margin.bottom" => 10,
|
||||||
|
], "label"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -135,6 +135,10 @@ class Render extends SpriteView implements IRender {
|
|||||||
private function onMouseDown(event:MouseEvent):Void {
|
private function onMouseDown(event:MouseEvent):Void {
|
||||||
if (Std.is(event.target, PartView)) {
|
if (Std.is(event.target, PartView)) {
|
||||||
var part:PartView = event.target;
|
var part:PartView = event.target;
|
||||||
|
if (event.ctrlKey) {
|
||||||
|
save(part);
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (part.completed) {
|
if (part.completed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -160,7 +164,6 @@ class Render extends SpriteView implements IRender {
|
|||||||
signal.emit(ACTION(PART_PUT(activePart.id, partPosition.clone())));
|
signal.emit(ACTION(PART_PUT(activePart.id, partPosition.clone())));
|
||||||
tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
|
tableView.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
|
||||||
tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
tableView.stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
|
||||||
//save(activePart);
|
|
||||||
activePart = null;
|
activePart = null;
|
||||||
activePoint = null;
|
activePoint = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
package ru.m.puzzlez.source;
|
package ru.m.puzzlez.source;
|
||||||
|
|
||||||
|
import haxe.io.Bytes;
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import haxework.net.ImageLoader;
|
import flash.utils.ByteArray;
|
||||||
|
import haxework.net.BytesLoader;
|
||||||
import haxework.net.JsonLoader;
|
import haxework.net.JsonLoader;
|
||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import ru.m.puzzlez.core.Id;
|
import ru.m.puzzlez.core.Id;
|
||||||
|
import ru.m.puzzlez.storage.CacheStorage;
|
||||||
|
|
||||||
typedef PixabayImage = {
|
typedef PixabayImage = {
|
||||||
var id:Int;
|
var id:Int;
|
||||||
@@ -57,6 +60,8 @@ class PixabaySource implements IImageSource<PixabayCategory> {
|
|||||||
|
|
||||||
private var cache:Map<String, Promise<PixabayImage>>;
|
private var cache:Map<String, Promise<PixabayImage>>;
|
||||||
|
|
||||||
|
@:provide static var imageCache:CacheStorage;
|
||||||
|
|
||||||
public function new() {
|
public function new() {
|
||||||
cache = new Map();
|
cache = new Map();
|
||||||
}
|
}
|
||||||
@@ -85,7 +90,17 @@ class PixabaySource implements IImageSource<PixabayCategory> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public function loadImage(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
public function loadImage(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
||||||
|
var key = '${id}_${preview}';
|
||||||
|
if (imageCache.exists(key)) {
|
||||||
|
return ImageUtil.bytesToImage(imageCache.read(key));
|
||||||
|
} else {
|
||||||
return getImage(id)
|
return getImage(id)
|
||||||
.pipe((data:PixabayImage) -> return new ImageLoader().GET(preview ? data.webformatURL : data.largeImageURL));
|
.pipe((data:PixabayImage) -> new BytesLoader().GET(preview ? data.webformatURL : data.largeImageURL))
|
||||||
|
.pipe((data:ByteArray) -> {
|
||||||
|
var bytes = Bytes.ofData(data);
|
||||||
|
imageCache.write(key, bytes);
|
||||||
|
return ImageUtil.bytesToImage(bytes);
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
66
src/haxe/ru/m/puzzlez/storage/CacheStorage.hx
Normal file
66
src/haxe/ru/m/puzzlez/storage/CacheStorage.hx
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package ru.m.puzzlez.storage;
|
||||||
|
|
||||||
|
import flash.net.SharedObject;
|
||||||
|
import haxe.io.Bytes;
|
||||||
|
|
||||||
|
#if html5
|
||||||
|
@:provide class CacheStorage {
|
||||||
|
public function new() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exists(key:String):Bool {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function read(key:String):Null<Bytes> {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function write(key:String, data:Bytes):Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove(key:String):Void {
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clean():Void {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
@:provide class CacheStorage {
|
||||||
|
|
||||||
|
public function new() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private inline function getSharedObject(key:String):SharedObject {
|
||||||
|
key = StringTools.replace(key, "/", "_");
|
||||||
|
key = StringTools.replace(key, ":", "_");
|
||||||
|
key = StringTools.replace(key, ".", "_");
|
||||||
|
return SharedObject.getLocal('cache/${key}');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exists(key:String):Bool {
|
||||||
|
var so = getSharedObject(key);
|
||||||
|
return so.size > 0 && Reflect.hasField(so.data, "data");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function read(key:String):Null<Bytes> {
|
||||||
|
var so = getSharedObject(key);
|
||||||
|
return Bytes.ofData(Reflect.field(so.data, "data"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function write(key:String, data:Bytes):Void {
|
||||||
|
var so = getSharedObject(key);
|
||||||
|
so.setProperty("data", data.getData());
|
||||||
|
so.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function remove(key:String):Void {
|
||||||
|
var so = getSharedObject(key);
|
||||||
|
so.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clean():Void {
|
||||||
|
//SharedObject.deleteAll("cache/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#end
|
||||||
@@ -1,15 +1,7 @@
|
|||||||
package ru.m.puzzlez.storage;
|
package ru.m.puzzlez.storage;
|
||||||
|
|
||||||
import flash.display.Bitmap;
|
|
||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.Loader;
|
|
||||||
import flash.display.LoaderInfo;
|
|
||||||
import flash.display.PNGEncoderOptions;
|
|
||||||
import flash.events.Event;
|
|
||||||
import flash.geom.Rectangle;
|
|
||||||
import flash.net.SharedObject;
|
import flash.net.SharedObject;
|
||||||
import flash.utils.ByteArray;
|
|
||||||
import promhx.Deferred;
|
|
||||||
import promhx.Promise;
|
import promhx.Promise;
|
||||||
import Reflect;
|
import Reflect;
|
||||||
import ru.m.puzzlez.core.Id;
|
import ru.m.puzzlez.core.Id;
|
||||||
@@ -47,22 +39,6 @@ import ru.m.puzzlez.source.PixabaySource;
|
|||||||
so.flush();
|
so.flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function serialize(image:BitmapData):ByteArray {
|
|
||||||
var data = new ByteArray();
|
|
||||||
return image.encode(new Rectangle(0, 0, image.width, image.height), new PNGEncoderOptions(), data);
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function unserialize(data:ByteArray):Promise<BitmapData> {
|
|
||||||
var def = new Deferred();
|
|
||||||
var loader = new Loader();
|
|
||||||
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, (event:Event) -> {
|
|
||||||
def.resolve(cast(cast(event.target, LoaderInfo).content, Bitmap).bitmapData);
|
|
||||||
});
|
|
||||||
loader.loadBytes(data);
|
|
||||||
return def.promise();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resolve(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
public function resolve(id:ImageId, preview:Bool = false):Promise<BitmapData> {
|
||||||
var key = '${id}_${preview}';
|
var key = '${id}_${preview}';
|
||||||
if (cache.exists(key)) {
|
if (cache.exists(key)) {
|
||||||
|
|||||||
@@ -2,27 +2,32 @@
|
|||||||
style: frame
|
style: frame
|
||||||
layout.margin: 10
|
layout.margin: 10
|
||||||
views:
|
views:
|
||||||
|
- $type: haxework.view.form.LabelView
|
||||||
|
text: Puzzle configure
|
||||||
|
style: label.header
|
||||||
- $type: haxework.view.group.HGroupView
|
- $type: haxework.view.group.HGroupView
|
||||||
geometry.width: 100%
|
geometry.width: 100%
|
||||||
layout.hAlign: center
|
layout.hAlign: center
|
||||||
layout.vAlign: middle
|
layout.vAlign: middle
|
||||||
views:
|
views:
|
||||||
- $type: haxework.view.form.ButtonView
|
|
||||||
geometry.margin.left: 15
|
|
||||||
text: Start
|
|
||||||
+onPress: ~start()
|
|
||||||
- id: sizes
|
- id: sizes
|
||||||
$type: haxework.view.data.DataView
|
$type: haxework.view.data.DataView
|
||||||
geometry.width: 100%
|
|
||||||
layout:
|
layout:
|
||||||
$type: haxework.view.layout.TailLayout
|
$type: haxework.view.layout.TailLayout
|
||||||
hAlign: center
|
hAlign: center
|
||||||
|
stretch: true
|
||||||
margin: 5
|
margin: 5
|
||||||
factory: ~factory
|
factory: ~factory
|
||||||
+onDataSelect: ~selectSize
|
+onDataSelect: ~selectSize
|
||||||
|
- $type: haxework.view.form.ButtonView
|
||||||
|
style: button.active
|
||||||
|
geometry.margin.left: 15
|
||||||
|
text: Start
|
||||||
|
+onPress: ~start()
|
||||||
- id: image
|
- id: image
|
||||||
$type: ru.m.puzzlez.view.PresetView
|
$type: ru.m.puzzlez.view.PresetView
|
||||||
geometry.stretch: true
|
geometry.stretch: true
|
||||||
|
geometry.margin: 15
|
||||||
- $type: haxework.view.form.ButtonView
|
- $type: haxework.view.form.ButtonView
|
||||||
text: Back
|
text: Back
|
||||||
geometry.position: absolute
|
geometry.position: absolute
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package ru.m.puzzlez.view;
|
|||||||
import flash.display.BitmapData;
|
import flash.display.BitmapData;
|
||||||
import flash.display.Graphics;
|
import flash.display.Graphics;
|
||||||
import flash.display.Shape;
|
import flash.display.Shape;
|
||||||
import flash.geom.Matrix;
|
|
||||||
import haxework.view.group.GroupView;
|
import haxework.view.group.GroupView;
|
||||||
import ru.m.puzzlez.core.GameState;
|
import ru.m.puzzlez.core.GameState;
|
||||||
import ru.m.puzzlez.render.RenderUtil;
|
import ru.m.puzzlez.render.RenderUtil;
|
||||||
@@ -20,8 +19,8 @@ class PresetView extends GroupView {
|
|||||||
|
|
||||||
private function set_scale(value:Float):Float {
|
private function set_scale(value:Float):Float {
|
||||||
var result = table.scaleX = table.scaleY = value;
|
var result = table.scaleX = table.scaleY = value;
|
||||||
table.x = (width - state.preset.tableRect.width * value) / 2;
|
table.x = (width - state.preset.imageRect.width * value) / 2;
|
||||||
table.y = (height - state.preset.tableRect.height * value) / 2;
|
table.y = (height - state.preset.imageRect.height * value) / 2;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -60,16 +59,14 @@ class PresetView extends GroupView {
|
|||||||
var partHeight = preset.imageRect.height / preset.grid.height;
|
var partHeight = preset.imageRect.height / preset.grid.height;
|
||||||
var graphics:Graphics = table.graphics;
|
var graphics:Graphics = table.graphics;
|
||||||
graphics.clear();
|
graphics.clear();
|
||||||
var matrix = new Matrix();
|
graphics.beginBitmapFill(image, null, false, true);
|
||||||
matrix.translate(preset.imageRect.x, preset.imageRect.y);
|
graphics.drawRect(0, 0, preset.imageRect.width, preset.imageRect.height);
|
||||||
graphics.beginBitmapFill(image, matrix, false, true);
|
|
||||||
graphics.drawRect(preset.imageRect.x, preset.imageRect.y, preset.imageRect.width, preset.imageRect.height);
|
|
||||||
graphics.endFill();
|
graphics.endFill();
|
||||||
|
|
||||||
for (part in state.parts) {
|
for (part in state.parts) {
|
||||||
var rect = part.rect.clone();
|
var rect = part.rect.clone();
|
||||||
rect.x = preset.imageRect.x + part.gridX * part.rect.width;
|
rect.x = part.gridX * part.rect.width;
|
||||||
rect.y = preset.imageRect.y + part.gridY * part.rect.height;
|
rect.y = part.gridY * part.rect.height;
|
||||||
var path = RenderUtil.builder.build(rect, part.bounds);
|
var path = RenderUtil.builder.build(rect, part.bounds);
|
||||||
for (value in RenderUtil.borderSettings) {
|
for (value in RenderUtil.borderSettings) {
|
||||||
graphics.lineStyle(1, value.color, value.opacity);
|
graphics.lineStyle(1, value.color, value.opacity);
|
||||||
@@ -82,7 +79,7 @@ class PresetView extends GroupView {
|
|||||||
override public function update():Void {
|
override public function update():Void {
|
||||||
super.update();
|
super.update();
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
scale = Math.min(width / state.preset.tableRect.width, height / state.preset.tableRect.height);
|
scale = Math.min(width / state.preset.imageRect.width, height / state.preset.imageRect.height);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,20 @@
|
|||||||
---
|
---
|
||||||
style: frame
|
style: frame
|
||||||
views:
|
views:
|
||||||
|
- $type: haxework.view.group.HGroupView
|
||||||
|
geometry.hAlign: center
|
||||||
|
geometry.margin.top: 15
|
||||||
|
layout.vAlign: middle
|
||||||
|
views:
|
||||||
|
- $type: haxework.view.ImageView
|
||||||
|
image: $a:image:resources/icon.png
|
||||||
|
stretch: false
|
||||||
|
fillType: CONTAIN
|
||||||
|
geometry.width: 96
|
||||||
|
geometry.height: 96
|
||||||
- $type: haxework.view.form.LabelView
|
- $type: haxework.view.form.LabelView
|
||||||
text: $r:text:name
|
text: $r:text:name
|
||||||
geometry.margin.top: 15
|
font.size: 50
|
||||||
geometry.hAlign: center
|
|
||||||
font.size: 40
|
|
||||||
- id: sources
|
- id: sources
|
||||||
$type: haxework.view.data.DataView
|
$type: haxework.view.data.DataView
|
||||||
layout:
|
layout:
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ class Updater {
|
|||||||
private var url:String;
|
private var url:String;
|
||||||
private var version:Version;
|
private var version:Version;
|
||||||
|
|
||||||
public function new(version:String, url:String) {
|
public function new(version:Version, url:String) {
|
||||||
this.url = url;
|
this.url = url;
|
||||||
this.version = version;
|
this.version = version;
|
||||||
}
|
}
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 25 KiB |
Reference in New Issue
Block a user