style: format code

This commit is contained in:
2024-02-12 00:59:07 +03:00
parent 2370c9c2b4
commit 05c736ddd1
84 changed files with 2868 additions and 2977 deletions

View File

@@ -4,13 +4,10 @@ root = true
[*] [*]
charset = utf-8 charset = utf-8
indent_style = space indent_style = space
indent_size = 4 indent_size = 2
insert_final_newline = true insert_final_newline = true
trim_trailing_whitespace = true trim_trailing_whitespace = true
[*.yaml]
indent_size = 2
[*.md] [*.md]
max_line_length = off max_line_length = off
trim_trailing_whitespace = false trim_trailing_whitespace = false

32
.vscode/launch.json vendored
View File

@@ -1,32 +0,0 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"args": [
"app:flash:test"
],
"name": "app:flash:test",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
},
{
"args": [
"server:cpp:test"
],
"name": "server:cpp:test",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"request": "launch",
"skipFiles": [
"<node_internals>/**"
],
"type": "node"
}
]
}

16
.vscode/settings.json vendored
View File

@@ -1,16 +0,0 @@
{
"haxe.executable": {
"path": "/home/shmyga/sdk/haxe/4.2.5/haxe",
"env": {
"HAXE_STD_PATH": "/home/shmyga/sdk/haxe/4.2.5/std",
},
},
"haxe.configurations": [
["build/app/flash/haxe/debug.hxml"],
],
"haxe.displayServer": {
"arguments": [
//"-v"
],
}
}

10
README.md Normal file
View File

@@ -0,0 +1,10 @@
`.bashrc`
```bash
export NEKO_VERSION="2.2.0"
export HAXE_VERSION="4.2.5"
export NEKO_SDK="$HOME/sdk/neko/$NEKO_VERSION"
export HAXE_SDK="$HOME/sdk/haxe/$HAXE_VERSION"
alias haxe-activate=". $NEKO_SDK/activate && . $HAXE_SDK/activate"
```

5
hxformat.json Normal file
View File

@@ -0,0 +1,5 @@
{
"indentation": {
"character": " "
}
}

View File

@@ -18,7 +18,8 @@
"openfl": "9.2.0", "openfl": "9.2.0",
"hxcpp": "4.2.1", "hxcpp": "4.2.1",
"svg": "1.1.3", "svg": "1.1.3",
"protohx": "0.4.6" "protohx": "0.4.6",
"formatter": "1.16.0"
}, },
"haxe": "4.2.5" "haxe": "4.2.5"
} }

46
puzzlez.code-workspace Normal file
View File

@@ -0,0 +1,46 @@
{
"folders": [
{
"path": "."
}
],
"settings": {
"haxe.executable": {
"path": "/home/shmyga/sdk/haxe/4.2.5/haxe",
"env": {
"HAXE_STD_PATH": "/home/shmyga/sdk/haxe/4.2.5/std"
}
},
"haxe.configurations": [["build/app/flash/haxe/debug.hxml"]],
"haxe.displayServer": {
"arguments": [
//"-v"
]
}
},
"extensions": {
"recommendations": ["nadako.vshaxe"]
},
"launch": {
"version": "0.2.0",
"configurations": [
{
"args": ["app:flash:test"],
"name": "app:flash:test",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"request": "launch",
"skipFiles": ["<node_internals>/**"],
"type": "node"
},
{
"args": ["server:cpp:test"],
"name": "server:cpp:test",
"program": "${workspaceFolder}/node_modules/gulp/bin/gulp.js",
"request": "launch",
"skipFiles": ["<node_internals>/**"],
"type": "node"
}
],
"compounds": []
}
}

8
scripts/format Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e
cd "$(dirname $(dirname "$0"))" || exit
source $NEKO_SDK/activate
source $HAXE_SDK/activate
haxelib install formatter
haxelib run formatter -s ./src/common/haxe -s ./src/app/haxe -s ./src/server/haxe

8
scripts/lint Executable file
View File

@@ -0,0 +1,8 @@
#!/usr/bin/env bash
set -e
cd "$(dirname $(dirname "$0"))" || exit
source $NEKO_SDK/activate
source $HAXE_SDK/activate
haxelib install formatter
haxelib run formatter --check -s ./src/common/haxe -s ./src/app/haxe -s ./src/server/haxe

5
scripts/setup Executable file
View File

@@ -0,0 +1,5 @@
#!/usr/bin/env bash
set -e
cd "$(dirname $(dirname "$0"))" || exit
npm ci

View File

@@ -3,6 +3,7 @@ package ru.m;
#if macro #if macro
import haxe.macro.Context; import haxe.macro.Context;
import haxe.macro.Expr; import haxe.macro.Expr;
using haxe.macro.Tools; using haxe.macro.Tools;
#end #end

View File

