map_watch.dart 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. import 'package:common_pub/logger.dart';
  2. import 'package:common_pub/service/controller.dart';
  3. import 'package:common_pub/ui/map_view/map_view.dart';
  4. import 'package:common_pub/ui/map_view/view_map_trace.dart';
  5. import 'package:track_common/model.dart';
  6. class Flag {
  7. Flag(this.value);
  8. int value;
  9. Color get color => Color(value);
  10. @override
  11. bool operator ==(Object other) {
  12. if (other is Flag) {
  13. return value == other.value;
  14. }
  15. return false;
  16. }
  17. @override
  18. int get hashCode => value.hashCode;
  19. static final red = Flag(0xffff0000);
  20. static final yellow = Flag(0xffffcb00);
  21. static final blue = Flag(0xff00a0ff);
  22. static List<Flag> get values => [red, yellow, blue];
  23. }
  24. class PlayerInfo {
  25. var id = 0;
  26. var name = '';
  27. var routeName = '';
  28. var cpWantList = <ControlPoint>[];
  29. }
  30. class PlayerOnMap extends AppGameState {
  31. var info = PlayerInfo();
  32. int get id => info.id;
  33. String get name => info.name;
  34. List<ControlPoint> get cpList => cpListChecked;
  35. final isHide = false.obs;
  36. var trace = <TracePoint>[].obs;
  37. var flag = Flag.red.obs;
  38. String get routeName => info.routeName;
  39. int heartRatePercent = 0;
  40. Pace pace = Pace.perKm(99.hours);
  41. var distance = 0.km;
  42. List<HeartRate> get hrInfo => hrHistory;
  43. List<Position> get positionList => positionHistory;
  44. @override
  45. Duration get duration => DateTime.now().difference(startAt);
  46. Distance get nextDistance {
  47. final one = cpNextWant;
  48. if (one != null) {
  49. final p1 = one.position;
  50. final p22 = positionList.lastOrNull;
  51. if (p22 != null) {
  52. return p1.distance(p22);
  53. }
  54. }
  55. return const Distance(m: 1000);
  56. }
  57. String get nextCPSN {
  58. return cpNextWant?.snString ?? '';
  59. }
  60. }
  61. class EventOnMap {
  62. var info = EventInfo();
  63. var userList = <PlayerOnMap>[];
  64. int get id => info.id;
  65. String get name => info.name;
  66. int get cpAllCount => info.cpAllCount;
  67. final isHide = false.obs;
  68. PlayerOnMap? getUserById(int id) {
  69. for (final one in userList) {
  70. if (one.id == id) {
  71. return one;
  72. }
  73. }
  74. return null;
  75. }
  76. }
  77. abstract class MapWatchService extends GetxService {
  78. final Rx<MapWatch?> _instance = Rx(null);
  79. MapWatch? get instance => _instance.value;
  80. @protected
  81. Future<MapWatch> newInstanceByMap(MapInfo info);
  82. Future<void> setMap(MapInfo mapInfo) async {
  83. final thisInstance = await newInstanceByMap(mapInfo);
  84. thisInstance.addPlugs([thisInstance.plugMap]);
  85. _instance.value = thisInstance;
  86. thisInstance.init();
  87. thisInstance.workFlushData();
  88. }
  89. }
  90. abstract class MapWatch extends PlugController {
  91. Future<void> workFlushData() async {
  92. while (isActive) {
  93. try {
  94. await flushData();
  95. } catch (e) {
  96. error(e);
  97. }
  98. await 1.seconds.delay();
  99. }
  100. }
  101. EventOnMap? getEventById(int id) {
  102. for (final one in eventList) {
  103. if (one.id == id) {
  104. return one;
  105. }
  106. }
  107. return null;
  108. }
  109. MapWatch({required this.id});
  110. final int id;
  111. String name = '';
  112. final plugMap = PlugMap();
  113. final eventList = <EventOnMap>[].obs;
  114. Future<void> flushData() async {
  115. final list = await getEventList(id);
  116. final newList = <EventOnMap>[];
  117. for (final one in list) {
  118. late EventOnMap event;
  119. final old = getEventById(one.id);
  120. if (old != null) {
  121. event = old;
  122. await updateEvent(event, one);
  123. } else {
  124. event = await initEvent(one);
  125. }
  126. newList.add(event);
  127. }
  128. eventList.value = newList;
  129. }
  130. Future<EventOnMap> initEvent(EventOnMap event) async {
  131. final id = event.id;
  132. final info = await getEventInfo(id);
  133. event.info = info;
  134. event.info.id = id;
  135. for (var p in event.userList) {
  136. await initPlayer(event, p);
  137. }
  138. return event;
  139. }
  140. Future<PlayerOnMap> initPlayer(EventOnMap event, PlayerOnMap player) async {
  141. final userId = player.id;
  142. final info = await getPlayerInfo(event.id, userId);
  143. player.info = info;
  144. player.info.id = userId;
  145. player.cpListWant = info.cpWantList;
  146. return player;
  147. }
  148. Future<void> updateEvent(EventOnMap old, EventOnMap newOne) async {
  149. final newUserList = <PlayerOnMap>[];
  150. for (final nUser in newOne.userList) {
  151. late PlayerOnMap user;
  152. final oUser = old.getUserById(nUser.id);
  153. if (oUser != null) {
  154. user = oUser;
  155. await updatePlayer(user, nUser);
  156. } else {
  157. user = await initPlayer(old, nUser);
  158. }
  159. user.updateState();
  160. await playerUpdateMap(user);
  161. newUserList.add(user);
  162. }
  163. old.userList = newUserList;
  164. }
  165. Future<void> playerUpdateMap(PlayerOnMap info) async {
  166. for (var one in info.cpList) {
  167. one.onMap = await plugMap.gameMap.worldToPixel(one.position);
  168. }
  169. }
  170. Future<void> updatePlayer(PlayerOnMap old, PlayerOnMap newUser) async {
  171. final indexMap = <int, TracePoint>{};
  172. for (final one in old.trace) {
  173. indexMap[one.ts.inMilliseconds] = one;
  174. }
  175. for (final one in newUser.positionList) {
  176. final t = one.timestamp;
  177. final startAt = old.startAt;
  178. final ts = t.difference(startAt);
  179. if (ts.inMilliseconds > 0 && !indexMap.containsKey(ts.inMilliseconds)) {
  180. final pos = one;
  181. final oneTrace = TracePoint()
  182. ..ts = ts
  183. ..position = pos;
  184. if (plugMap.isInitFinish) {
  185. oneTrace.onMap =
  186. await plugMap.gameMap.worldToPixel(oneTrace.position);
  187. }
  188. old.trace.add(oneTrace);
  189. }
  190. }
  191. }
  192. @protected
  193. Future<List<EventOnMap>> getEventList(int mapId);
  194. @protected
  195. Future<EventInfo> getEventInfo(int id);
  196. @protected
  197. Future<PlayerInfo> getPlayerInfo(int eventId, int userId);
  198. }