1354 lines
51 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using Assets.Scenes.Ride.Scripts;
using Assets.Scripts;
using Assets.Scripts.Apis.Models;
using Assets.Scripts.Ble.Service;
using Assets.Scripts.Devices;
using Assets.Scripts.Devices.Ant;
using Assets.Scripts.Devices.Ant.Interfaces;
using Assets.Scripts.Devices.Ble;
using Assets.Scripts.Devices.Ble.Characteristic;
using Assets.Scripts.Devices.Ble.Devices;
using Assets.Scripts.Devices.Ble.Interfaces;
using ChartAndGraph;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using UnityEngine;
using UnityEngine.Android;
using UnityEngine.UI;
using static RowerTaskPanel;
public class RowerHomeScript : PFUIPanel
{
private class TempRowerCalc
{
public int power { get; set; }
public ushort pace { get; set; }
public uint rate { get; set; }
public int heartRate { get; set; }
public int energy { get; set; }
public int distance { get; set; }
public int strokeCount { get; set; }
}
/// <summary>
/// 划船机数据
/// </summary>
private IRowerCommonData RowerData
{
get
{
return Rower != null ? (C2RowerData.IsEnabled == true ? (IRowerCommonData)(Rower.c2RowerData) : (IRowerCommonData)(Rower.rowerData)) : null;
//var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected) && d.Sensor == SensorType.Rower);
//if (device != null)
//{
// return ((IRowerDevice)device).rowerData;
//}
//return null;
}
}
protected override void OnDestroy()
{
Debug.Log("銷毀");
if (RowerData != null)
{
RowerData.PullChanged -= PaintPullCurve;
RowerData.StartEvent -= StartFunc;
RowerData.RowerResChanged -= ResChanged;
}
C2RowerData.EnableChanged -= ModeChanged;
}
private IRowerDevice Rower
{
get
{
var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => d.State == DeviceState.Connected && d.Sensor == SensorType.Rower);
if (device != null)
{
return (IRowerDevice)device;
}
return null;
}
}
/// <summary>
/// 心率数据
/// </summary>
private int? HeartRate
{
get
{
var device = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType.HeartRate);
if (device != null)
{
return ((IHeartRateDevice)device).HeartRate;
}
return null;
}
}
GameObject btnStart;
Transform left, bottom, mid, rmydata;
Image leftImage;
Image rightImage;
float timer = 1.0f;
List<DoubleVector2> pullList, historyPullList;
public Dictionary<object, Sprite> spriteDict, spriteDict2;
List<string> records;
List<TempRowerCalc> values;
DateTime startTime;
DateTime? createTime;
double Kj = 0;
int seconds = 0;
bool isPause = false;
public RowerType rowerType = null;
/// <summary>
/// 计算停止的秒数如果超过5秒除了累加值都变成--这些值记录为0提示用户如果超过90秒将直接保存数据
/// 如果5-90秒有拉力则继续滑行
/// 如果超过90秒都没有拉力则直接保存
/// </summary>
int stopSeconds = 0;
uint totalDistance = 0;
Transform slider;
RowerGraphChartFeed rowerGraphChartFeed { get; set; }
RowerGraphChartFeed graphChartFeed { get; set; }
protected override void Start()
{
var rect = transform.GetComponent<RectTransform>();
rect.offsetMax = Vector2.zero;
rect.offsetMin = Vector2.zero;
rowerGraphChartFeed = mid.Find("GraphChart").GetComponent<RowerGraphChartFeed>();
graphChartFeed = transform.Find("Rower/Modes/Scroll/M2/MyData/GraphChart").GetComponent<RowerGraphChartFeed>();
}
Transform M1 { get; set; }
protected override void Awake()
{
Id = Guid.NewGuid().ToString();
rowerType = new RowerType() { type = 1, value = 500 };
spriteDict = new Dictionary<object, Sprite>()
{
{"Start",Resources.Load<Sprite>("Images/RowerNew/ICON_continue_44") },
{"Untagged",Resources.Load<Sprite>("Images/RowerNew/ICON_pause_44")},
{0,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0001") },
{1,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0002") },
{2,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0003") },
{3,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0004") },
{4,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0005") },
{5,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0006") },
{6,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0007") },
{7,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0008") },
{8,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0009") },
{9,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0010") },
{10,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0011") },
{11,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0012") },
{12,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0013") },
{13,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0014") },
{14,Resources.Load<Sprite>("Images/Rower/序列帧/划船机0015") },
};
spriteDict2 = new Dictionary<object, Sprite>()
{
{0,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0001") },
{1,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0002") },
{2,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0003") },
{3,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0004") },
{4,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0005") },
{5,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0006") },
{6,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0007") },
{7,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0008") },
{8,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0009") },
{9,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0010") },
{10,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0011") },
{11,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0012") },
{12,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0013") },
{13,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0014") },
{14,Resources.Load<Sprite>("Images/RowerNew/序列帧/划船机0015") },
};
rowerMultiModeScript = GetComponent<RowerMultiModeScript>();
GetComponent<RectTransform>().localScale = Vector3.one;
GetComponent<RectTransform>().localPosition = Vector3.zero;
records = new List<string>();
values = new List<TempRowerCalc>();
pullList = new List<DoubleVector2>();
historyPullList = new List<DoubleVector2>();
//mainNav.ShowExit();
M1 = transform.Find("Rower/Modes/Scroll/M1");
left = transform.Find("Rower/Modes/Scroll/M1/Left");
bottom = transform.Find("Rower/Bottom");
KMText = bottom.Find("KM/Value").GetComponent<Text>();
TimeText = bottom.Find("Time/Value").GetComponent<Text>();
BPMText = bottom.Find("BPM/Value").GetComponent<Text>();
mid = transform.Find("Rower/Modes/Scroll/M1/Mid");
rmydata = transform.Find("Rower/Modes/Scroll/M2/MyData");
slider = transform.Find("ResBar/PFUISlider");
WText = mid.Find("W/Value").GetComponent<Text>();
rmyWText = rmydata.Find("W/Value").GetComponent<Text>();
FiveText = bottom.Find("500/Value").GetComponent<Text>();
MSText = bottom.Find("MS/Value").GetComponent<Text>();
ExpectedText = bottom.Find("Expected/Value").GetComponent<Text>();
TimesText = left.Find("Times/Value").GetComponent<Text>();
Caloriestext = left.Find("Calories/Value").GetComponent<Text>();
rmyCaloriestext = rmydata.Find("Calories/Value").GetComponent<Text>();
AvgForceText = mid.Find("AvgForce/Value").GetComponent<Text>();
rmyAvgForceText = rmydata.Find("AvgForce/Value").GetComponent<Text>();
PeakForceText = mid.Find("PeakForce/Value").GetComponent<Text>();
rmyPeakForceText = rmydata.Find("PeakForce/Value").GetComponent<Text>();
UIManager.AddEvent(transform.Find("ResBar/BtnAdd").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
if (RowerData != null)
{
slider.GetComponent<PFUISlider>().SetValue((RowerData.ResistanceLevel + 1 - 50) / 300f);
}
});
UIManager.AddEvent(transform.Find("ResBar/BtnSub").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
if (RowerData != null)
{
slider.GetComponent<PFUISlider>().SetValue((RowerData.ResistanceLevel - 1 - 50) / 300f);
}
});
slider.GetComponent<PFUISlider>().valueHandler = (a) => 50 + a * 300;
slider.GetComponent<PFUISlider>().SetValueChanged(r =>
{
var v = (ushort)Math.Round((r * 300));
print("设置阻力" + v);
StartCoroutine(SetResistanceLevel(v));
});
//transform.Find("Ready/DeviceStatus").gameObject.SetActive(!flag);
//transform.Find("Ready/DeviceStatusConnect").gameObject.SetActive(flag);
UIManager.AddEvent(transform.Find("Ready/DeviceStatus").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
if (checkRowing()) return;
UIManager.ShowRowerDevicePanel();
});
UIManager.AddEvent(transform.Find("Ready/DeviceStatusConnect").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
if (checkRowing()) return;
UIManager.ShowRowerDevicePanel();
});
UIManager.AddEvent(transform.Find("Stopped/DeviceStatus").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
//if (checkRowing()) return;
UIManager.ShowRowerDevicePanel();
});
UIManager.AddEvent(transform.Find("Stopped/DeviceStatusConnect").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
//if (checkRowing()) return;
UIManager.ShowRowerDevicePanel();
});
//手机版tab
#if UNITY_ANDROID || UNITY_IOS
var nav = transform.Find("MainNav-mobile").GetComponent<NewMainNav>();
var c1 = new NewMainNav.CustomButton(Resources.Load<Sprite>("Images/RowerNew/ICON_create_44"), () =>
{
//UIManager.ShowRowerWelldone("31C5A37D-6ADD-4EE1-B6DA-5AA2F9949C4B", Init);
//return;
//UIManager.ShowRowerWelldone("C0F81E83-120B-4A2C-AD0E-8BC1B8EB3E74", Init);
//return;
if (checkRowing()) return;
if (C2RowerData.IsEnabled == true && C2RowerData.rowerType != null) return;
UIManager.ShowRowerTaskPanel(type =>
{
rowerType = type;
HandleSelectType();
}, rowerType);
}, false);
var c2 = new NewMainNav.CustomButton(Resources.Load<Sprite>("Images/RowerNew/记录"), () =>
{
if (checkRowing()) return;
UIManager.ShowResultListPanel();
}, false);
btnStart = transform.Find("MainNav-mobile/Custom2").gameObject;
//var c3 = new NewMainNav.CustomButton(Resources.Load<Sprite>("Images/RowerNew/ICON_mode_44"), () =>
//{
// ReturnHome();
//}, false);
//隐藏骑行
nav.SetButtonActive(new List<int> { 3, 7 }, null, c1, null, c2, false);
newNav = nav;
#endif
UIManager.AddEvent(transform.Find("Stopped/Confirm/BtnSave").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
transform.Find("Stopped").gameObject.SetActive(false);
HandleSaveDirect();
});
UIManager.AddEvent(transform.Find("Stopped/Confirm/BtnDrop").gameObject, UnityEngine.EventSystems.EventTriggerType.PointerClick, b =>
{
Discard();
});
if (RowerData != null)
{
RowerData.PullChanged -= PaintPullCurve;
RowerData.PullChanged += PaintPullCurve;
RowerData.StartEvent -= StartFunc;
RowerData.StartEvent += StartFunc;
}
rowerType = new RowerType { type = 1, value = 500 };
HandleSelectType();
Init();
isFirstReset = false;
}
IEnumerator SetResistanceLevel(ushort res)
{
yield return new WaitForSeconds(0.1f);
if (Rower != null)
{
Rower.SetResistanceLevel(res);
}
}
RowerResultModel reRowData = null;
public void ReRow(RowerResultModel r)
{
this.reRowData = r;
if (r != null && r.Type.HasValue)
{
rowerType = new RowerType { type = r.Type.Value, value = (float)r.TypeValue.Value };
if (Rower != null)
{
Rower.Reset();
}
//RowerPanel/Rower/Bottom/Expected/Title
//var dw = rowerType.type == 1 ? $"{rowerType.value}M" : $"{(rowerType.value / 60).ToString("#0.00")}Min";
//bottom.Find("Expected/Title").GetComponent<Text>().text = $"EST\n/ {dw}";
var dw = "";
if (rowerType.type == 0)
{
dw = $"\nM/ 30Min";
}
else if (rowerType.type == 2)
{
dw = $"\nM";
}
bottom.Find("Expected/Title").GetComponent<Text>().text = $"{App.GetLocalString("EST")}{dw}";
}
}
private void DeleteCacheDir()
{
//删除实时记录
try
{
var dir = $"{PFConstants.RowerRecordCacheFolder}/{App.CurrentUser.Id}/";
if (Directory.Exists(dir))
{
Helper.DelectDir(dir);
//Directory.Delete(dir, true);
}
}
catch (Exception e)
{
Debug.LogError(e.ToString());
}
}
private void Discard()
{
openTimer = false;
if (Application.internetReachability == NetworkReachability.NotReachable)
{
transform.Find("Stopped").gameObject.SetActive(true);
Utils.showToast(null, App.GetLocalString("Please check the network status!"));
return;
}
transform.Find("Stopped").gameObject.SetActive(false);
isPause = true;
DeleteCacheDir();
historyTime = 0;
if (C2RowerData.IsEnabled == true)
{
Utils.showToast(null, "Press \"Menu\" to save.", int.MaxValue, stopFunc: () => C2RowerData.isReadyStatus, endCallback: Init);
}
else
{
Init();
}
}
private void HandleSelectType()
{
if (Rower != null)
{
Rower.Reset();
}
reRowData = null;
//RowerPanel/Rower/Bottom/Expected/Title
//var dw = rowerType.type == 1 ? $"{rowerType.value}M" : $"{(rowerType.value / 60).ToString("#0.00")}Min";
//bottom.Find("Expected/Title").GetComponent<Text>().text = $"EST\n/ {dw}";
var dw = "";
if (rowerType.type == 0)
{
dw = $"\nM/ 30Min";
}
else if (rowerType.type == 2)
{
dw = $"\nM";
}
bottom.Find("Expected/Title").GetComponent<Text>().text = $"{App.GetLocalString("EST")}{dw}";
Init();
//Utils.showToast(null, "请滑动划船机并开始", isLowest: true, type: 1);
}
protected override void OnDisable()
{
base.OnDisable();
//App.MainDeviceAdapter.StopScan();
}
public override void Show()
{
base.Show();
//var mainNav = this.transform.Find("MainNav").GetComponent<MainNav>();
//mainNav.ShowRowerTab();
//App.MainDeviceAdapter.StartScan();
transform.MyDOFade();
//Debug.Log("140,开始扫描");
//App.MainDeviceAdapter.StartScan();
Init();
CheckLocalData();
//transform.Find("Left/Rower").GetComponent<RowerAnimation>().StartAnimation();
}
void Disconnect()
{
foreach (var d in App.MainDeviceAdapter.GetDevices())
{
if ((d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && (d.Sensor == SensorType.Rower || d.Sensor == SensorType.HeartRate))
{
d.Disconnect();
}
}
App.MainDeviceAdapter.StopScan();
}
void HandleDiscardDirect()
{
openTimer = false;
isPause = true;
Debug.Log(RowerData);
btnStart.GetComponent<Image>().sprite = spriteDict["Start"];
btnStart.tag = "Start";
Init();
}
void HandleSaveDirect()
{
openTimer = false;
isPause = true;
btnStart.GetComponent<Image>().sprite = spriteDict["Start"];
btnStart.tag = "Start";
transform.Find("Stopped").gameObject.SetActive(false);
//Utils.showToast()
Action f = () =>
{
reRowData = null;
if (tempRecordData == null)
{
if (Save()) Init();
}
else
{
if (SaveFunc(tempRecordData.model, tempRecordData.files)) Init();
}
};
createTime = UIManager.Now.GetDateTime();
if (C2RowerData.IsEnabled == true)
{
Utils.showToast(null, "Press \"Menu\" to save.", int.MaxValue, stopFunc: () => C2RowerData.isReadyStatus, endCallback: f);
}
else
{
f.Invoke();
}
}
private string Id { get; set; }
int truelyTime = 0;
private void StartFunc(object sender, EventArgs e)
{
var rowdata = (IRowerCommonData)sender;
if (rowdata != RowerData)
return;
Debug.Log($"开始了:{openTimer}");
if (UIManager.Instance.confirm != null && UIManager.Instance.confirm.IsActive())
{
print("当前有弹窗");
return;
}
if (openTimer) return;
Id = Guid.NewGuid().ToString();
if (transform.parent.parent.Find("ModalPanel/RowerWelldone(Clone)") && transform.parent.parent.Find("ModalPanel/RowerWelldone(Clone)").gameObject.activeInHierarchy)
{
return;
}
//设定一个标准 如果满足条件不让他开始
if (C2RowerData.IsEnabled && RowerData != null && RowerData.ElapsedTime >= 5)
{
Utils.showToast(null, "Press \"Menu\" to save.", stopFunc: () => RowerData.ElapsedTime < 5);
return;
}
if (!isPause)
{
}
if (!openTimer)
{
startTime = UIManager.Now.GetDateTime();
createTime = null;
truelyTime = historyTime;
//TimerTicks();
openTimer = true;
timer = 1.0f;
}
transform.Find("Ready").gameObject.SetActive(false);
//if (UIManager.Instance.RowerWelldone)
//{
// UIManager.Instance.RowerWelldone.CloseModal();
//}
btnStart.GetComponent<Image>().sprite = spriteDict["Untagged"];
btnStart.tag = "Untagged";
}
private bool SaveFunc(RowerRecordModel model, List<string> files)
{
if (Application.internetReachability == NetworkReachability.NotReachable)
{
transform.Find("Stopped").gameObject.SetActive(true);
Utils.showToast(null, App.GetLocalString("Please check the network status!"));
tempRecordData = new TempRecordData(model, files);
return false;
}
var res = ConfigHelper.rowerApi.Add(model, files);
if (res.result)
{
UIManager.ShowRowerWelldone(model.Id, Init);
try
{
if (File.Exists(files[0]))
{
File.Delete(files[0]);
}
DeleteCacheDir();
}
catch (Exception ex)
{
Debug.LogError(ex);
}
}
else
{
Utils.showToast(null, res.errMsg);
}
tempRecordData = null;
return true;
}
public class TempRecordData
{
public RowerRecordModel model;
public List<string> files;
public TempRecordData(RowerRecordModel model, List<string> files)
{
this.model = model;
this.files = files;
}
}
TempRecordData tempRecordData;
private bool Save(string shadowids = null)
{
RowerRecordModel model = new RowerRecordModel();
model.Ticks = records.Count;
var bleDevice = App.MainDeviceAdapter.GetDevices().FirstOrDefault(d => (d.State == DeviceState.Connected || d.State == DeviceState.Connecting) && d.Sensor == SensorType.Rower) as BleDevice;
if (bleDevice != null)
{
model.ManufacturerName = bleDevice.Name + " " + bleDevice.Network + " " + bleDevice.Sensor;
model.DeviceNumber = $"{ bleDevice.Address },{ bleDevice.Sensor }";
}
model.Id = Id;//Guid.NewGuid().ToString();
model.Weight = App.CurrentUser.Weight;
if (string.IsNullOrEmpty(shadowids))
{
model.StartTime = startTime;
}
else
{
model.StartTime = createTime.Value.AddSeconds(-values.Count);
}
model.CreateTime = createTime.Value;
Debug.Log(values.Count);
if (values.Count > 0)
{
model.MaxPower = values.Max(x => x.power);
if (values.Count(x => x.pace > 0) > 0)
{
model.MaxPace = values.Where(x => x.pace > 0).Min(x => x.pace);
model.AvgPace = values.Where(x => x.pace > 0).Average(x => x.pace);
}
model.MaxRate = values.Max(x => x.rate);
model.MaxHeartRate = values.Max(x => x.heartRate);
model.AvgPower = values.Average(x => x.power);
model.AvgRate = values.Average(x => x.rate);
model.AvgHeartRate = (int)values.Average(x => x.heartRate);
model.StrokeCount = (ushort)values.Max(x=>x.strokeCount);
model.TotalDistance = (ushort)values.Max(x => x.distance);
model.Kj = values.Max(x => x.energy);
}
model.TotalTime = records.Count;
model.Type = rowerType.type == 0 ? (int?)null : rowerType.type;
model.TypeValue = rowerType.value == 0 ? (float?)null : rowerType.value;
model.ShadowIds = string.IsNullOrEmpty(shadowids)?string.Join(",",GetComponent<RowerMultiModeScript>().shadowList.Select(x=>x.Nid)):shadowids;
var path = PFConstants.RowerRecordFolder + "/" + model.Id;
Helper.CreateDirectoryIfNotExsit(path);
var files = new List<string>();
try
{
var fname = path + "/" + model.Id + ".txt";
using (var fs = new FileInfo(fname).OpenWrite())
{
var stream = new StreamWriter(fs);
stream.BaseStream.Seek(0, SeekOrigin.End);
print("结果数" + records.Count);
stream.Write(string.Join("\r\n", records));
//foreach (var item in records)
//{
// stream.Write(item + "\r\n");
//}
stream.Flush();
stream.Close();
files.Add(fname);
}
}
catch (Exception ex)
{
Helper.DelectDir(path);
Debug.Log(ex.Message);
}
return SaveFunc(model, files);
//Disconnect();
}
private void Init()
{
pointCount = 0;
print("初始化");
if (Rower != null)
{
Rower.Reset();
}
//if (RowerData != null)
//{
// RowerData.Reset();
//}
GetComponent<RowerMultiModeScript>().GetShadowList(rowerType, reRowData);
btnStart.tag = "Start";
btnStart.GetComponent<Image>().sprite = spriteDict["Start"];
left.Find("Rower").GetComponent<Image>().sprite = spriteDict[0];
leftImage = left.Find("LeftImage/Value").GetComponent<Image>();
rightImage = left.Find("RightImage/Value").GetComponent<Image>();
leftImage.fillAmount = 0;
rightImage.fillAmount = 0;
TimesText.text = "---";
Caloriestext.text = "---";
rmyCaloriestext.text = "---";
pullList.Clear();
historyPullList.Clear();
//SetChartData(pullList, historyPullList);
//mid.Find("GraphChart").GetComponent<RowerGraphChartFeed>().SetData(pullList);
openTimer = false;
if (rowerType.type == 0)
{
TimeText.text = "---";
KMText.text = "---";
}
else
{
if (rowerType.type == 1)
{
TimeText.text = "---";
KMText.text = $"{rowerType.value}";
}
else
{
TimeText.text = TimeSpan.FromSeconds(rowerType.value).ToPFString();
KMText.text = "---";
}
}
WText.text = "---";
rmyWText.text = "---";
FiveText.text = "---";
MSText.text = "---";
//bottom.Find("MS/AvgValue").GetComponent<Text>().text = "---";
bottom.Find("BPM/Value").GetComponent<Text>().text = "---";
ExpectedText.text = "---";
bottom.Find("Expected/Title").GetComponent<Text>().text = bottom.Find("Expected/Title").GetComponent<Text>().text.Replace("EST",App.GetLocalString("EST"));
AvgForceText.text = "---";
rmyAvgForceText.text = "---";
PeakForceText.text = "---";
rmyPeakForceText.text = "---";
records.Clear();// = new List<string>();
values.Clear(); //= new List<TempRowerCalc>();
Kj = 0;
x = 0;
seconds = 0;
totalDistance = 0;
stopSeconds = 0;
isPause = false;
#if !UNITY_EDITOR
transform.Find("Ready").gameObject.SetActive(true);
#endif
C2RowerData.EnableChanged -= ModeChanged;
C2RowerData.EnableChanged += ModeChanged;
if (RowerData != null)
{
RowerData.RowerResChanged -= ResChanged;
RowerData.RowerResChanged += ResChanged;
}
//FtmsRowerData.RowerResChanged -= ResChanged;
//FtmsRowerData.RowerResChanged += ResChanged;
//标志线复位
Transform leftLine = transform.Find("Rower/Modes/Scroll/M2/Track/TraceContainer/LineMeterLeft"),
rightLine = transform.Find("Rower/Modes/Scroll/M2/Track/TraceContainer/LineMeterRight"),
finishLine = transform.Find("Rower/Modes/Scroll/M2/Track/TraceContainer/LineFinish");
leftLine.localPosition = new Vector3(-207.5f+43, leftLine.localPosition.y, leftLine.localPosition.z);
rightLine.localPosition = new Vector3(164.5f+43, rightLine.localPosition.y, rightLine.localPosition.z);
finishLine.localPosition = new Vector3(-237.5f+43, finishLine.localPosition.y, finishLine.localPosition.z);
historyStrokeCount = 0;
historyDistance = 0;
historyTime = 0;
historyEnergy = 0;
Resources.UnloadUnusedAssets();
GC.Collect();
}
private void ModeChanged(object sender, EventArgs e)
{
if (RowerData != null)
{
RowerData.PullChanged -= PaintPullCurve;
RowerData.PullChanged += PaintPullCurve;
RowerData.StartEvent -= StartFunc;
RowerData.StartEvent += StartFunc;
RowerData.RowerResChanged -= ResChanged;
RowerData.RowerResChanged += ResChanged;
}
slider.GetComponent<Slider>().interactable = !(bool)sender;
transform.Find("ResBar/BtnSub").GetComponent<Button>().interactable = !(bool)sender;
transform.Find("ResBar/BtnAdd").GetComponent<Button>().interactable = !(bool)sender;
}
private void ResChanged(object sender, EventArgs e)
{
var originData = (IRowerCommonData)sender;
if (slider && RowerData!= null && originData == RowerData)
{
var origin = RowerData.ResistanceLevel;
var wrapped = origin< 50 ? 50 : origin;
slider.GetComponent<PFUISlider>().SetValue((wrapped - 50) / 300f);
}
}
public bool checkRowing()
{
if (seconds > 0)
{
Utils.showToast(null, "Please end this training.", isLowest: true, isOnly: true);
return true;
}
return false;
}
private void ReturnHome()
{
if (checkRowing()) return;
//Disconnect();
UIManager.ShowHomePanel();
UIManager.ShowRowerSelector();
}
// Update is called once per frame
public bool openTimer { get; private set; } = false;
double x = 0f;
#if UNITY_EDITOR
List<ushort> tempList = new List<ushort>()
{
0,300,200,1100,400,500,120,130,160,0,0,0,200,300,400,500,600,500
};
int tempx = 0;
#endif
private Text WText { get; set; }
private Text rmyWText { get; set; }
private Text FiveText { get; set; }
private Text MSText { get; set; }
private Text ExpectedText { get; set; }
private Text KMText { get; set; }
private Text BPMText { get; set; }
private Text TimeText { get; set; }
private Text TimesText { get; set; }
private Text Caloriestext { get; set; }
private Text rmyCaloriestext { get; set; }
private Text AvgForceText { get; set; }
private Text rmyAvgForceText { get; set; }
private Text PeakForceText { get; set; }
private Text rmyPeakForceText { get; set; }
private bool interruptFlag{ get; set; }
void TimerTicks()
{
var heartRate = HeartRate ?? 0;
#if UNITY_EDITOR
var a = tempList[(tempx++) % tempList.Count];
Debug.Log(a);
PaintPullCurve((ushort)(a / 10));
if (RowerData == null) return;
#endif
//#if !UNITY_EDITOR
if (Rower == null)
{
interruptFlag = true;
//HandleDiscardDirect();
isPause = true;
UIManager.ShowConfirm(App.GetLocalString("Warning"), App.GetLocalString("Save the game?"), () =>
{
HandleSaveDirect();
UIManager.CloseConfirm();
interruptFlag = false;
}, 2, ()=> {
Init();
interruptFlag = false;
});
return;
}
if (interruptFlag) return;
if (RowerData == null) return;
//#endif
//断线重连继续
var distance = (int)RowerData.TotalDistance + historyDistance;
var energy = RowerData.TotalEnergy + historyEnergy;
var strokeCount = RowerData.StrokeCount + historyStrokeCount;
var power = RowerData.InstantaneousPower;
var rate = RowerData.StrokeRate;
truelyTime++;
TempRowerCalc tmpdata = null;
//里程停止逻辑
if (totalDistance == RowerData.TotalDistance + historyDistance)
{
//判定一次停止
stopSeconds++;
}
else
{
stopSeconds = 0;
transform.Find("Stopped").gameObject.SetActive(false);
}
if (stopSeconds >= 2)
{
if (UIManager.Instance.confirm != null && UIManager.Instance.confirm.IsActive())
return;
transform.Find("Stopped").gameObject.SetActive(true);
//if (stopSeconds == 6)
//{
// Utils.showToast(null, "Please keep rowing...", duration: 60, stopFunc: () => stopSeconds < 6, isLowest: true);
//}
if (rowerType.type == 2)
{
var remainTime = rowerType.value - (++seconds);
if (remainTime == 0)
{
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},0,0,0,{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = 0, power = 0, rate = 0, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
HandleSaveDirect();
return;
}
TimeSpan.FromSeconds(remainTime).ToPFString();
TimeText.text = TimeSpan.FromSeconds(remainTime).ToPFString();
}
else
{
TimeText.text = TimeSpan.FromSeconds(++seconds).ToPFString();
}
WText.text = "---";
rmyWText.text = "---";
FiveText.text = "---";
MSText.text = "---";
ExpectedText.text = "---";
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},0,0,0,{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = 0, power = 0, rate = 0, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
return;
}
totalDistance = (uint)distance;
var pace = RowerData.InstantaneousPace;
WText.text = power.ToString();
rmyWText.text = power.ToString();
FiveText.text = TimeSpan.FromSeconds(pace).ToPFString();
MSText.text = rate.ToString();
TimesText.text = strokeCount.ToString();
Caloriestext.text = energy.ToString();
rmyCaloriestext.text = energy.ToString();
AvgForceText.text = RowerData.AverageDriveForce.ToString("#0");
rmyAvgForceText.text = RowerData.AverageDriveForce.ToString("#0");
PeakForceText.text = RowerData.PeakDriveForce.ToString("#0");
rmyPeakForceText.text = RowerData.PeakDriveForce.ToString("#0");
if (pace != 0)
{
if (rowerType.type == 1)
{
//设置里程时 显示预估时间 当前时间+剩余里程/配速(转换)
var remainDistance = rowerType.value - totalDistance;
var time = values.Count + (remainDistance / (500f / pace));
ExpectedText.text = TimeSpan.FromSeconds(time).ToPFString();
}
else if (rowerType.type == 2)
{
var remainTime = rowerType.value - values.Count;
var dis = totalDistance + (remainTime * (500f / pace));
//设置时间时 显示预估里程 当前里程+剩余时间*配速
ExpectedText.text = $"{dis:#0}";
}
else
{
//自由滑 显示30min里程 当前里程+剩余时间*配速
var count30 = ((int)Math.Ceiling(values.Count / 1800f));
var remainTime = count30 * 1800 - values.Count;
var dif = 0;
if (count30 > 1 && (count30 - 1) * 1800 - 1 < values.Count)
{
dif = values[(count30 - 1) * 1800 - 1].distance;
}
var dis = totalDistance - dif + (remainTime * (500f / pace));
//设置时间时 显示预估里程 当前里程+剩余时间*配速
ExpectedText.text = $"{dis:#0}";
}
}
if (rowerType.type == 2)
{
var remainTime = rowerType.value - (++seconds);
TimeText.text = TimeSpan.FromSeconds(remainTime).ToPFString();
if (remainTime == 0)
{
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},{RowerData.InstantaneousPower},{RowerData.InstantaneousPace},{RowerData.StrokeRate},{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = pace, power = power, rate = rate, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
HandleSaveDirect();
return;
}
}
else
{
TimeText.text = TimeSpan.FromSeconds(++seconds).ToPFString();
}
if (rowerType.type == 1)
{
var remainDistance = rowerType.value - totalDistance;
if (remainDistance <= 0)
{
KMText.text = "0";
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},{RowerData.InstantaneousPower},{RowerData.InstantaneousPace},{RowerData.StrokeRate},{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = pace, power = power, rate = rate, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
HandleSaveDirect();
return;
}
KMText.text = remainDistance.ToString();
}
else
{
KMText.text = totalDistance.ToString();
}
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},{RowerData.InstantaneousPower},{RowerData.InstantaneousPace},{RowerData.StrokeRate},{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = pace, power = power, rate = rate, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
if (C2RowerData.IsEnabled == true && C2RowerData.isReadyStatus && values.Count()>10)
{
HandleSaveDirect();
}
if (ticks % 5 == 0)
{
SaveRealTimes();//实时保存数据
}
}
//检查本地数据
int historyDistance = 0,historyStrokeCount = 0,historyEnergy = 0;
public int historyTime = 0;
private void CheckLocalData()
{
try
{
var dir = $"{PFConstants.RowerRecordCacheFolder}/{App.CurrentUser.Id}/";
var hasLocalData = Directory.Exists(dir);
if (hasLocalData)
{
var files = Directory.GetFiles(dir);
if (files.Length == 0)
return;
var historyRowerTime = PlayerPrefs.GetString("historyRowerTime");
if (!string.IsNullOrEmpty(historyRowerTime))
{
UIManager.ShowConfirm(App.GetLocalString("Warning"), App.GetLocalString("Save the game?"), () =>
{
var str = File.ReadAllText(files[0]);
var list = str.Replace("\r\n", " ").Split(' ');
records.Clear();
foreach (var item in list)
{
if (!string.IsNullOrEmpty(item))
{
var datas = item.Split(',');
records.Add(item);
values.Add(new TempRowerCalc()
{
strokeCount = int.Parse(datas[0]),
pace = ushort.Parse(datas[4]),
power = int.Parse(datas[3]),
rate = uint.Parse(datas[5]),
heartRate = int.Parse(datas[7]),
distance = int.Parse(datas[2]),
energy = int.Parse(datas[8])
});
}
//records.Add($"{strokeCount}0,{RowerData.ElapsedTime},{distance}2,{power}3,{pace}4,{rate}5,{RowerData.ResistanceLevel},{heartRate}7,{energy}8,{RowerData.AveragePower},{truelyTime}");
}
var historyRowerType = PlayerPrefs.GetString("historyRowerType");
if (!string.IsNullOrEmpty(historyRowerType))
{
var typeObject = historyRowerType.Split(',');
rowerType = new RowerType() { type = int.Parse(typeObject[0]), value = float.Parse(typeObject[1]) };
}
createTime = UIManager.Now.GetDateTime();
Save(PlayerPrefs.GetString("historyRowerShadowIds"));
Helper.DelectDir(dir);
UIManager.CloseConfirm();
}, 2,
() =>
{
Helper.DelectDir(dir);
UIManager.CloseConfirm();
if (Rower != null)
{
Rower.Reset();
}
});
}
}
}
catch (Exception e)
{
Debug.LogError(e);
}
}
//5s钟保存
private void SaveRealTimes()
{
try
{
var dir = $"{PFConstants.RowerRecordCacheFolder}/{App.CurrentUser.Id}/";
var path = $"{dir}/{Id}.txt";
if (!Directory.Exists(dir))
{
Directory.CreateDirectory(dir);
}
File.WriteAllText(path, string.Join("\r\n", records));
File.WriteAllText($"{PFConstants.RowerRecordCacheFolder}/cache.txt", string.Join("\r\n", App.cacheList));
PlayerPrefs.SetString("historyRowerType", $"{rowerType.type},{rowerType.value}");
PlayerPrefs.SetString("historyRowerTime", UIManager.Now.GetDateTime().ToString());
PlayerPrefs.SetString("historyRowerShadowIds", string.Join(",", GetComponent<RowerMultiModeScript>().shadowList.Select(x => x.Nid)));
//Debug.Log(Convert.ToDateTime());
}
catch (Exception e)
{
Debug.LogError(e);
}
}
private RowerMultiModeScript rowerMultiModeScript { get; set; }
void SendDataToRace(TempRowerCalc tmpdata)
{
rowerMultiModeScript.HandleTimeTick(new RowerChartModel
{
Pace = tmpdata.pace,
Power = tmpdata.power,
HeartRate = tmpdata.heartRate,
Rate = tmpdata.rate,
Distance = tmpdata.distance,
StrokeCount = tmpdata.strokeCount
});
}
void PaintPullCurve(object sender, EventArgs e)
{
//防止设备断开重连rowData对象发生变化事件重复触发
var ftms = (IRowerCommonData)sender;
if (RowerData != ftms)
return;
//Debug.Log(ftms.PullValue);
PaintPullCurve(ftms.PullValue);
}
bool isPlay = false;
int pointCount = 0;
void PaintPullCurve(ushort y)
{
Debug.Log($"收到拉力 x={x} , y={y}");
//#if !UNITY_EDITOR
// if (!openTimer)
// {
// if (y > 0 && !isPause)
// {
// StartFunc();
// }
// else
// {
// return;
// }
// }
//#endif
//if (y > 1200) y = 1200;
//拉力条
var rate = ((float)y) * 2 / 120;
if (rate > 1) rate = 1f;
leftImage.fillAmount = rate;
rightImage.fillAmount = rate;
//动画
//left.Find("Rower").GetComponent<Image>().sprite = spriteDict[y / 67];
//曲线
if (y == 0)
{
//if (pullList.Count == 0)
if(pointCount == 0)
{
ClearChart("Player 2");
isPlay = true;
x = 0.1;
pointCount++;
pullList.Add(new DoubleVector2(x, y));
SetChartData(x, y);
}
//else if (pullList.Count > 1)
else if(pointCount > 1)
{
x += 0.1;
pointCount++;
pullList.Add(new DoubleVector2(x, y));
SetChartData(x, y);
historyPullList = pullList.Select(x => x).ToList();
pullList.Clear();
pointCount = 0;
x = 0.1;
//SetChartData(x, y);
pointCount = 1;
//isPlay = true;
pullList.Add(new DoubleVector2(x, y));
}
else
{
//只有0并且两秒没拉曲线消失
if (stopSeconds == 1)
{
ClearChart("Player 1");
ClearChart("Player 2");
//SetChartData(new List<DoubleVector2>(), new List<DoubleVector2>());
}
}
}
else
{
if (pullList.Count(x => x.y == 0) == pullList.Count)
{
ClearChart("Player 2");
pointCount = 0;
SetChartData(0.1, 0);
}
x += 0.1;
pointCount++;
pullList.Add(new DoubleVector2(x, y));
//if (pullList.Count > 5 && isPlay)
if (pointCount > 5 && isPlay)
{
Debug.Log("开始动画");
isPlay = false;
//left.Find("Rower").GetComponent<RowerAnimation>().StartAnimation();
}
//SetChartData(pullList, historyPullList);
SetChartData(x, y);
}
//Debug.Log($"{x},{y}");
//transform.Find("Mid/GraphChart").GetComponent<RowerGraphChartFeed>().SetData(pullList);
//pullList.Add(new DoubleVector2(x, y));
//if (pullList.Count >= 75)
//{
// pullList.RemoveAt(0);
// pullList = pullList.Select(val => new DoubleVector2(val.x - 0.1, val.y)).ToList();
//}
//else
//{
// x += 0.1f;
//}
}
void ClearChart(string cateName)
{
rowerGraphChartFeed.ClearChart(cateName);
graphChartFeed.ClearChart(cateName);
}
double preX, preY;
void SetChartData(double x, double y)
{
if (M1.localPosition.x == 0)
{
rowerGraphChartFeed.SetCurrentPoint(x, y);
rowerGraphChartFeed.SetHistoryData(historyPullList);
}
else
{
graphChartFeed.SetCurrentPoint(x, y);
}
}
void SetChartData(List<DoubleVector2> v1, List<DoubleVector2> v2)
{
//graph.DataSource.AddPointToCategoryRealtime("Player 2", item.x, item.y);
if (M1.localPosition.x == 0)
{
rowerGraphChartFeed.SetData(v1, v2);
}
else
{
graphChartFeed.SetData(v1);
}
}
float staticTimer = 1f,shortTimer = 0.25f;
int ticks { get; set; } = 0;
void Update()
{
#if UNITY_EDITOR
if (openTimer || true)
#else
if (openTimer)
#endif
{
timer -= Time.deltaTime;
shortTimer -= Time.deltaTime;
if (shortTimer <= 0)
{
ShortUpdateData();
shortTimer += 0.25f;
}
if (timer <= 0)
{
TimerTicks();
ticks++;
timer = 1f + timer;
}
}
staticTimer -= Time.deltaTime;
if (staticTimer <= 0)
{
var heartRate = HeartRate ?? 0;
BPMText.text = heartRate == 0 ? "---": heartRate.ToString();
HandleStatic();
staticTimer += 1f;
}
//shortTimer -= Time.deltaTime;
//if (shortTimer <= 0)
//{
// if (openTimer)
// {
// ShortUpdateData();
// }
// shortTimer += 0.5f;
//}
}
void ShortUpdateData()
{
if (RowerData == null) return;
var power = RowerData.InstantaneousPower;
var rate = RowerData.StrokeRate;
var pace = RowerData.InstantaneousPace;
var strokeCount = RowerData.StrokeCount + historyStrokeCount;
var distance = (int)RowerData.TotalDistance + historyDistance;
var energy = RowerData.TotalEnergy + historyEnergy;
var heartRate = HeartRate ?? 0;
if (rowerType.type == 1 && totalDistance >=rowerType.value && !createTime.HasValue)
{
openTimer = false;
KMText.text = "0";
records.Add($"{strokeCount},{RowerData.ElapsedTime},{distance},{power},{pace},{rate},{RowerData.ResistanceLevel},{heartRate},{energy},{RowerData.AveragePower},{truelyTime}");
var tmpdata = new TempRowerCalc() { strokeCount = strokeCount, pace = pace, power = power, rate = rate, heartRate = heartRate, distance = distance, energy = energy };
values.Add(tmpdata);
SendDataToRace(tmpdata);
HandleSaveDirect();
return;
}
if (stopSeconds >= 2)
{
return;
}
WText.text = power.ToString();
rmyWText.text = power.ToString();
FiveText.text = TimeSpan.FromSeconds(pace).ToPFString();
MSText.text = rate.ToString();
}
bool isFirstReset = false;
void HandleStatic()
{
var flag = Rower != null && RowerData != null && !(UIManager.Instance.confirm != null && UIManager.Instance.confirm.IsActive());
if (transform.Find("Ready").gameObject.activeInHierarchy)
{
transform.Find("Ready/DeviceStatus").gameObject.SetActive(!flag);
transform.Find("Ready/Img").gameObject.SetActive(flag);
transform.Find("Ready/Text").gameObject.SetActive(flag);
transform.Find("Ready/DeviceStatusConnect").gameObject.SetActive(flag);
if (flag && RowerData.TotalDistance != 0)
{
Rower.Reset();
if(C2RowerData.IsEnabled)
RowerData.Reset();
}
}
if (transform.Find("Stopped").gameObject.activeInHierarchy)
{
transform.Find("Stopped/DeviceStatus").gameObject.SetActive(!flag);
transform.Find("Stopped/DeviceStatusConnect").gameObject.SetActive(flag);
}
if (Rower != null)
{
if (C2RowerData.IsEnabled == true && !openTimer && !isPause && C2RowerData.rowerType!=null)
{
rowerType = C2RowerData.rowerType;
HandleSelectType();
}
//if (C2RowerData.IsEnabled)
//{
// Rower.C2GetStatus(new byte[] { 0xc1 });
//}
}
}
}