@@ -15,7 +15,6 @@ enum abstract Platform(String) from String to String {
} }
class Device { class Device {
public static var platform(get, null):Platform; public static var platform(get, null):Platform;
private static function get_platform():Platform { private static function get_platform():Platform {
@@ -34,9 +33,7 @@ class Device {
#end #end
} }
private static var MOBILES(default, never):Array<String> = [ private static var MOBILES(default, never):Array<String> = ["Android", "webOS", "iPhone", "iPad", "iPod", "BlackBerry", "Windows Phone",];
"Android", "webOS", "iPhone", "iPad", "iPod", "BlackBerry", "Windows Phone",
];
public static function isMobile():Bool { public static function isMobile():Bool {
#if android #if android
@@ -71,7 +68,6 @@ class Device {
} }
public static function toggleFullScreen():Void { public static function toggleFullScreen():Void {
Lib.current.stage.displayState = Lib.current.stage.displayState == StageDisplayState.NORMAL ? Lib.current.stage.displayState = Lib.current.stage.displayState == StageDisplayState.NORMAL ? StageDisplayState.FULL_SCREEN : StageDisplayState.NORMAL;
StageDisplayState.FULL_SCREEN : StageDisplayState.NORMAL;
} }
} }

View File

@@ -24,26 +24,17 @@ class Callback<T> {
class ModernFileReference extends FileReference { class ModernFileReference extends FileReference {
#if android #if android
private static var fileUtilBrowse = lime.system.JNI.createStaticMethod( private static var fileUtilBrowse = lime.system.JNI.createStaticMethod("ru.m.android.FileUtil", "browse", "(Lorg/haxe/lime/HaxeObject;)V");
"ru.m.android.FileUtil",
"browse",
"(Lorg/haxe/lime/HaxeObject;)V"
);
#end #end
override public function browse(?typeFilter:Array<FileFilter>):Bool { override public function browse(?typeFilter:Array<FileFilter>):Bool {
#if android #if android
fileUtilBrowse(new Callback<haxe.io.BytesData>( fileUtilBrowse(new Callback<haxe.io.BytesData>(function(result:haxe.io.BytesData):Void {
function(result:haxe.io.BytesData):Void {
data = ByteArray.fromBytesData(result); data = ByteArray.fromBytesData(result);
dispatchEvent(new flash.events.Event(flash.events.Event.COMPLETE)); dispatchEvent(new flash.events.Event(flash.events.Event.COMPLETE));
}, }, function(error:Dynamic):Void {
function(error:Dynamic):Void { dispatchEvent(new flash.events.IOErrorEvent(flash.events.IOErrorEvent.IO_ERROR, false, false, Std.string(error)));
dispatchEvent(new flash.events.IOErrorEvent( }));
flash.events.IOErrorEvent.IO_ERROR, false, false, Std.string(error)
));
}
));
return true; return true;
#else #else
return super.browse(typeFilter); return super.browse(typeFilter);

View File

@@ -0,0 +1,76 @@
package ru.m.api;
import hw.net.JsonLoader;
import promhx.Promise;
typedef PixabayImage = {
var id:Int;
var largeImageURL:String;
var webformatURL:String;
var previewURL:String;
}
typedef PixabayResponse = {
var total:Int;
var totalHits:Int;
var hits:Array<PixabayImage>;
}
enum abstract PixabayCategory(String) from String to String {
var FASHION = "fashion";
var NATURE = "nature";
var BACKGROUNDS = "backgrounds";
var SCIENCE = "science";
var EDUCATION = "education";
var PEOPLE = "people";
var FEELINGS = "feelings";
var RELIGION = "religion";
var HEALTH = "health";
var PLACES = "places";
var ANIMALS = "animals";
var INDUSTRY = "industry";
var FOOD = "food";
var COMPUTER = "computer";
var SPORTS = "sports";
var TRANSPORTATION = "transportation";
var TRAVEL = "travel";
var BUILDINGS = "buildings";
var BUSINESS = "business";
var MUSIC = "music";
}
enum abstract PixabayImageType(String) from String to String {
var ALL = "all";
var PHOTO = "photo";
var ILLUSTRATION = "illustration";
var VECTOR = "vector";
}
class PixabayApi {
private var baseUrl:String = "https://pixabay.com/api/";
private var key:String;
public function new(key:String) {
this.key = key;
}
private function buildRequest(queryMap:Map<String, Dynamic>):String {
queryMap.set("key", key);
var query = [for (k in queryMap.keys()) '${k}=${queryMap.get(k)}'].join("&");
return '${baseUrl}?${query}';
}
public function getPage(page:Int, perPage:Int, category:PixabayCategory = PixabayCategory.NATURE):Promise<PixabayResponse> {
return new JsonLoader<PixabayResponse>().GET(buildRequest([
"category" => category,
"image_type" => PixabayImageType.PHOTO,
"editors_choice" => true,
"per_page" => perPage,
"page" => page,
]));
}
public function get(id:Int):Promise<PixabayImage> {
return new JsonLoader<PixabayResponse>().GET(buildRequest(["id" => id])).then((response:PixabayResponse) -> response.hits[0]);
}
}

View File

@@ -41,8 +41,7 @@ class UnsplashApi {
} }
public function getPage(page:Int, perPage:Int, query:String):Promise<UnsplashResponse> { public function getPage(page:Int, perPage:Int, query:String):Promise<UnsplashResponse> {
return new JsonLoader<UnsplashResponse>() return new JsonLoader<UnsplashResponse>().GET(buildRequest([
.GET(buildRequest([
"per_page" => perPage, "per_page" => perPage,
"page" => page, "page" => page,
"order_by" => "relevant", "order_by" => "relevant",
@@ -52,11 +51,8 @@ class UnsplashApi {
} }
public function get(id:String):Promise<UnsplashImage> { public function get(id:String):Promise<UnsplashImage> {
var queryMap = [ var queryMap = ["client_id" => key,];
"client_id" => key,
];
var query = buildQuery(queryMap); var query = buildQuery(queryMap);
return new JsonLoader<UnsplashImage>() return new JsonLoader<UnsplashImage>().GET('${baseUrl}/photos/${id}?${query}');
.GET('${baseUrl}/photos/${id}?${query}');
} }
} }

View File

@@ -3,6 +3,7 @@ package ru.m.data;
import promhx.Promise; import promhx.Promise;
typedef Filter = Map<String, Dynamic>; typedef Filter = Map<String, Dynamic>;
typedef Order = Array<{ typedef Order = Array<{
var field:String; var field:String;
@:optional var reverse:Bool; @:optional var reverse:Bool;

View File

@@ -2,6 +2,4 @@ package ru.m.event;
import flash.events.Event; import flash.events.Event;
class GestureEvent extends Event { class GestureEvent extends Event {}
}

View File

@@ -10,7 +10,6 @@ typedef Touch = {
} }
class GestureManager { class GestureManager {
private var target:DisplayObject; private var target:DisplayObject;
private var touchesMap:Map<Int, Touch>; private var touchesMap:Map<Int, Touch>;
private var touches:Array<Touch>; private var touches:Array<Touch>;

View File

@@ -1,79 +0,0 @@
package ru.m.pixabay;
import hw.net.JsonLoader;
import promhx.Promise;
typedef PixabayImage = {
var id:Int;
var largeImageURL:String;
var webformatURL:String;
var previewURL:String;
}
typedef PixabayResponse = {
var total:Int;
var totalHits:Int;
var hits:Array<PixabayImage>;
}
enum abstract PixabayCategory(String) from String to String {
var FASHION = "fashion";
var NATURE = "nature";
var BACKGROUNDS = "backgrounds";
var SCIENCE = "science";
var EDUCATION = "education";
var PEOPLE = "people";
var FEELINGS = "feelings";
var RELIGION = "religion";
var HEALTH = "health";
var PLACES = "places";
var ANIMALS = "animals";
var INDUSTRY = "industry";
var FOOD = "food";
var COMPUTER = "computer";
var SPORTS = "sports";
var TRANSPORTATION = "transportation";
var TRAVEL = "travel";
var BUILDINGS = "buildings";
var BUSINESS = "business";
var MUSIC = "music";
}
enum abstract PixabayImageType(String) from String to String {
var ALL = "all";
var PHOTO = "photo";
var ILLUSTRATION = "illustration";
var VECTOR = "vector";
}
class PixabayApi {
private var baseUrl:String = "https://pixabay.com/api/";
private var key:String;
public function new(key:String) {
this.key = key;
}
private function buildRequest(queryMap:Map<String, Dynamic>):String {
queryMap.set("key", key);
var query = [for (k in queryMap.keys()) '${k}=${queryMap.get(k)}'].join("&");
return '${baseUrl}?${query}';
}
public function getPage(page:Int, perPage:Int, category:PixabayCategory = PixabayCategory.NATURE):Promise<PixabayResponse> {
return new JsonLoader<PixabayResponse>()
.GET(buildRequest([
"category" => category,
"image_type" => PixabayImageType.PHOTO,
"editors_choice" => true,
"per_page" => perPage,
"page" => page,
]));
}
public function get(id:Int):Promise<PixabayImage> {
return new JsonLoader<PixabayResponse>()
.GET(buildRequest(["id" => id]))
.then((response:PixabayResponse) -> response.hits[0]);
}
}

View File

@@ -13,7 +13,6 @@ typedef FileContent = {
} }
class FileUtil { class FileUtil {
public static function browse():Promise<FileContent> { public static function browse():Promise<FileContent> {
var d = new Deferred<FileContent>(); var d = new Deferred<FileContent>();
var file = new ModernFileReference(); var file = new ModernFileReference();

View File

@@ -11,7 +11,6 @@ import promhx.Deferred;
import promhx.Promise; import promhx.Promise;
class ImageUtil { class ImageUtil {
public static function bytesToImage(bytes:Bytes):Promise<BitmapData> { public static function bytesToImage(bytes:Bytes):Promise<BitmapData> {
var def = new Deferred(); var def = new Deferred();
var loader = new Loader(); var loader = new Loader();

View File

@@ -15,7 +15,6 @@ import ru.m.puzzlez.view.PuzzlezAppView;
import ru.m.update.Updater; import ru.m.update.Updater;
class PuzzlezApp { class PuzzlezApp {
@:provide static var updater:Updater; @:provide static var updater:Updater;
@:provide static var sourceBundle:ImageSourceBundle; @:provide static var sourceBundle:ImageSourceBundle;

View File

@@ -10,7 +10,6 @@ import openfl.Assets;
import ru.m.skin.ButtonSVGSkin; import ru.m.skin.ButtonSVGSkin;
class PuzzlezTheme extends Theme { class PuzzlezTheme extends Theme {
private static var ICONS:Map<String, String> = [ private static var ICONS:Map<String, String> = [
"close" => "times-circle-solid.svg", "close" => "times-circle-solid.svg",
"setting" => "cog-solid.svg", "setting" => "cog-solid.svg",
@@ -23,9 +22,7 @@ class PuzzlezTheme extends Theme {
public function new() { public function new() {
super({embed: true}, {light: "gray"}, {base: "4h"}); super({embed: true}, {light: "gray"}, {base: "4h"});
register(new Style("frame", [ register(new Style("frame", ["geometry.padding" => Box.fromFloat(8),]));
"geometry.padding" => Box.fromFloat(8),
]));
register(new Style("view", [ register(new Style("view", [
"skin.background.color" => colors.light, "skin.background.color" => colors.light,
"skin.border.color" => colors.border, "skin.border.color" => colors.border,
@@ -33,9 +30,7 @@ class PuzzlezTheme extends Theme {
"geometry.width" => SizeValue.fromString("50h"), "geometry.width" => SizeValue.fromString("50h"),
"geometry.height" => SizeValue.fromString("40h"), "geometry.height" => SizeValue.fromString("40h"),
])); ]));
register(new Style("text.error", [ register(new Style("text.error", ["font.color" => Color.fromString("red"),], "text"));
"font.color" => Color.fromString("red"),
], "text"));
register(new Style("icon", [ register(new Style("icon", [
"geometry.width" => SizeValue.fromString("8h"), "geometry.width" => SizeValue.fromString("8h"),
"geometry.height" => SizeValue.fromString("8h"), "geometry.height" => SizeValue.fromString("8h"),
@@ -43,32 +38,22 @@ class PuzzlezTheme extends Theme {
"skin.color" => colors.light, "skin.color" => colors.light,
])); ]));
for (key in ICONS.keys()) { for (key in ICONS.keys()) {
register(new Style('icon.${key}', [ register(new Style('icon.${key}', ["skin.svg" => Assets.getText('resources/icon/${ICONS.get(key)}'),]));
"skin.svg" => Assets.getText('resources/icon/${ICONS.get(key)}'),
]));
} }
register(new Style("icon.small", [ register(new Style("icon.small", [
"geometry.width" => SizeValue.fromString("6h"), "geometry.width" => SizeValue.fromString("6h"),
"geometry.height" => SizeValue.fromString("6h"), "geometry.height" => SizeValue.fromString("6h"),
])); ]));
register(new Style("icon.red", [ register(new Style("icon.red", ["skin.color" => 0xcc0000,]));
"skin.color" => 0xcc0000, register(new Style("icon.orange", ["skin.color" => 0xcc5500,]));
])); register(new Style("icon.green", ["skin.color" => 0x00ff00,]));
register(new Style("icon.orange", [
"skin.color" => 0xcc5500,
]));
register(new Style("icon.green", [
"skin.color" => 0x00ff00,
]));
register(new Style("icon.control", [ register(new Style("icon.control", [
"geometry.hAlign" => HAlign.RIGHT, "geometry.hAlign" => HAlign.RIGHT,
"geometry.vAlign" => VAlign.TOP, "geometry.vAlign" => VAlign.TOP,
"geometry.margin" => Box.fromFloat(3), "geometry.margin" => Box.fromFloat(3),
])); ]));
register(new Style("button.red", [ register(new Style("button.red", ["skin.color" => 0xcc0000,], "button"));
"skin.color" => 0xcc0000,
], "button"));
register(new Style("label.header", [ register(new Style("label.header", [
"font.size" => SizeValue.fromString("5h"), "font.size" => SizeValue.fromString("5h"),

View File

@@ -9,7 +9,6 @@ import ru.m.puzzlez.core.ImageValue;
import ru.m.puzzlez.proto.game.ImageId; import ru.m.puzzlez.proto.game.ImageId;
abstract ImageData(ImageId) from ImageId { abstract ImageData(ImageId) from ImageId {
private static var cache:Map<String, Promise<BitmapData>> = new Map(); private static var cache:Map<String, Promise<BitmapData>> = new Map();
private static var storageCache:StorageCache = new StorageCache(); private static var storageCache:StorageCache = new StorageCache();

View File

@@ -7,7 +7,6 @@ import flash.geom.Matrix;
import ru.m.puzzlez.render.part.IPartBuilder; import ru.m.puzzlez.render.part.IPartBuilder;
class CompleteView extends Shape { class CompleteView extends Shape {
public var parts:Array<PartView>; public var parts:Array<PartView>;
public var preset:GamePreset; public var preset:GamePreset;

View File

@@ -13,7 +13,6 @@ typedef Result = {
} }
class ImagePartBuilder { class ImagePartBuilder {
private var image:BitmapData; private var image:BitmapData;
public function new(image:BitmapData) { public function new(image:BitmapData) {

View File

@@ -12,7 +12,6 @@ import ru.m.puzzlez.wrap.PointExt;
import ru.m.puzzlez.wrap.RectangleExt; import ru.m.puzzlez.wrap.RectangleExt;
class PartView extends Sprite { class PartView extends Sprite {
public var id(default, null):Int; public var id(default, null):Int;
public var part(default, null):Part; public var part(default, null):Part;
public var position(default, set):Point; public var position(default, set):Point;
@@ -88,7 +87,6 @@ class PartView extends Sprite {
} }
class SpritePartView extends PartView { class SpritePartView extends PartView {
@:provide static var builder:IPartBuilder; @:provide static var builder:IPartBuilder;
override private function redraw():Void { override private function redraw():Void {

View File

@@ -3,7 +3,6 @@ package ru.m.puzzlez.render;
import hw.view.form.LabelView; import hw.view.form.LabelView;
class ProgressView extends LabelView { class ProgressView extends LabelView {
public function new() { public function new() {
super(); super();
text = 'Loading...'; text = 'Loading...';

View File

@@ -22,7 +22,6 @@ import ru.m.puzzlez.settings.Settings;
import ru.m.puzzlez.wrap.PointExt; import ru.m.puzzlez.wrap.PointExt;
class Render extends SpriteView implements IRender { class Render extends SpriteView implements IRender {
public var actions(default, null):Signal<GameAction>; public var actions(default, null):Signal<GameAction>;
public var scale(get, set):Float; public var scale(get, set):Float;
public var manager(default, null):RenderManager; public var manager(default, null):RenderManager;
@@ -198,35 +197,21 @@ class Render extends SpriteView implements IRender {
activePoint = tableView.globalToLocal(point); activePoint = tableView.globalToLocal(point);
tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove); tableView.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp); tableView.stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
actions.emit(new GameAction() actions.emit(new GameAction().setAction(Action.TAKE).setPlayerId(playerId).setPartId(activePart.id));
.setAction(Action.TAKE)
.setPlayerId(playerId)
.setPartId(activePart.id)
);
} }
} }
private function onMouseMove(event:MouseEvent):Void { private function onMouseMove(event:MouseEvent):Void {
var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)); var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY));
var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint); var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint);
actions.emit(new GameAction() actions.emit(new GameAction().setAction(Action.MOVE).setPlayerId(playerId).setPartId(activePart.id).setPosition(partPosition));
.setAction(Action.MOVE)
.setPlayerId(playerId)
.setPartId(activePart.id)
.setPosition(partPosition)
);
activePoint = newPoint; activePoint = newPoint;
} }
private function onMouseUp(event:MouseEvent):Void { private function onMouseUp(event:MouseEvent):Void {
var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY)); var newPoint:PointExt = tableView.globalToLocal(new FlashPoint(event.stageX, event.stageY));
var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint); var partPosition = cast(activePart.position, PointExt).add(newPoint).subtract(activePoint);
actions.emit(new GameAction() actions.emit(new GameAction().setAction(Action.PUT).setPlayerId(playerId).setPartId(activePart.id).setPosition(partPosition));
.setAction(Action.PUT)
.setPlayerId(playerId)
.setPartId(activePart.id)
.setPosition(partPosition)
);
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);
activePart = null; activePart = null;

View File

@@ -7,7 +7,6 @@ import flash.events.MouseEvent;
import flash.geom.Point; import flash.geom.Point;
class RenderManager { class RenderManager {
public var locked(default, default):Bool; public var locked(default, default):Bool;
private var content:DisplayObject; private var content:DisplayObject;

View File

@@ -47,8 +47,7 @@ class RenderUtil {
} }
private static function buildPartGeometry(part:Part):{rect:Rectangle, drawRect:Rectangle} { private static function buildPartGeometry(part:Part):{rect:Rectangle, drawRect:Rectangle} {
var source = new Rectangle() var source = new Rectangle().setX(part.rect.width * part.point.x)
.setX(part.rect.width * part.point.x)
.setY(part.rect.height * part.point.y) .setY(part.rect.height * part.point.y)
.setWidth(part.rect.width) .setWidth(part.rect.width)
.setHeight(part.rect.height); .setHeight(part.rect.height);
@@ -118,8 +117,7 @@ class RenderUtil {
var s = Math.min(1, Math.min(target.width / source.width, target.height / source.height)); var s = Math.min(1, Math.min(target.width / source.width, target.height / source.height));
var width = source.width * s; var width = source.width * s;
var height = source.height * s; var height = source.height * s;
return new Rectangle() return new Rectangle().setX((target.width - width) / 2)
.setX((target.width - width) / 2)
.setY((target.height - height) / 2) .setY((target.height - height) / 2)
.setWidth(width) .setWidth(width)
.setHeight(height); .setHeight(height);

View File

@@ -8,16 +8,13 @@ import ru.m.puzzlez.proto.game.PartBounds;
import ru.m.puzzlez.render.part.IPartBuilder; import ru.m.puzzlez.render.part.IPartBuilder;
class BasePartBuilder implements IPartBuilder { class BasePartBuilder implements IPartBuilder {
public function new() {}
public function new() {
}
private function createAngle(path:DrawPath, x:Float, y:Float, first:Bool = false):Void { private function createAngle(path:DrawPath, x:Float, y:Float, first:Bool = false):Void {
path.commands.push(first ? MOVE_TO(x, y) : LINE_TO(x, y)); path.commands.push(first ? MOVE_TO(x, y) : LINE_TO(x, y));
} }
private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void {}
}
public function build(rect:RectangleExt, bounds:PartBounds):DrawPath { public function build(rect:RectangleExt, bounds:PartBounds):DrawPath {
var path = new DrawPath(); var path = new DrawPath();

View File

@@ -5,7 +5,6 @@ import ru.m.puzzlez.proto.game.BoundType;
import ru.m.puzzlez.proto.game.PartBound; import ru.m.puzzlez.proto.game.PartBound;
class ClassicPartBuilder extends BasePartBuilder { class ClassicPartBuilder extends BasePartBuilder {
override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void {
var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX); var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY); var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
@@ -24,22 +23,36 @@ class ClassicPartBuilder extends BasePartBuilder {
} }
switch bound.spike { switch bound.spike {
case BoundType.IN | BoundType.OUT: case BoundType.IN | BoundType.OUT:
path.commands.push(LINE_TO( path.commands.push(LINE_TO(fromX + spikeOffset * dx + spikeSideOffset * dy, fromY + spikeOffset * dy + spikeSideOffset * dx));
fromX + spikeOffset * dx + spikeSideOffset * dy, path.commands.push(CURVE_TO(fromX
fromY + spikeOffset * dy + spikeSideOffset * dx + (spikeOffset * 0.7) * dx
)); - spikeDepth * dy
path.commands.push(CURVE_TO( + spikeSideOffset * dy,
fromX + (spikeOffset * 0.7) * dx - spikeDepth * dy + spikeSideOffset * dy, fromY
fromY + spikeDepth * dx + (spikeOffset * 0.7) * dy + spikeSideOffset * dx, + spikeDepth * dx
fromX + (spikeOffset + spikeWidth / 2) * dx - (spikeDepth * 1.1) * dy + spikeSideOffset * dy, + (spikeOffset * 0.7) * dy
fromY + (spikeDepth * 1.1) * dx + (spikeOffset + spikeWidth / 2) * dy + spikeSideOffset * dx + spikeSideOffset * dx,
)); fromX
path.commands.push(CURVE_TO( + (spikeOffset + spikeWidth / 2) * dx
fromX + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx - spikeDepth * dy + spikeSideOffset * dy, - (spikeDepth * 1.1) * dy
fromY + spikeDepth * dx + (spikeOffset + spikeWidth + spikeOffset * 0.3) * dy + spikeSideOffset * dx, + spikeSideOffset * dy,
fromX + (spikeOffset + spikeWidth) * dx + spikeSideOffset * dy, fromY
fromY + (spikeOffset + spikeWidth) * dy + spikeSideOffset * dx + (spikeDepth * 1.1) * dx
)); + (spikeOffset + spikeWidth / 2) * dy
+ spikeSideOffset * dx));
path.commands.push(CURVE_TO(fromX
+ (spikeOffset + spikeWidth + spikeOffset * 0.3) * dx
- spikeDepth * dy
+ spikeSideOffset * dy,
fromY
+ spikeDepth * dx
+ (spikeOffset + spikeWidth + spikeOffset * 0.3) * dy
+ spikeSideOffset * dx,
fromX
+ (spikeOffset + spikeWidth) * dx
+ spikeSideOffset * dy, fromY
+ (spikeOffset + spikeWidth) * dy
+ spikeSideOffset * dx));
case _: case _:
} }
} }

View File

@@ -4,7 +4,6 @@ import flash.display.Shape;
import ru.m.draw.DrawPath; import ru.m.draw.DrawPath;
class PartMask extends Shape { class PartMask extends Shape {
public function new(path:DrawPath) { public function new(path:DrawPath) {
super(); super();
graphics.beginFill(0xff00ff, 1); graphics.beginFill(0xff00ff, 1);

View File

@@ -5,7 +5,6 @@ import ru.m.puzzlez.proto.game.BoundType;
import ru.m.puzzlez.proto.game.PartBound; import ru.m.puzzlez.proto.game.PartBound;
class SquarePartBuilder extends BasePartBuilder { class SquarePartBuilder extends BasePartBuilder {
override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void { override private function createBound(path:DrawPath, fromX:Float, fromY:Float, toX:Float, toY:Float, bound:PartBound):Void {
var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX); var dx = toX == fromX ? 0 : (toX - fromX) / Math.abs(toX - fromX);
var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY); var dy = toY == fromY ? 0 : (toY - fromY) / Math.abs(toY - fromY);
@@ -20,22 +19,10 @@ class SquarePartBuilder extends BasePartBuilder {
switch bound.spike { switch bound.spike {
case BoundType.NONE: case BoundType.NONE:
case BoundType.IN | BoundType.OUT: case BoundType.IN | BoundType.OUT:
path.commands.push(LINE_TO( path.commands.push(LINE_TO(fromX + spikeOffset * dx,
fromX + spikeOffset * dx, fromY + spikeOffset * dy)) path.commands.push(LINE_TO(fromX + spikeOffset * dx - spikeDepth * dy, fromY + spikeDepth * dx + spikeOffset * dy));
fromY + spikeOffset * dy path.commands.push(LINE_TO(fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy, fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy));
)) path.commands.push(LINE_TO(fromX + (spikeOffset + spikeWidth) * dx, fromY + (spikeOffset + spikeWidth) * dy));
path.commands.push(LINE_TO(
fromX + spikeOffset * dx - spikeDepth * dy,
fromY + spikeDepth * dx + spikeOffset * dy
));
path.commands.push(LINE_TO(
fromX + (spikeOffset + spikeWidth) * dx - spikeDepth * dy,
fromY + spikeDepth * dx + (spikeOffset + spikeWidth) * dy
));
path.commands.push(LINE_TO(
fromX + (spikeOffset + spikeWidth) * dx,
fromY + (spikeOffset + spikeWidth) * dy
));
} }
} }
} }

View File

@@ -21,11 +21,13 @@ class AssetImageSource implements ImageSource {
return _data; return _data;
} }
public function new() { public function new() {}
}
private function resolveData():Array<ImageId> { private function resolveData():Array<ImageId> {
return [for (name in Assets.list(AssetType.IMAGE).filter((name:String) -> name.substr(0, 15) == "resources/image")) new ImageId().setSource(id).setId(name)]; return [
for (name in Assets.list(AssetType.IMAGE).filter((name:String) -> name.substr(0, 15) == "resources/image"))
new ImageId().setSource(id).setId(name)
];
} }
public function getPage(page:Page):Promise<DataPage<ImageId>> { public function getPage(page:Page):Promise<DataPage<ImageId>> {

View File

@@ -12,8 +12,7 @@ class FileImageSource implements ImageSource {
@:provide private var storage:FileStorage; @:provide private var storage:FileStorage;
public function new() { public function new() {}
}
public function getPage(page:Page):Promise<DataPage<ImageId>> { public function getPage(page:Page):Promise<DataPage<ImageId>> {
return storage.getIndexPage(page).then((response:DataPage<String>) -> { return storage.getIndexPage(page).then((response:DataPage<String>) -> {

View File

@@ -1,8 +1,8 @@
package ru.m.puzzlez.source; package ru.m.puzzlez.source;
import promhx.Promise; import promhx.Promise;
import ru.m.api.PixabayApi;
import ru.m.data.DataSource; import ru.m.data.DataSource;
import ru.m.pixabay.PixabayApi;
import ru.m.puzzlez.core.ImageSource; import ru.m.puzzlez.core.ImageSource;
import ru.m.puzzlez.core.ImageValue; import ru.m.puzzlez.core.ImageValue;
import ru.m.puzzlez.proto.game.ImageId; import ru.m.puzzlez.proto.game.ImageId;
@@ -11,6 +11,7 @@ class PixabayImageSource implements ImageSource {
public var id(default, never):String = "pixabay"; public var id(default, never):String = "pixabay";
private var api:PixabayApi; private var api:PixabayApi;
private static var imageUrlsCache:Map<String, String> = new Map(); private static var imageUrlsCache:Map<String, String> = new Map();
public function new() { public function new() {
@@ -19,8 +20,7 @@ class PixabayImageSource implements ImageSource {
} }
public function getPage(page:Page):Promise<DataPage<ImageId>> { public function getPage(page:Page):Promise<DataPage<ImageId>> {
return this.api.getPage(page.index + 1, page.count, page.filter.get("category")) return this.api.getPage(page.index + 1, page.count, page.filter.get("category")).then((response:PixabayResponse) -> {
.then((response:PixabayResponse) -> {
var data:Array<ImageId> = []; var data:Array<ImageId> = [];
for (hit in response.hits) { for (hit in response.hits) {
imageUrlsCache.set('${hit.id}', hit.largeImageURL); imageUrlsCache.set('${hit.id}', hit.largeImageURL);

View File

@@ -7,12 +7,9 @@ import ru.m.puzzlez.core.ImageSource;
import ru.m.puzzlez.core.ImageValue; import ru.m.puzzlez.core.ImageValue;
import ru.m.puzzlez.proto.game.ImageId; import ru.m.puzzlez.proto.game.ImageId;
typedef Resolver = (id:String, thumb:Bool) -> Promise<String>; typedef Resolver = (id:String, thumb:Bool) -> Promise<String>;
class ImageResolver { class ImageResolver {
private var cache:Map<String, String>; private var cache:Map<String, String>;
private var resolver:Resolver; private var resolver:Resolver;
@@ -29,8 +26,9 @@ class ImageResolver {
return key; return key;
} }
public function setValue(id:String, url:String):Void { public function setValue(id:String, url:String, thumb:Bool = false):Void {
cache.set(id, url); var key = buildKey(id, thumb);
cache.set(key, url);
} }
public function resolve(id:String, thumb:Bool = false) { public function resolve(id:String, thumb:Bool = false) {
@@ -50,21 +48,22 @@ class UnsplashImageSource implements ImageSource {
public var id(default, never):String = "unsplash"; public var id(default, never):String = "unsplash";
private var api:UnsplashApi; private var api:UnsplashApi;
private static var resolver:ImageResolver; private static var resolver:ImageResolver;
public function new() { public function new() {
var key:String = CompilationOption.get("UNSPLASH_KEY"); var key:String = CompilationOption.get("UNSPLASH_KEY");
api = new UnsplashApi(key); api = new UnsplashApi(key);
resolver = new ImageResolver((imageId, thumb) -> { resolver = new ImageResolver((imageId, thumb) -> {
return api.get(imageId).then(data -> thumb ? data.urls.thumb : data.urls.regular); return api.get(imageId).then(data -> thumb ? data.urls.small : data.urls.regular);
}); });
} }
public function getPage(page:Page):Promise<DataPage<ImageId>> { public function getPage(page:Page):Promise<DataPage<ImageId>> {
return this.api.getPage(page.index + 1, page.count, page.filter.get("category")) return this.api.getPage(page.index + 1, page.count, page.filter.get("category")).then((response:UnsplashResponse) -> {
.then((response:UnsplashResponse) -> {
var data:Array<ImageId> = []; var data:Array<ImageId> = [];
for (image in response.results) { for (image in response.results) {
resolver.setValue(image.id, image.urls.small, true);
resolver.setValue(image.id, image.urls.regular); resolver.setValue(image.id, image.urls.regular);
data.push(new ImageId().setSource(id).setId(image.id)); data.push(new ImageId().setSource(id).setId(image.id));
} }

View File

@@ -4,7 +4,6 @@ import haxe.io.Bytes;
import ru.m.storage.SharedObjectDataStorage; import ru.m.storage.SharedObjectDataStorage;
@:provide class FileStorage extends SharedObjectDataStorage<Bytes, String> { @:provide class FileStorage extends SharedObjectDataStorage<Bytes, String> {
public function new() { public function new() {
super("file", new DefaultHelper()); super("file", new DefaultHelper());
} }

View File

@@ -7,9 +7,7 @@ import ru.m.puzzlez.proto.game.ImageId;
import ru.m.storage.SharedObjectDataStorage; import ru.m.storage.SharedObjectDataStorage;
class GameStorageHelper implements DataHelper<GameState, ImageId> { class GameStorageHelper implements DataHelper<GameState, ImageId> {
public function new() { public function new() {}
}
public function idKey(id:ImageId):String { public function idKey(id:ImageId):String {
return '${id.source}:${id.id}'; return '${id.source}:${id.id}';
@@ -33,15 +31,11 @@ class GameStorageHelper implements DataHelper<GameState, ImageId> {
} }
public function dataMeta(data:GameState):DataMeta { public function dataMeta(data:GameState):DataMeta {
return [ return ["status" => data.status, "date" => Date.now(),];
"status" => data.status,
"date" => Date.now(),
];
} }
} }
@:provide class GameStorage extends SharedObjectDataStorage<GameState, ImageId> { @:provide class GameStorage extends SharedObjectDataStorage<GameState, ImageId> {
public function new() { public function new() {
super("game", new GameStorageHelper()); super("game", new GameStorageHelper());
} }

View File

@@ -92,8 +92,7 @@ import ru.m.puzzlez.view.popup.PreviewPopup;
} }
private function back():Void { private function back():Void {
(game.state.status == GameStatus.COMPLETE ? Promise.promise(true) : ConfirmView.confirm("Exit?")) (game.state.status == GameStatus.COMPLETE ? Promise.promise(true) : ConfirmView.confirm("Exit?")).then(result -> {
.then(result -> {
if (result) { if (result) {
switcher.change(StartFrame.ID); switcher.change(StartFrame.ID);
} }

View File

@@ -16,8 +16,8 @@ import ru.m.puzzlez.view.common.PresetView;
@:view("sizes") var sizesView:DataView<IntPoint, ToggleButtonView>; @:view("sizes") var sizesView:DataView<IntPoint, ToggleButtonView>;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
//@:provide var network:Network;
// @:provide var network:Network;
private var imageId:ImageId; private var imageId:ImageId;
public function new() { public function new() {

View File

@@ -9,7 +9,6 @@ import hw.view.frame.FrameSwitcher;
import hw.view.group.VGroupView; import hw.view.group.VGroupView;
@:template class PuzzlezAppView extends VGroupView { @:template class PuzzlezAppView extends VGroupView {
@:view("switcher") var switcherView:FrameSwitcher; @:view("switcher") var switcherView:FrameSwitcher;
@:view("fullscreen") var fullscreenButton:ButtonView; @:view("fullscreen") var fullscreenButton:ButtonView;
@:view("user") var userLabel:LabelView; @:view("user") var userLabel:LabelView;

View File

@@ -4,13 +4,13 @@ import hw.view.data.DataView;
import hw.view.form.ButtonView; import hw.view.form.ButtonView;
import hw.view.frame.FrameSwitcher; import hw.view.frame.FrameSwitcher;
import hw.view.frame.FrameView; import hw.view.frame.FrameView;
import ru.m.pixabay.PixabayApi; import ru.m.api.PixabayApi;
import ru.m.puzzlez.FileUtil; import ru.m.puzzlez.FileUtil;
import ru.m.puzzlez.proto.game.GameStatus; import ru.m.puzzlez.proto.game.GameStatus;
import ru.m.puzzlez.storage.FileStorage; import ru.m.puzzlez.storage.FileStorage;
import ru.m.puzzlez.storage.GameStorage; import ru.m.puzzlez.storage.GameStorage;
import ru.m.puzzlez.view.ImageListFrame;
import ru.m.puzzlez.view.GameListFrame; import ru.m.puzzlez.view.GameListFrame;
import ru.m.puzzlez.view.ImageListFrame;
import ru.m.update.Updater; import ru.m.update.Updater;
@:template class StartFrame extends FrameView<Dynamic> { @:template class StartFrame extends FrameView<Dynamic> {
@@ -22,7 +22,9 @@ import ru.m.update.Updater;
@:view var updateButton:ButtonView; @:view var updateButton:ButtonView;
@:provide var switcher:FrameSwitcher; @:provide var switcher:FrameSwitcher;
@:provide static var appUpdater:Updater; @:provide static var appUpdater:Updater;
@:provide var fileStorage:FileStorage; @:provide var fileStorage:FileStorage;
@:provide var gameStorage:GameStorage; @:provide var gameStorage:GameStorage;
@@ -48,9 +50,7 @@ import ru.m.update.Updater;
} }
public function upload():Void { public function upload():Void {
FileUtil.browse() FileUtil.browse().pipe((data:FileContent) -> fileStorage.save(data.content)).then(_ -> showSource(fileSource));
.pipe((data:FileContent) -> fileStorage.save(data.content))
.then(_ -> showSource(fileSource));
} }
public function showSource(config:ImageListConfig):Void { public function showSource(config:ImageListConfig):Void {

View File

@@ -8,20 +8,17 @@ import ru.m.puzzlez.proto.game.ImageId;
import ru.m.view.LoadingWrapper; import ru.m.view.LoadingWrapper;
@:template class ImageIdView extends GroupView { @:template class ImageIdView extends GroupView {
public var thumb:Bool = false; public var thumb:Bool = false;
public var imageId(default, set):ImageId; public var imageId(default, set):ImageId;
private function set_imageId(value:ImageId):ImageId { private function set_imageId(value:ImageId):ImageId {
imageId = value; imageId = value;
var imageData = ImageData var imageData = ImageData.fromImageId(imageId);
.fromImageId(imageId);
if (thumb) { if (thumb) {
imageData = imageData.withThumb(); imageData = imageData.withThumb();
} }
loading.promise = imageData loading.promise = imageData.resolve().then(data -> this.imageView.image = data);
.resolve()
.then(data -> this.imageView.image = data);
return imageId; return imageId;
} }

View File

@@ -15,25 +15,9 @@ import ru.m.puzzlez.proto.game.ImageId;
import ru.m.puzzlez.render.Background; import ru.m.puzzlez.render.Background;
@:singleton @:template class BackgroundPopup extends PopupView<Background> { @:singleton @:template class BackgroundPopup extends PopupView<Background> {
private static var colorsList:Array<Color> = [ private static var colorsList:Array<Color> = [
'#FFFFFF', '#FFFFFF', '#001f3f', '#0074D9', '#7FDBFF', '#39CCCC', '#3D9970', '#2ECC40', '#01FF70', '#FFDC00', '#FF851B', '#FF4136', '#85144b', '#F012BE', '#B10DC9',
'#001f3f', '#111111', '#AAAAAA', '#DDDDDD',
'#0074D9',
'#7FDBFF',
'#39CCCC',
'#3D9970',
'#2ECC40',
'#01FF70',
'#FFDC00',
'#FF851B',
'#FF4136',
'#85144b',
'#F012BE',
'#B10DC9',
'#111111',
'#AAAAAA',
'#DDDDDD',
]; ];
@:view("selected") var selectedView:SpriteView; @:view("selected") var selectedView:SpriteView;

View File

@@ -7,7 +7,6 @@ import promhx.Promise;
import ru.m.puzzlez.view.common.PresetView; import ru.m.puzzlez.view.common.PresetView;
@:singleton @:template class PreviewPopup extends PopupView<Dynamic> { @:singleton @:template class PreviewPopup extends PopupView<Dynamic> {
@:view("preview") var previewView:PresetView; @:view("preview") var previewView:PresetView;
public function new() { public function new() {

View File

@@ -10,7 +10,6 @@ using StringTools;
using hw.color.ColorUtil; using hw.color.ColorUtil;
@:style class ButtonSVGSkin implements ISkin<ButtonView> { @:style class ButtonSVGSkin implements ISkin<ButtonView> {
@:style(null) public var svg:String; @:style(null) public var svg:String;
@:style(0) public var color:Null<Color>; @:style(0) public var color:Null<Color>;
@:style(false) public var solid:Null<Bool>; @:style(false) public var solid:Null<Bool>;

View File

@@ -30,9 +30,7 @@ interface DataHelper<D, I> {
} }
class DefaultHelper implements DataHelper<Bytes, String> { class DefaultHelper implements DataHelper<Bytes, String> {
public function new() { public function new() {}
}
public function idKey(id:String):String { public function idKey(id:String):String {
return id; return id;

View File

@@ -30,7 +30,6 @@ typedef PackagesBundle = {
} }
class Updater { class Updater {
private static inline var TAG = "Update"; private static inline var TAG = "Update";
public var type(get, null):PackageType; public var type(get, null):PackageType;
@@ -61,11 +60,8 @@ class Updater {
} }
public function check():Promise<Null<PackageInfo>> { public function check():Promise<Null<PackageInfo>> {
return bundle.then((bundle:PackagesBundle) -> Lambda.find(bundle.packages, item -> ( return bundle.then((bundle:PackagesBundle) -> Lambda.find(bundle.packages,
item.platform == Device.platform && item -> (item.platform == Device.platform && item.type == type && version < Version.fromString(item.version))));
item.type == type &&
version < Version.fromString(item.version)
)));
} }
public function download():Promise<Bool> { public function download():Promise<Bool> {

View File

@@ -1,17 +1,12 @@
package ru.m.update; package ru.m.update;
abstract Version(Array<Int>) { abstract Version(Array<Int>) {
public function new(mayor:Int, minor:Int, patch:Int, snapshot:Bool = false) { public function new(mayor:Int, minor:Int, patch:Int, snapshot:Bool = false) {
this = [ this = [mayor, minor, patch, snapshot ? -1 : 0,];
mayor,
minor,
patch,
snapshot ? -1 : 0,
];
} }
@:arrayAccess public inline function get(key:Int) return this[key]; @:arrayAccess public inline function get(key:Int)
return this[key];
public function compare(other:Version):Int { public function compare(other:Version):Int {
if (other == null) { if (other == null) {
@@ -26,21 +21,19 @@ abstract Version(Array<Int>) {
return 0; return 0;
} }
@:op(A > B) static function gt(a:Version, b:Version):Bool return a.compare(b) > 0; @:op(A > B) static function gt(a:Version, b:Version):Bool
return a.compare(b) > 0;
@:op(A == B) static function eq(a:Version, b:Version):Bool return a.compare(b) == 0; @:op(A == B) static function eq(a:Version, b:Version):Bool
return a.compare(b) == 0;
@:op(A < B) static function lt(a:Version, b:Version):Bool return a.compare(b) < 0; @:op(A < B) static function lt(a:Version, b:Version):Bool
return a.compare(b) < 0;
@:from public static function fromString(value:String):Version { @:from public static function fromString(value:String):Version {
var r = ~/(\d+)\.(\d+)\.(\d+)(-SNAPSHOT)?/; var r = ~/(\d+)\.(\d+)\.(\d+)(-SNAPSHOT)?/;
return if (r.match(value)) { return if (r.match(value)) {
new Version( new Version(Std.parseInt(r.matched(1)), Std.parseInt(r.matched(2)), Std.parseInt(r.matched(3)), r.matched(4) != null);
Std.parseInt(r.matched(1)),
Std.parseInt(r.matched(2)),
Std.parseInt(r.matched(3)),
r.matched(4) != null
);
} else { } else {
new Version(0, 0, 0); new Version(0, 0, 0);
} }

View File

@@ -7,11 +7,11 @@ import ru.m.data.DataSource;
import ru.m.view.LoadingWrapper; import ru.m.view.LoadingWrapper;
@:template class DataList<T, V:View<Dynamic>> extends VGroupView { @:template class DataList<T, V:View<Dynamic>> extends VGroupView {
public var source:DataSource<T>; public var source:DataSource<T>;
public var page:Page; public var page:Page;
@:view public var list(default, null):DataView<T, V>; @:view public var list(default, null):DataView<T, V>;
@:view private var paginator:PaginatorView; @:view private var paginator:PaginatorView;
private var loading:LoadingWrapper; private var loading:LoadingWrapper;

View File

@@ -20,9 +20,7 @@ class LoadingWrapper {
private function set_promise(value:Promise<Dynamic>):Promise<Dynamic> { private function set_promise(value:Promise<Dynamic>):Promise<Dynamic> {
state = LOADING; state = LOADING;
value value.then(_ -> state = NONE).catchError(error -> state = ERROR(error));
.then(_ -> state = NONE)
.catchError(error -> state = ERROR(error));
return value; return value;
} }

View File

@@ -33,7 +33,6 @@ class PaginatorButtonView extends ToggleButtonView {
} }
class PaginatorView extends DataView<PaginatorAction, PaginatorButtonView> { class PaginatorView extends DataView<PaginatorAction, PaginatorButtonView> {
public var page(default, set):DataPage<Dynamic>; public var page(default, set):DataPage<Dynamic>;
public var onPageSelect(default, null):Signal<Int>; public var onPageSelect(default, null):Signal<Int>;

View File

@@ -9,12 +9,8 @@ import ru.m.puzzlez.proto.event.GameEvent;
import ru.m.puzzlez.proto.game.GameState; import ru.m.puzzlez.proto.game.GameState;
class EventUtil { class EventUtil {
public static function start(state:GameState, resume:Bool):GameEvent { public static function start(state:GameState, resume:Bool):GameEvent {
return new GameEvent().setStart(new GameStart() return new GameEvent().setStart(new GameStart().setState(state).setResume(resume));
.setState(state)
.setResume(resume)
);
} }
public static function complete():GameEvent { public static function complete():GameEvent {
@@ -26,11 +22,6 @@ class EventUtil {
} }
public static function change(part:Part):GameEvent { public static function change(part:Part):GameEvent {
return new GameEvent().setChange(new GameChange() return new GameEvent().setChange(new GameChange().setPartId(part.id).setLocation(part.location).setPosition(part.position).setPlayerId(part.playerId));
.setPartId(part.id)
.setLocation(part.location)
.setPosition(part.position)
.setPlayerId(part.playerId)
);
} }
} }

View File

@@ -64,7 +64,8 @@ class Game implements IGame {
for (part in partsById) { for (part in partsById) {
switch part.location { switch part.location {
case PartLocation.IMAGE: case PartLocation.IMAGE:
case _: return false; case _:
return false;
} }
} }
return true; return true;
@@ -91,8 +92,8 @@ class Game implements IGame {
} }
case Action.PUT: case Action.PUT:
part.playerId = null; part.playerId = null;
var target = new PointExt(state.preset.imageRect.x, state.preset.imageRect.y) var target = new PointExt(state.preset.imageRect.x,
.add(new PointExt(part.point.x * part.rect.width, part.point.y * part.rect.height)); state.preset.imageRect.y).add(new PointExt(part.point.x * part.rect.width, part.point.y * part.rect.height));
var d = distance(target, event.action.position); var d = distance(target, event.action.position);
if (d < 70) { if (d < 70) {
part.location = PartLocation.IMAGE; part.location = PartLocation.IMAGE;
@@ -110,9 +111,7 @@ class Game implements IGame {
} }
} }
public function stop():Void { public function stop():Void {}
}
public function dispose():Void { public function dispose():Void {
events.dispose(); events.dispose();

View File

@@ -15,7 +15,6 @@ import ru.m.puzzlez.proto.game.PartBounds;
import ru.m.puzzlez.proto.game.PartLocation; import ru.m.puzzlez.proto.game.PartLocation;
class BoundsMap { class BoundsMap {
private var grid:IntPoint; private var grid:IntPoint;
private var bounds:Array<PartBound>; private var bounds:Array<PartBound>;
@@ -65,7 +64,6 @@ class BoundsMap {
} }
class GameUtil { class GameUtil {
private static inline var MAX_SIZE = 20; private static inline var MAX_SIZE = 20;
private static function normilizeSize(size:Int, maxValue:Int = MAX_SIZE):Int { private static function normilizeSize(size:Int, maxValue:Int = MAX_SIZE):Int {
@@ -79,18 +77,12 @@ class GameUtil {
var offsetY = 200; var offsetY = 200;
var imageSize = 1024; var imageSize = 1024;
var s = width / height; var s = width / height;
var imageRect = new Rectangle() var imageRect = new Rectangle().setX(offsetX).setY(offsetY).setWidth(imageSize).setHeight(imageSize / s);
.setX(offsetX) var tableRect = new Rectangle().setX(0)
.setY(offsetY)
.setWidth(imageSize)
.setHeight(imageSize / s);
var tableRect = new Rectangle()
.setX(0)
.setY(0) .setY(0)
.setWidth(imageRect.width + offsetX * 2) .setWidth(imageRect.width + offsetX * 2)
.setHeight(imageRect.height + offsetY * 2); .setHeight(imageRect.height + offsetY * 2);
return new GamePreset() return new GamePreset().setImage(image)
.setImage(image)
.setGrid(new IntPoint().setX(width).setY(height)) .setGrid(new IntPoint().setX(width).setY(height))
.setTableRect(tableRect) .setTableRect(tableRect)
.setImageRect(imageRect); .setImageRect(imageRect);
@@ -104,8 +96,7 @@ class GameUtil {
var boundsMap = new BoundsMap(preset.grid); var boundsMap = new BoundsMap(preset.grid);
for (y in 0...preset.grid.y) { for (y in 0...preset.grid.y) {
for (x in 0...preset.grid.x) { for (x in 0...preset.grid.x) {
var bounds:PartBounds = new PartBounds() var bounds:PartBounds = new PartBounds().setLeft(boundsMap.getBound(x, y, LEFT))
.setLeft(boundsMap.getBound(x, y, LEFT))
.setRight(boundsMap.getBound(x, y, RIGHT)) .setRight(boundsMap.getBound(x, y, RIGHT))
.setTop(boundsMap.getBound(x, y, TOP)) .setTop(boundsMap.getBound(x, y, TOP))
.setBottom(boundsMap.getBound(x, y, BOTTOM)); .setBottom(boundsMap.getBound(x, y, BOTTOM));
@@ -123,28 +114,23 @@ class GameUtil {
} }
var id = (x << 16) + y; var id = (x << 16) + y;
var position = new Point().setX(position.x + x * partWidth).setY(position.y + y * partHeight); var position = new Point().setX(position.x + x * partWidth).setY(position.y + y * partHeight);
parts.push(new Part() parts.push(new Part().setId(id)
.setId(id)
.setPoint(new IntPoint().setX(x).setY(y)) .setPoint(new IntPoint().setX(x).setY(y))
.setLocation(PartLocation.TABLE) .setLocation(PartLocation.TABLE)
.setPosition(position) .setPosition(position)
.setBounds(bounds) .setBounds(bounds)
.setRect(new Rectangle().setX(0).setY(0).setWidth(partWidth).setHeight(partHeight)) .setRect(new Rectangle().setX(0).setY(0).setWidth(partWidth).setHeight(partHeight)));
);
} }
} }
return new GameState() return new GameState().setId(IdUtil.generate()).setStatus(GameStatus.READY).setPreset(preset).setParts(parts);
.setId(IdUtil.generate())
.setStatus(GameStatus.READY)
.setPreset(preset)
.setParts(parts);
} }
public static function calcProgress(state:GameState):{complete:Int, total:Int} { public static function calcProgress(state:GameState):{complete:Int, total:Int} {
var complete = 0; var complete = 0;
for (part in state.parts) { for (part in state.parts) {
switch part.location { switch part.location {
case PartLocation.IMAGE: complete++; case PartLocation.IMAGE:
complete++;
case _: case _:
} }
} }

View File

@@ -6,36 +6,25 @@ import flash.geom.Point as FlashPoint;
#end #end
abstract PointExt(Point) from Point to Point { abstract PointExt(Point) from Point to Point {
public function new(x:Float = 0, y:Float = 0) { public function new(x:Float = 0, y:Float = 0) {
this = new Point() this = new Point().setX(x).setY(y);
.setX(x)
.setY(y);
} }
public function clone():PointExt { public function clone():PointExt {
return new Point() return new Point().setX(this.x).setY(this.y);
.setX(this.x)
.setY(this.y);
} }
public function add(point:Point):PointExt { public function add(point:Point):PointExt {
return new Point() return new Point().setX(this.x + point.x).setY(this.y + point.y);
.setX(this.x + point.x)
.setY(this.y + point.y);
} }
public function subtract(point:Point):PointExt { public function subtract(point:Point):PointExt {
return new Point() return new Point().setX(this.x - point.x).setY(this.y - point.y);
.setX(this.x - point.x)
.setY(this.y - point.y);
} }
#if app #if app
@:from public static function fromFlashPoint(point:FlashPoint):PointExt { @:from public static function fromFlashPoint(point:FlashPoint):PointExt {
return new Point() return new Point().setX(point.x).setY(point.y);
.setX(point.x)
.setY(point.y);
} }
#end #end
} }

View File

@@ -11,11 +11,7 @@ abstract RectangleExt(Rectangle) from Rectangle to Rectangle {
public var size(get, never):Point; public var size(get, never):Point;
public function new(x:Float = 0, y:Float = 0, width:Float = 0, height:Float = 0) { public function new(x:Float = 0, y:Float = 0, width:Float = 0, height:Float = 0) {
this = new Rectangle() this = new Rectangle().setX(x).setY(y).setWidth(width).setHeight(height);
.setX(x)
.setY(y)
.setWidth(width)
.setHeight(height);
} }
private function get_left():Float { private function get_left():Float {
@@ -35,16 +31,10 @@ abstract RectangleExt(Rectangle) from Rectangle to Rectangle {
} }
private function get_size():Point { private function get_size():Point {
return new Point() return new Point().setX(this.width).setY(this.height);
.setX(this.width)
.setY(this.height);
} }
public function clone():Rectangle { public function clone():Rectangle {
return new Rectangle() return new Rectangle().setX(this.x).setY(this.y).setWidth(this.width).setHeight(this.height);
.setX(this.x)
.setY(this.y)
.setWidth(this.width)
.setHeight(this.height);
} }
} }

View File

@@ -66,12 +66,10 @@ class GameSession extends ProtoSession<Response, Request> {
private function list(list:GameListRequest):Void { private function list(list:GameListRequest):Void {
var games = Lambda.array(gamesById); var games = Lambda.array(gamesById);
var pageGames = games.slice(list.page * list.count, list.count); var pageGames = games.slice(list.page * list.count, list.count);
send(new Response().setList(new GameListResponse() send(new Response().setList(new GameListResponse().setPage(list.page)
.setPage(list.page)
.setCount(list.count) .setCount(list.count)
.setTotal(games.length) .setTotal(games.length)
.setGames(pageGames.map(game -> game.state)) .setGames(pageGames.map(game -> game.state))));
));
} }
private function create(create:GameCreateRequest):Void { private function create(create:GameCreateRequest):Void {

View File

@@ -13,7 +13,6 @@ typedef ClientMessage<M> = {
} }
class PuzzlezServer extends ThreadServer<GameSession, Message> { class PuzzlezServer extends ThreadServer<GameSession, Message> {
private static inline var TAG = 'Server'; private static inline var TAG = 'Server';
override public function clientConnected(socket:Socket):GameSession { override public function clientConnected(socket:Socket):GameSession {

View File

@@ -1,11 +1,10 @@
const gulp = require('gulp'); const gulp = require("gulp");
const fs = require('fs'); const fs = require("fs");
const fse = require('fs-extra'); const fse = require("fs-extra");
const path = require('path'); const path = require("path");
const through = require('through2'); const through = require("through2");
class Package { class Package {
constructor(platform, type, version, versionInt) { constructor(platform, type, version, versionInt) {
this.platform = platform; this.platform = platform;
this.type = type; this.type = type;
@@ -14,16 +13,16 @@ class Package {
} }
get key() { get key() {
return [this.platform, this.type].join(':'); return [this.platform, this.type].join(":");
} }
static getPlatform(filename) { static getPlatform(filename) {
for (const [platform, r] of [ for (const [platform, r] of [
['android', /^.*?\.apk$/], ["android", /^.*?\.apk$/],
['linux', /^.*?\.deb$/], ["linux", /^.*?\.deb$/],
['linux', /^.*?linux\.tar\.gz$/], ["linux", /^.*?linux\.tar\.gz$/],
['windows', /^.*?win\.zip$/], ["windows", /^.*?win\.zip$/],
['windows', /^.*?\.exe$/], ["windows", /^.*?\.exe$/],
]) { ]) {
if (r.test(filename)) { if (r.test(filename)) {
return platform; return platform;
@@ -34,11 +33,11 @@ class Package {
static getType(filename) { static getType(filename) {
for (const [type, r] of [ for (const [type, r] of [
['apk', /^.*?\.apk$/], ["apk", /^.*?\.apk$/],
['deb', /^.*?\.deb$/], ["deb", /^.*?\.deb$/],
['archive', /^.*?\.tar\.gz$/], ["archive", /^.*?\.tar\.gz$/],
['archive', /^.*?\.zip$/], ["archive", /^.*?\.zip$/],
['exe', /^.*?\.exe$/], ["exe", /^.*?\.exe$/],
]) { ]) {
if (r.test(filename)) { if (r.test(filename)) {
return type; return type;
@@ -50,7 +49,10 @@ class Package {
static getVersion(filename) { static getVersion(filename) {
const m = /(\d+)\.(\d+)\.(\d+)/.exec(filename); const m = /(\d+)\.(\d+)\.(\d+)/.exec(filename);
if (m) { if (m) {
return [m[0], parseInt(m[1]) * 10000 + parseInt(m[2]) * 100 + parseInt(m[3])]; return [
m[0],
parseInt(m[1]) * 10000 + parseInt(m[2]) * 100 + parseInt(m[3]),
];
} }
return null; return null;
} }
@@ -66,28 +68,37 @@ class Package {
} }
} }
module.exports = (name, version, publishDir, publishUrl) => function publish(cb) { module.exports = (name, version, publishDir, publishUrl) =>
function publish(cb) {
const packages = {}; const packages = {};
fse.ensureDirSync(publishDir); fse.ensureDirSync(publishDir);
return gulp.series([ return gulp.series([
function copy() { function copy() {
return gulp.src('target/app/@(android|archive|debian|installer)/*') return gulp
.pipe(through.obj(function (file, enc, cb) { .src("target/app/@(android|archive|debian|installer)/*")
.pipe(
through.obj(function (file, enc, cb) {
const pack = Package.parseFilename(file.path); const pack = Package.parseFilename(file.path);
if (pack) { if (pack) {
this.push(file); this.push(file);
} }
cb(null); cb(null);
})) })
.pipe(gulp.dest(publishDir)) )
.pipe(gulp.dest(publishDir));
}, },
function generate() { function generate() {
return gulp.src(`${publishDir}/*/*`) return gulp
.pipe(through.obj(function (file, enc, cb) { .src(`${publishDir}/*/*`)
const basepath = file.path.replace(file.base + path.sep, ''); .pipe(
through.obj(function (file, enc, cb) {
const basepath = file.path.replace(file.base + path.sep, "");
const pack = Package.parseFilename(file.path); const pack = Package.parseFilename(file.path);
if (pack) { if (pack) {
if (!packages[pack.key] || packages[pack.key].versionInt < pack.versionInt) { if (
!packages[pack.key] ||
packages[pack.key].versionInt < pack.versionInt
) {
packages[pack.key] = { packages[pack.key] = {
platform: pack.platform, platform: pack.platform,
type: pack.type, type: pack.type,
@@ -96,18 +107,27 @@ module.exports = (name, version, publishDir, publishUrl) => function publish(cb)
path: basepath, path: basepath,
filename: basepath.split(path.sep).pop(), filename: basepath.split(path.sep).pop(),
url: `${publishUrl}/${basepath.replace(path.sep, "/")}`, url: `${publishUrl}/${basepath.replace(path.sep, "/")}`,
} };
} }
} }
cb(null); cb(null);
})).on('end', function () { })
fs.writeFileSync(path.join(publishDir, 'packages.json'), JSON.stringify({ )
.on("end", function () {
fs.writeFileSync(
path.join(publishDir, "packages.json"),
JSON.stringify(
{
name: name, name: name,
version: version, version: version,
packages: Object.values(packages), packages: Object.values(packages),
}, null, 4)); },
}) null,
} 4
)
);
});
},
])(cb); ])(cb);
}; };