@@ -14,18 +14,6 @@ using System.Text;
namespace Shadowsocks.View
{
struct TrafficInfo
{
public long inbound;
public long outbound;
public TrafficInfo(long inbound, long outbound)
{
this.inbound = inbound;
this.outbound = outbound;
}
}
public partial class LogForm : Form
{
long lastOffset;
@@ -37,9 +25,17 @@ namespace Shadowsocks.View
// global traffic update lock, make it static
private static readonly object _lock = new object();
#region chart
long lastMaxSpeed;
ShadowsocksController.QueueLast<TrafficInfo> traffic = new ShadowsocksController.QueueLast<TrafficInfo>();
#region Traffic Chart
Queue<TrafficInfo> trafficInfoQueue = new Queue<TrafficInfo>();
const int queueMaxLength = 60;
long lastInbound, lastOutbound;
long maxSpeed = 0, lastMaxSpeed = 0;
const long minScale = 50;
BandwidthScaleInfo bandwidthScale;
List<float> inboundPoints = new List<float>();
List<float> outboundPoints = new List<float>();
TextAnnotation inboundAnnotation = new TextAnnotation();
TextAnnotation outboundAnnotation = new TextAnnotation();
#endregion
public LogForm(ShadowsocksController controller, string filename)
@@ -63,29 +59,24 @@ namespace Shadowsocks.View
UpdateTexts();
}
private void update_ TrafficChart()
private void Update TrafficChart()
{
List<float> inboundPoints = new List<float>();
List<float> outboundPoints = new List<float>();
TextAnnotation inboundAnnotation = new TextAnnotation();
TextAnnotation outboundAnnotation = new TextAnnotation();
BandwidthScaleInfo bandwidthScale;
const long minScale = 50;
long maxSpeed = 0;
long lastInbound, lastOutbound;
lock (_lock)
{
if (traffic.Count == 0)
if (trafficInfoQueue.Count == 0)
return;
foreach (var trafficPerSecond in traffic)
inboundPoints.Clear();
outboundPoints.Clear();
maxSpeed = 0;
foreach (var trafficInfo in trafficInfoQueue)
{
inboundPoints.Add(trafficPerSecond.inbound);
outboundPoints.Add(trafficPerSecond.outbound);
maxSpeed = Math.Max(maxSpeed, Math.Max(trafficPerSecond.inbound, trafficPerSecond.outbound));
inboundPoints.Add(trafficInfo .inbound);
outboundPoints.Add(trafficInfo .outbound);
maxSpeed = Math.Max(maxSpeed, Math.Max(trafficInfo.inbound, trafficInfo .outbound));
}
lastInbound = traffic.Last().inbound;
lastOutbound = traffic.Last().outbound;
lastInbound = trafficInfoQueue .Last().inbound;
lastOutbound = trafficInfoQueue .Last().outbound;
}
if (maxSpeed > 0)
@@ -101,7 +92,7 @@ namespace Shadowsocks.View
bandwidthScale = Utils.GetBandwidthScale(maxSpeed);
//rescale the original data points, since it is List<float>, .ForEach does not work
// re- scale the original data points, since it is List<float>, .ForEach does not work
inboundPoints = inboundPoints.Select(p => p / bandwidthScale.unit).ToList();
outboundPoints = outboundPoints.Select(p => p / bandwidthScale.unit).ToList();
@@ -109,7 +100,7 @@ namespace Shadowsocks.View
{
trafficChart.Series["Inbound"].Points.DataBindY(inboundPoints);
trafficChart.Series["Outbound"].Points.DataBindY(outboundPoints);
trafficChart.ChartAreas[0].AxisY.LabelStyle.Format = "{0:0.##} " + bandwidthScale.unit_n ame;
trafficChart.ChartAreas[0].AxisY.LabelStyle.Format = "{0:0.##} " + bandwidthScale.unitN ame;
trafficChart.ChartAreas[0].AxisY.Maximum = bandwidthScale.value;
inboundAnnotation.AnchorDataPoint = trafficChart.Series["Inbound"].Points.Last();
inboundAnnotation.Text = Utils.FormatBandwidth(lastInbound);
@@ -125,10 +116,29 @@ namespace Shadowsocks.View
{
lock (_lock)
{
traffic = new ShadowsocksController.QueueLast<TrafficInfo>();
foreach (var trafficPerSecond in controller.traffic)
if (trafficInfoQueue.Count == 0)
{
traffic.Enqueue(new TrafficInfo(trafficPerSecond.inboundIncreasement, trafficPerSecond.outboundIncreasement));
// Init an empty queue
for (int i = 0; i < queueMaxLength; i++)
{
trafficInfoQueue.Enqueue(new TrafficInfo(0, 0));
}
foreach (var trafficPerSecond in controller.trafficPerSecondQueue)
{
trafficInfoQueue.Enqueue(new TrafficInfo(trafficPerSecond.inboundIncreasement,
trafficPerSecond.outboundIncreasement));
if (trafficInfoQueue.Count > queueMaxLength)
trafficInfoQueue.Dequeue();
}
}
else
{
var lastTraffic = controller.trafficPerSecondQueue.Last();
trafficInfoQueue.Enqueue(new TrafficInfo(lastTraffic.inboundIncreasement,
lastTraffic.outboundIncreasement));
if (trafficInfoQueue.Count > queueMaxLength)
trafficInfoQueue.Dequeue();
}
}
}
@@ -157,7 +167,7 @@ namespace Shadowsocks.View
private void Timer_Tick(object sender, EventArgs e)
{
UpdateContent();
update_ TrafficChart();
Update TrafficChart();
}
private void InitContent()
@@ -258,9 +268,9 @@ namespace Shadowsocks.View
config.topMost = topMostTrigger;
config.wrapText = wrapTextTrigger;
config.toolbarShown = toolbarTrigger;
config.Font=LogMessageTextBox.Font;
config.BackgroundColor=LogMessageTextBox.BackColor;
config.TextColor=LogMessageTextBox.ForeColor;
config.Font = LogMessageTextBox.Font;
config.BackgroundColor = LogMessageTextBox.BackColor;
config.TextColor = LogMessageTextBox.ForeColor;
if (WindowState != FormWindowState.Minimized && !(config.Maximized = WindowState == FormWindowState.Maximized))
{
config.Top = Top;
@@ -410,5 +420,17 @@ namespace Shadowsocks.View
ToolbarFlowLayoutPanel.Visible = toolbarTrigger;
ShowToolbarMenuItem.Checked = toolbarTrigger;
}
private class TrafficInfo
{
public long inbound;
public long outbound;
public TrafficInfo(long inbound, long outbound)
{
this.inbound = inbound;
this.outbound = outbound;
}
}
}
}