|
|
@@ -1,3 +1,4 @@
|
|
|
+import 'package:common_pub/model/control_point.dart';
|
|
|
import 'package:common_pub/model/distance.dart';
|
|
|
import 'package:common_pub/model/pace.dart';
|
|
|
import 'package:common_pub/model/position.dart';
|
|
|
@@ -8,17 +9,16 @@ import '../logger.dart';
|
|
|
import '../service/api.dart' as pb;
|
|
|
import 'package:fixnum/fixnum.dart';
|
|
|
|
|
|
-
|
|
|
typedef MapId = Int64;
|
|
|
|
|
|
-class Flag{
|
|
|
+class Flag {
|
|
|
Flag(this.value);
|
|
|
int value;
|
|
|
- Color get color=>Color(value);
|
|
|
+ Color get color => Color(value);
|
|
|
|
|
|
@override
|
|
|
bool operator ==(Object other) {
|
|
|
- if(other is Flag){
|
|
|
+ if (other is Flag) {
|
|
|
return value == other.value;
|
|
|
}
|
|
|
return false;
|
|
|
@@ -30,20 +30,19 @@ class Flag{
|
|
|
static final red = Flag(0xffff0000);
|
|
|
static final yellow = Flag(0xffffcb00);
|
|
|
static final blue = Flag(0xff00a0ff);
|
|
|
- static List<Flag> get values =>[red, yellow, blue];
|
|
|
+ static List<Flag> get values => [red, yellow, blue];
|
|
|
}
|
|
|
|
|
|
-class ActiveInfo{
|
|
|
+class ActiveInfo {
|
|
|
var id = 0;
|
|
|
var name = '';
|
|
|
var cpAllCount = 0;
|
|
|
var userList = <UserInfo>[];
|
|
|
final isHide = false.obs;
|
|
|
|
|
|
-
|
|
|
- UserInfo? getUserById(int id){
|
|
|
- for (final one in userList){
|
|
|
- if(one.gameInfo.userId==id){
|
|
|
+ UserInfo? getUserById(int id) {
|
|
|
+ for (final one in userList) {
|
|
|
+ if (one.gameInfo.userId == id) {
|
|
|
return one;
|
|
|
}
|
|
|
}
|
|
|
@@ -51,18 +50,18 @@ class ActiveInfo{
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- Future<UserInfo> newUserInfo(pb.ToOrienteerInGameInfo info)async{
|
|
|
- final r =await pb.ApiService.to.stub.toUserInActionBasicQuery(pb.ToUserInActionBasicQueryRequest(
|
|
|
- actId: id,
|
|
|
- userId: info.userId
|
|
|
- ));
|
|
|
+ Future<UserInfo> newUserInfo(pb.ToOrienteerInGameInfo info) async {
|
|
|
+ final r = await pb.ApiService.to.stub.toUserInActionBasicQuery(
|
|
|
+ pb.ToUserInActionBasicQueryRequest(actId: id, userId: info.userId));
|
|
|
|
|
|
- return UserInfo()
|
|
|
+ final user = UserInfo()
|
|
|
..routeInfo = r.courseBaseInfo
|
|
|
- ..userInfo = r.baseInfo
|
|
|
- ..gameInfo = info
|
|
|
- ;
|
|
|
+ ..userInfo = r.baseInfo;
|
|
|
+ await user.setGameInfo(info);
|
|
|
+
|
|
|
+ return user;
|
|
|
}
|
|
|
+
|
|
|
Future<void> update(pb.ToActionInfo info) async {
|
|
|
final newUserList = <UserInfo>[];
|
|
|
|
|
|
@@ -72,8 +71,7 @@ class ActiveInfo{
|
|
|
if (oUser != null) {
|
|
|
user = oUser;
|
|
|
await user.update(nUser);
|
|
|
-
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
user = await newUserInfo(nUser);
|
|
|
}
|
|
|
|
|
|
@@ -81,20 +79,19 @@ class ActiveInfo{
|
|
|
}
|
|
|
userList = newUserList;
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
-extension ActiveInfoExt on pb.ToActionInfo{
|
|
|
+
|
|
|
+extension ActiveInfoExt on pb.ToActionInfo {
|
|
|
Future<ActiveInfo> into() async {
|
|
|
- final info = await pb.ApiService.to.stub.toActionBasicQuery(
|
|
|
- pb.IdRequest(id: Int64(actId)));
|
|
|
+ final info = await pb.ApiService.to.stub
|
|
|
+ .toActionBasicQuery(pb.IdRequest(id: Int64(actId)));
|
|
|
|
|
|
final out = ActiveInfo()
|
|
|
..id = actId
|
|
|
..name = info.actName
|
|
|
..cpAllCount = info.totalControlNum;
|
|
|
|
|
|
-
|
|
|
- for(final one in userList){
|
|
|
+ for (final one in userList) {
|
|
|
out.userList.add(await out.newUserInfo(one));
|
|
|
}
|
|
|
|
|
|
@@ -102,27 +99,31 @@ extension ActiveInfoExt on pb.ToActionInfo{
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-class UserInfo{
|
|
|
+class UserInfo {
|
|
|
final isHide = false.obs;
|
|
|
String get name => userInfo.name;
|
|
|
String get routeName => routeInfo.courseName;
|
|
|
- Pace get pace => Pace.perKm( gameInfo.gpsInfo.pace.seconds);
|
|
|
- Duration get duration => DateTime.now().difference(gameInfo.gameSaveInfo.startAt.toModel());
|
|
|
+ Pace get pace => Pace.perKm(gameInfo.gpsInfo.pace.seconds);
|
|
|
+ Duration get duration =>
|
|
|
+ DateTime.now().difference(gameInfo.gameSaveInfo.startAt.toModel());
|
|
|
Distance get distance => Distance(m: gameInfo.gpsInfo.distance.toDouble());
|
|
|
var gameInfo = pb.ToOrienteerInGameInfo();
|
|
|
var routeInfo = pb.CourseBaseInfo();
|
|
|
var userInfo = pb.OrienteerBaseInfo();
|
|
|
var trace = <TracePoint>[].obs;
|
|
|
var flag = Flag.red.obs;
|
|
|
- DateTime? get startAt => gameInfo.gameSaveInfo.hasStartAt()?gameInfo.gameSaveInfo.startAt.toModel(): null;
|
|
|
+ DateTime? get startAt => gameInfo.gameSaveInfo.hasStartAt()
|
|
|
+ ? gameInfo.gameSaveInfo.startAt.toModel()
|
|
|
+ : null;
|
|
|
+ var cpList = <ControlPoint>[];
|
|
|
+ ControlPoint? nextWant;
|
|
|
|
|
|
Distance get nextDistance {
|
|
|
final one = nextWant;
|
|
|
- if(one!= null){
|
|
|
- final p1 = Position(longitude: one.ciPosition.longitude, latitude: one.ciPosition.latitude);
|
|
|
+ if (one != null) {
|
|
|
+ final p1 = one.position;
|
|
|
final p22 = gameInfo.gpsInfo.gameGpsInfos.lastOrNull;
|
|
|
- if(p22 != null){
|
|
|
+ if (p22 != null) {
|
|
|
final p2 = Position(longitude: p22.longitude, latitude: p22.latitude);
|
|
|
return p1.distance(p2);
|
|
|
}
|
|
|
@@ -130,78 +131,84 @@ class UserInfo{
|
|
|
return const Distance(m: 1000);
|
|
|
}
|
|
|
|
|
|
- pb.ToControlPoint? get nextWant{
|
|
|
- final no = gameInfo.gameSaveInfo.nextControlPoint.orderNo;
|
|
|
- if(no < routeInfo.controlPointSortedList.length){
|
|
|
- final out = routeInfo.controlPointSortedList[no];
|
|
|
- out.orderNo=no;
|
|
|
- return out;
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
- }
|
|
|
- String get nextCPSN{
|
|
|
- var str = '开始';
|
|
|
- final next = nextWant;
|
|
|
- final wantList = routeInfo.controlPointSortedList;
|
|
|
- if(next != null){
|
|
|
- if(next.orderNo == wantList.length-1){
|
|
|
- str = '结束';
|
|
|
- }else if(next.orderNo > 0){
|
|
|
- str = '${next.orderNo}号';
|
|
|
- }
|
|
|
- }
|
|
|
- return str;
|
|
|
+ String get nextCPSN {
|
|
|
+ return nextWant?.snString ?? '';
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- Future<void> update(pb.ToOrienteerInGameInfo info)async{
|
|
|
+ Future<void> update(pb.ToOrienteerInGameInfo info) async {
|
|
|
final map = MapWatchService.instance;
|
|
|
|
|
|
-
|
|
|
- gameInfo = info;
|
|
|
+ await setGameInfo(info);
|
|
|
final indexMap = <int, TracePoint>{};
|
|
|
|
|
|
- for (final one in trace){
|
|
|
- indexMap[one.ts.inMilliseconds]=one;
|
|
|
+ for (final one in trace) {
|
|
|
+ indexMap[one.ts.inMilliseconds] = one;
|
|
|
}
|
|
|
|
|
|
- for(final one in info.gpsInfo.gameGpsInfos){
|
|
|
+ for (final one in info.gpsInfo.gameGpsInfos) {
|
|
|
final t = one.gpsTime.toModel();
|
|
|
final startAt = gameInfo.gameSaveInfo.startAt.toModel();
|
|
|
final ts = t.difference(startAt);
|
|
|
- if(ts.inMilliseconds>0 && !indexMap.containsKey(ts.inMilliseconds)){
|
|
|
+ if (ts.inMilliseconds > 0 && !indexMap.containsKey(ts.inMilliseconds)) {
|
|
|
final pos = one.toModel();
|
|
|
trace.add(TracePoint()
|
|
|
- ..ts = ts
|
|
|
- ..position=pos
|
|
|
- );
|
|
|
+ ..ts = ts
|
|
|
+ ..position = pos);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- if(map!.plugMap.isInitFinish){
|
|
|
- for (final one in trace){
|
|
|
- if(one.onMap==Offset.zero){
|
|
|
+ if (map!.plugMap.isInitFinish) {
|
|
|
+ for (final one in trace) {
|
|
|
+ if (one.onMap == Offset.zero) {
|
|
|
one.onMap = await map.plugMap.gameMap.worldToPixel(one.position);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
-}
|
|
|
|
|
|
+ Future<void> setGameInfo(pb.ToOrienteerInGameInfo info) async {
|
|
|
+ final map = MapWatchService.instance;
|
|
|
+ gameInfo = info;
|
|
|
+ cpList.clear();
|
|
|
+ final cpMap = <int, ControlPoint>{};
|
|
|
+ for (var (i, src) in routeInfo.controlPointSortedList.indexed) {
|
|
|
+ final one = src.toModel()..sn = i.toString();
|
|
|
+ if (map != null) {
|
|
|
+ one.onMap = await map.plugMap.gameMap.worldToPixel(one.position);
|
|
|
+ }
|
|
|
+
|
|
|
+ cpList.add(one);
|
|
|
+ cpMap[one.intId.toInt()] = one;
|
|
|
+ }
|
|
|
+ if (cpList.isNotEmpty) {
|
|
|
+ cpList.first.isStart = true;
|
|
|
+ cpList.last.isFinish = true;
|
|
|
+ }
|
|
|
+ for (var cp in gameInfo.gameSaveInfo.checkedSortedList) {
|
|
|
+ cpMap[cp.controlPointId]!.isSuccess = cp.isCheckSuccess;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (var cp in cpList) {
|
|
|
+ if (!cp.isSuccess) {
|
|
|
+ cp.isNext = true;
|
|
|
+ nextWant = cp;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
|
|
|
-class MapWatchService extends PlugController{
|
|
|
+class MapWatchService extends PlugController {
|
|
|
static final Rx<MapWatchService?> _instance = Rx(null);
|
|
|
static MapWatchService? get instance => _instance.value;
|
|
|
|
|
|
- static Future<void> setMapById(MapId id)async{
|
|
|
- final info = await pb.ApiService.to.stub.toMapDetailV2(pb.IdRequest()
|
|
|
- ..id = id);
|
|
|
+ static Future<void> setMapById(MapId id) async {
|
|
|
+ final info =
|
|
|
+ await pb.ApiService.to.stub.toMapDetailV2(pb.IdRequest()..id = id);
|
|
|
|
|
|
- final thisInstance = MapWatchService(
|
|
|
- id: id)
|
|
|
+ final thisInstance = MapWatchService(id: id)
|
|
|
..name = info.mapName
|
|
|
- ..plugMap.gameMap = info.zipImage.toGameMap() ;
|
|
|
+ ..plugMap.gameMap = info.zipImage.toGameMap();
|
|
|
|
|
|
thisInstance.addPlugs([thisInstance.plugMap]);
|
|
|
|
|
|
@@ -210,39 +217,39 @@ class MapWatchService extends PlugController{
|
|
|
thisInstance.workFlushData();
|
|
|
}
|
|
|
|
|
|
- Future<void> workFlushData()async{
|
|
|
- while(isActive){
|
|
|
- try{
|
|
|
+ Future<void> workFlushData() async {
|
|
|
+ while (isActive) {
|
|
|
+ try {
|
|
|
await flushData();
|
|
|
- }catch(e){
|
|
|
+ } catch (e) {
|
|
|
error(e);
|
|
|
}
|
|
|
await 1.seconds.delay();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- ActiveInfo? getActiveById(int id){
|
|
|
- for (final one in activeList){
|
|
|
- if(one.id==id){
|
|
|
+ ActiveInfo? getActiveById(int id) {
|
|
|
+ for (final one in activeList) {
|
|
|
+ if (one.id == id) {
|
|
|
return one;
|
|
|
}
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
|
|
|
|
- Future<void> flushData()async{
|
|
|
- final r = await pb.ApiService.to.stub.toUserDetailQueryV2(pb.ToUserDetailQueryRequestV2(
|
|
|
- mapId: id.toInt()));
|
|
|
+ Future<void> flushData() async {
|
|
|
+ final r = await pb.ApiService.to.stub
|
|
|
+ .toUserDetailQueryV2(pb.ToUserDetailQueryRequestV2(mapId: id.toInt()));
|
|
|
|
|
|
final newList = <ActiveInfo>[];
|
|
|
|
|
|
- for(final one in r.list){
|
|
|
+ for (final one in r.list) {
|
|
|
late ActiveInfo info;
|
|
|
final old = getActiveById(one.actId);
|
|
|
- if(old != null){
|
|
|
+ if (old != null) {
|
|
|
info = old;
|
|
|
await info.update(one);
|
|
|
- }else{
|
|
|
+ } else {
|
|
|
info = await one.into();
|
|
|
}
|
|
|
newList.add(info);
|
|
|
@@ -251,10 +258,9 @@ class MapWatchService extends PlugController{
|
|
|
activeList.value = newList;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
MapWatchService({required this.id});
|
|
|
final MapId id;
|
|
|
- String name= '';
|
|
|
+ String name = '';
|
|
|
final plugMap = PlugMap();
|
|
|
final activeList = <ActiveInfo>[].obs;
|
|
|
-}
|
|
|
+}
|