[common] add DesktopConnection
This commit is contained in:
@@ -79,7 +79,7 @@ class Init {
|
||||
#elseif html5
|
||||
connection = new ru.m.connect.js.JsConnection<Request, Response>(host, 5000, Response);
|
||||
#else
|
||||
connection = new ru.m.connect.fake.FakeConnection<Request, Response>(Response);
|
||||
connection = new ru.m.connect.desktop.DesktopConnection<Request, Response>(host, 5000, Response);
|
||||
#end
|
||||
networkManager = new NetworkManager();
|
||||
}
|
||||
|
||||
@@ -146,5 +146,7 @@ class Style {
|
||||
registerButton("close", "times-circle-solid.svg");
|
||||
registerButton("next", "arrow-alt-circle-right-solid.svg");
|
||||
registerButton("start", "play-circle-solid.svg");
|
||||
registerButton("login", "sign-in-solid.svg");
|
||||
registerButton("logout", "sign-out-solid.svg");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,70 +1,80 @@
|
||||
package ru.m.tankz.network;
|
||||
|
||||
import ru.m.tankz.storage.MultiplayerStorage;
|
||||
import haxework.storage.IStorage;
|
||||
import haxework.signal.Signal;
|
||||
import ru.m.tankz.proto.pack.GameRequest;
|
||||
import ru.m.tankz.proto.core.GameProto;
|
||||
import ru.m.tankz.proto.pack.StartGameRequest;
|
||||
import ru.m.tankz.proto.game.GameChangeProto;
|
||||
import ru.m.tankz.proto.game.GameActionTypeProto;
|
||||
import ru.m.tankz.proto.pack.GameUpdateRequest;
|
||||
import ru.m.connect.IConnection;
|
||||
import ru.m.tankz.control.Control;
|
||||
import ru.m.tankz.proto.core.GameInfoProto;
|
||||
import ru.m.tankz.proto.game.GameActionTypeProto;
|
||||
import ru.m.tankz.proto.game.GameChangeProto;
|
||||
import ru.m.tankz.proto.pack.CreateGameRequest;
|
||||
import ru.m.tankz.proto.pack.GameUpdateRequest;
|
||||
import ru.m.tankz.proto.pack.JoinGameRequest;
|
||||
import ru.m.tankz.proto.pack.LeaveGameRequest;
|
||||
import ru.m.tankz.proto.pack.CreateGameRequest;
|
||||
import ru.m.connect.IConnection;
|
||||
import ru.m.tankz.proto.core.GameInfoProto;
|
||||
import ru.m.tankz.proto.pack.ListGameRequest;
|
||||
import ru.m.tankz.proto.pack.LoginRequest;
|
||||
import ru.m.tankz.proto.pack.LogoutRequest;
|
||||
import ru.m.tankz.proto.pack.Request;
|
||||
import ru.m.tankz.proto.pack.Response;
|
||||
import ru.m.tankz.proto.pack.StartGameRequest;
|
||||
import ru.m.tankz.storage.MultiplayerStorage;
|
||||
|
||||
typedef ClientConnection = IConnection<Request, Response>;
|
||||
|
||||
enum ConnectionState {
|
||||
OFFLINE;
|
||||
CONNECT;
|
||||
CONNECTED;
|
||||
LOGIN;
|
||||
ONLINE(user:User);
|
||||
ERROR(error:Dynamic);
|
||||
}
|
||||
|
||||
class NetworkManager {
|
||||
|
||||
public var state(default, null):String;
|
||||
public var stateSignal:Signal<String>;
|
||||
public var state(default, null):ConnectionState;
|
||||
public var stateSignal:Signal<ConnectionState>;
|
||||
public var listGameSignal:Signal<Array<GameInfoProto>>;
|
||||
public var gameSignal:Signal<GameInfoProto>;
|
||||
public var gameUpdateSignal:Signal<Array<GameChangeProto>>;
|
||||
public var user(default, null):User;
|
||||
public var game(default, set):NetworkGame;
|
||||
|
||||
@:provide private var connection:ClientConnection;
|
||||
@:provide private var storage:MultiplayerStorage;
|
||||
|
||||
public function new() {
|
||||
stateSignal = new Signal<String>();
|
||||
listGameSignal = new Signal<Array<GameInfoProto>>();
|
||||
gameSignal = new Signal<GameInfoProto>();
|
||||
gameUpdateSignal = new Signal<Array<GameChangeProto>>();
|
||||
updateState('offline');
|
||||
stateSignal = new Signal();
|
||||
listGameSignal = new Signal();
|
||||
gameSignal = new Signal();
|
||||
gameUpdateSignal = new Signal();
|
||||
updateState(OFFLINE);
|
||||
connection.handler.connect(onConnectionEvent);
|
||||
connection.receiveHandler.connect(onResponse);
|
||||
user = storage.user;
|
||||
if (user == null) {
|
||||
user = {name: 'User', uuid: null};
|
||||
var user = storage.user;
|
||||
if (user != null) {
|
||||
login(user.name, user.uuid);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateState(value:String):Void {
|
||||
private function updateState(value:ConnectionState):Void {
|
||||
state = value;
|
||||
stateSignal.emit(value);
|
||||
}
|
||||
|
||||
public function login(name:String):Void {
|
||||
user.name = name;
|
||||
updateState('connect...');
|
||||
public function login(name:String, uuid:String = null):Void {
|
||||
updateState(CONNECT);
|
||||
connection.connect().then(function(c:ClientConnection) {
|
||||
updateState('login...');
|
||||
updateState(LOGIN);
|
||||
c.send(new Request().setLogin(
|
||||
new LoginRequest()
|
||||
.setUuid(user.uuid)
|
||||
.setName(user.name)
|
||||
.setUuid(uuid)
|
||||
.setName(name)
|
||||
));
|
||||
}).catchError(function(_) {});
|
||||
}).catchError(function(error) {
|
||||
updateState(ERROR(error));
|
||||
});
|
||||
}
|
||||
|
||||
public function logout():Void {
|
||||
connection.send(new Request().setLogout(new LogoutRequest()));
|
||||
}
|
||||
|
||||
public function listGame():Void {
|
||||
@@ -108,30 +118,30 @@ class NetworkManager {
|
||||
}
|
||||
|
||||
private function onConnectionEvent(event:ConnectionEvent):Void {
|
||||
updateState(switch (event) {
|
||||
case ConnectionEvent.CONNECTED:
|
||||
updateState(switch event {
|
||||
case CONNECTED:
|
||||
L.d('Network', '$event');
|
||||
'connected';
|
||||
case ConnectionEvent.DISCONNECTED:
|
||||
CONNECTED;
|
||||
case DISCONNECTED:
|
||||
L.d('Network', '$event');
|
||||
'offline';
|
||||
case ConnectionEvent.ERROR(error):
|
||||
OFFLINE;
|
||||
case ERROR(error):
|
||||
L.e('Network', '$error', error);
|
||||
'error';
|
||||
ERROR(error);
|
||||
});
|
||||
}
|
||||
|
||||
private function onResponse(packet:Response):Void {
|
||||
if (packet.hasLogin()) {
|
||||
user = {
|
||||
var user = {
|
||||
uuid: packet.login.user.uuid,
|
||||
name: packet.login.user.name,
|
||||
};
|
||||
storage.user = user;
|
||||
updateState('online');
|
||||
updateState(ONLINE(user));
|
||||
} else if (packet.hasLogout()) {
|
||||
user = null;
|
||||
updateState('connected');
|
||||
storage.user = null;
|
||||
updateState(CONNECTED);
|
||||
} else if (packet.hasListGame()) {
|
||||
listGameSignal.emit(packet.listGame.games);
|
||||
} else if (packet.hasCreateGame()) {
|
||||
@@ -145,13 +155,7 @@ class NetworkManager {
|
||||
} else if (packet.hasUpdateGame()) {
|
||||
gameUpdateSignal.emit(packet.updateGame.changes);
|
||||
} else if (packet.hasGame()) {
|
||||
game.load(packet.game.game);
|
||||
//game.load(packet.game.game);
|
||||
}
|
||||
}
|
||||
|
||||
private function set_game(value:NetworkGame):NetworkGame {
|
||||
this.game = value;
|
||||
connection.send(new Request().setGame(new GameRequest()));
|
||||
return this.game;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,25 +1,69 @@
|
||||
package ru.m.tankz.view;
|
||||
|
||||
import haxework.view.ButtonView;
|
||||
import haxework.view.LabelView;
|
||||
import haxework.view.frame.FrameSwitcher;
|
||||
import haxework.view.VGroupView;
|
||||
import ru.m.tankz.game.GameState;
|
||||
import ru.m.tankz.network.NetworkManager;
|
||||
import ru.m.tankz.Type.GameType;
|
||||
import ru.m.tankz.view.popup.FontPopup;
|
||||
import ru.m.tankz.view.popup.LoginPopup;
|
||||
|
||||
@:template class StartFrame extends VGroupView {
|
||||
|
||||
public static var ID(default, never):String = "start";
|
||||
|
||||
@:view var username:LabelView;
|
||||
@:view("login") var loginButton:ButtonView;
|
||||
@:view("logout") var logoutButton:ButtonView;
|
||||
@:view("network") var networkButton:ButtonView;
|
||||
|
||||
@:provide var state:GameState;
|
||||
@:provide var switcher:FrameSwitcher;
|
||||
@:provide var network:NetworkManager;
|
||||
|
||||
private var fontPopup:FontPopup;
|
||||
|
||||
public function onShow():Void {
|
||||
onConnectionState(network.state);
|
||||
network.stateSignal.connect(onConnectionState);
|
||||
}
|
||||
|
||||
public function onHide():Void {
|
||||
network.stateSignal.disconnect(onConnectionState);
|
||||
}
|
||||
|
||||
private function onConnectionState(state:ConnectionState):Void {
|
||||
trace("state", state);
|
||||
setUser(switch state {
|
||||
case ONLINE(user): user;
|
||||
case _: null;
|
||||
});
|
||||
}
|
||||
|
||||
private function setUser(value:User):Void {
|
||||
username.text = value == null ? "" : value.name;
|
||||
loginButton.visible = value == null;
|
||||
logoutButton.visible = value != null;
|
||||
networkButton.disabled = value == null;
|
||||
}
|
||||
|
||||
private function startGame(type:GameType):Void {
|
||||
state = new GameState(type);
|
||||
switcher.change(LevelFrame.ID);
|
||||
}
|
||||
|
||||
private function login():Void {
|
||||
LoginPopup.instance.show().then(function(user:User):Void {
|
||||
L.d("Login", 'user: $user');
|
||||
});
|
||||
}
|
||||
|
||||
private function logout():Void {
|
||||
network.logout();
|
||||
}
|
||||
|
||||
private function choiceFont():Void {
|
||||
if (fontPopup == null) {
|
||||
fontPopup = new FontPopup();
|
||||
|
||||
@@ -1,40 +1,63 @@
|
||||
---
|
||||
views:
|
||||
- $type: haxework.view.VGroupView
|
||||
skinId: container
|
||||
layout.margin: 10
|
||||
views:
|
||||
- $type: haxework.view.LabelView
|
||||
text: Tank'z
|
||||
skinId: font
|
||||
fontSize: 100
|
||||
geometry.margin.bottom: 30
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('classic')
|
||||
text: Classic
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('dota')
|
||||
text: DotA
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('death')
|
||||
text: DeathMatch
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:switcher.change('record')
|
||||
text: Records
|
||||
- $type: haxework.view.HGroupView
|
||||
skinId: panel
|
||||
views:
|
||||
- id: settings
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button.settings
|
||||
+onPress: $code:switcher.change('settings')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.width: 100%
|
||||
- $type: haxework.view.LabelView
|
||||
geometry.padding: [20, 5]
|
||||
skinId: text.box
|
||||
text: $r:text:version
|
||||
- $type: haxework.view.VGroupView
|
||||
skinId: container
|
||||
layout.margin: 10
|
||||
views:
|
||||
- $type: haxework.view.LabelView
|
||||
text: Tank'z
|
||||
skinId: font
|
||||
fontSize: 100
|
||||
geometry.margin.bottom: 30
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('classic')
|
||||
text: Classic
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('dota')
|
||||
text: DotA
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:startGame('death')
|
||||
text: DeathMatch
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
+onPress: $code:switcher.change('record')
|
||||
text: Records
|
||||
- id: network
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button
|
||||
# +onPress: $code:switcher.change('record')
|
||||
text: Network
|
||||
disabled: true
|
||||
- $type: haxework.view.HGroupView
|
||||
skinId: panel
|
||||
views:
|
||||
- id: settings
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button.settings
|
||||
+onPress: $code:switcher.change('settings')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.width: 100%
|
||||
- id: username
|
||||
$type: haxework.view.LabelView
|
||||
skinId: text
|
||||
geometry.margin.right: 10
|
||||
- id: login
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button.login
|
||||
+onPress: $code:login()
|
||||
- id: logout
|
||||
$type: haxework.view.ButtonView
|
||||
skinId: button.logout
|
||||
+onPress: $code:logout()
|
||||
visible: false
|
||||
- $type: haxework.view.LabelView
|
||||
geometry.hAlign: right
|
||||
geometry.vAlign: top
|
||||
geometry.padding: [20, 5]
|
||||
geometry.position: absolute
|
||||
geometry.margin: [0, 20, 20, 0]
|
||||
skinId: text.box
|
||||
text: $r:text:version
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
---
|
||||
view:
|
||||
$type: haxework.view.VGroupView
|
||||
geometry.size.width: 400
|
||||
geometry.size.height: 80%
|
||||
geometry.padding: 10
|
||||
geometry.hAlign: center
|
||||
geometry.vAlign: middle
|
||||
skinId: dark
|
||||
views:
|
||||
- id: fonts
|
||||
$type: haxework.view.list.VListView
|
||||
geometry.size.stretch: true
|
||||
factory: $this:fontViewFactory
|
||||
+onItemSelect: $code:function(item) close(item.data)
|
||||
scroll:
|
||||
$type: haxework.view.list.VScrollBarView
|
||||
skinId: scroll.vertical
|
||||
- $type: haxework.view.HGroupView
|
||||
geometry.size.width: 100%
|
||||
geometry.margin.top: 10
|
||||
layout.hAlign: right
|
||||
views:
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button.simple
|
||||
text: Cancel
|
||||
+onPress: $code:reject('cancel')
|
||||
$type: haxework.view.VGroupView
|
||||
geometry.size.width: 400
|
||||
geometry.size.height: 80%
|
||||
geometry.padding: 10
|
||||
geometry.hAlign: center
|
||||
geometry.vAlign: middle
|
||||
skinId: dark
|
||||
views:
|
||||
- id: fonts
|
||||
$type: haxework.view.list.VListView
|
||||
geometry.size.stretch: true
|
||||
factory: $this:fontViewFactory
|
||||
+onItemSelect: $code:function(item) close(item.data)
|
||||
scroll:
|
||||
$type: haxework.view.list.VScrollBarView
|
||||
skinId: scroll.vertical
|
||||
- $type: haxework.view.HGroupView
|
||||
geometry.size.width: 100%
|
||||
geometry.margin.top: 10
|
||||
layout.hAlign: right
|
||||
views:
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button.simple
|
||||
text: Cancel
|
||||
+onPress: $code:reject('cancel')
|
||||
|
||||
@@ -2,34 +2,34 @@
|
||||
layout.hAlign: center
|
||||
layout.vAlign: middle
|
||||
view:
|
||||
$type: haxework.view.VGroupView
|
||||
layout.hAlign: center
|
||||
geometry.size.width: 400
|
||||
geometry.size.height: 400
|
||||
skinId: window
|
||||
views:
|
||||
- $type: haxework.view.HGroupView
|
||||
geometry.size.width: 100%
|
||||
geometry.padding: 10
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- id: name
|
||||
$type: haxework.view.LabelView
|
||||
geometry.size.width: 100%
|
||||
geometry.margin.left: 10
|
||||
layout.hAlign: left
|
||||
skinId: text
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: window.close
|
||||
+onPress: $code:reject('close')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.height: 100%
|
||||
- id: presets
|
||||
$type: haxework.view.DataView
|
||||
factory: $this:presetViewFactory
|
||||
+onDataSelect: $this:onPresetSelect
|
||||
layout:
|
||||
$type: haxework.view.layout.HorizontalLayout
|
||||
hAlign: center
|
||||
margin: 5
|
||||
skinId: panel
|
||||
$type: haxework.view.VGroupView
|
||||
layout.hAlign: center
|
||||
geometry.size.width: 400
|
||||
geometry.size.height: 400
|
||||
skinId: window
|
||||
views:
|
||||
- $type: haxework.view.HGroupView
|
||||
geometry.size.width: 100%
|
||||
geometry.padding: 10
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- id: name
|
||||
$type: haxework.view.LabelView
|
||||
geometry.size.width: 100%
|
||||
geometry.margin.left: 10
|
||||
layout.hAlign: left
|
||||
skinId: text
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: window.close
|
||||
+onPress: $code:reject('close')
|
||||
- $type: haxework.view.SpriteView
|
||||
geometry.size.height: 100%
|
||||
- id: presets
|
||||
$type: haxework.view.DataView
|
||||
factory: $this:presetViewFactory
|
||||
+onDataSelect: $this:onPresetSelect
|
||||
layout:
|
||||
$type: haxework.view.layout.HorizontalLayout
|
||||
hAlign: center
|
||||
margin: 5
|
||||
skinId: panel
|
||||
|
||||
47
src/client/haxe/ru/m/tankz/view/popup/LoginPopup.hx
Normal file
47
src/client/haxe/ru/m/tankz/view/popup/LoginPopup.hx
Normal file
@@ -0,0 +1,47 @@
|
||||
package ru.m.tankz.view.popup;
|
||||
|
||||
import haxework.log.BaseLogger.LoggerUtil;
|
||||
import haxework.view.InputView;
|
||||
import haxework.view.popup.PopupView;
|
||||
import haxework.view.TextView;
|
||||
import ru.m.tankz.network.NetworkManager;
|
||||
|
||||
@:template class LoginPopup extends PopupView<User> {
|
||||
|
||||
@:view var username:InputView;
|
||||
@:view var password:InputView;
|
||||
@:view var error:TextView;
|
||||
|
||||
@:provide static var network:NetworkManager;
|
||||
|
||||
override private function onShow():Void {
|
||||
super.onShow();
|
||||
network.stateSignal.connect(onStateChange);
|
||||
}
|
||||
|
||||
override private function onClose():Void {
|
||||
super.onClose();
|
||||
network.stateSignal.disconnect(onStateChange);
|
||||
}
|
||||
|
||||
private function onStateChange(state:ConnectionState):Void {
|
||||
switch state {
|
||||
case ONLINE(user): close(user);
|
||||
case ERROR(error): this.error.text = LoggerUtil.printError(error);
|
||||
case _: this.error.text = null;
|
||||
}
|
||||
}
|
||||
|
||||
private function submit():Void {
|
||||
network.login(username.text);
|
||||
}
|
||||
|
||||
public static var instance(get, null):LoginPopup;
|
||||
|
||||
private static function get_instance():LoginPopup {
|
||||
if (instance == null) {
|
||||
instance = new LoginPopup();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
64
src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml
Normal file
64
src/client/haxe/ru/m/tankz/view/popup/LoginPopup.yaml
Normal file
@@ -0,0 +1,64 @@
|
||||
---
|
||||
layout.hAlign: center
|
||||
layout.vAlign: middle
|
||||
view:
|
||||
$type: haxework.view.VGroupView
|
||||
layout.hAlign: center
|
||||
geometry.size.width: 400
|
||||
# geometry.size.height: 400
|
||||
skinId: window
|
||||
views:
|
||||
- $type: haxework.view.HGroupView
|
||||
geometry.size.width: 100%
|
||||
geometry.padding: 10
|
||||
layout.vAlign: middle
|
||||
views:
|
||||
- id: name
|
||||
$type: haxework.view.LabelView
|
||||
geometry.size.width: 100%
|
||||
geometry.margin.left: 10
|
||||
layout.hAlign: left
|
||||
skinId: text
|
||||
text: Login
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: window.close
|
||||
+onPress: $code:reject('close')
|
||||
- $type: haxework.view.VGroupView
|
||||
geometry.size.width: 100%
|
||||
# geometry.size.stretch: true
|
||||
geometry.padding: 20
|
||||
layout.margin: 5
|
||||
views:
|
||||
- $type: haxework.view.LabelView
|
||||
geometry.size.width: 100%
|
||||
skinId: text
|
||||
text: Username
|
||||
- id: username
|
||||
$type: haxework.view.InputView
|
||||
geometry.size.width: 100%
|
||||
geometry.size.height: 28
|
||||
skinId: text.box
|
||||
- $type: haxework.view.LabelView
|
||||
geometry.size.width: 100%
|
||||
skinId: text
|
||||
text: Password
|
||||
- id: password
|
||||
$type: haxework.view.InputView
|
||||
textField.displayAsPassword: true
|
||||
geometry.size.width: 100%
|
||||
geometry.size.height: 28
|
||||
skinId: text.box
|
||||
- id: error
|
||||
$type: haxework.view.TextView
|
||||
geometry.size.width: 100%
|
||||
skinId: text
|
||||
fill: false
|
||||
- $type: haxework.view.HGroupView
|
||||
layout.hAlign: center
|
||||
layout.margin: 5
|
||||
skinId: panel
|
||||
views:
|
||||
- $type: haxework.view.ButtonView
|
||||
skinId: button.simple
|
||||
text: Submit
|
||||
+onPress: $code:submit()
|
||||
Reference in New Issue
Block a user