Skip to content

Commit

Permalink
Add a utility for toggling the profiler from within the game.
Browse files Browse the repository at this point in the history
  • Loading branch information
angavrilov committed Feb 15, 2014
1 parent 4a3fbea commit bb9d0a7
Show file tree
Hide file tree
Showing 3 changed files with 171 additions and 1 deletion.
161 changes: 161 additions & 0 deletions Misc/MonoProfilerToggle.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
using System;
using UnityEngine;

using System.IO;
using System.Net.Sockets;
using System.Text.RegularExpressions;
using System.Text;

[KSPAddon(KSPAddon.Startup.Instantly, false)]
public class MonoProfilerToggle : MonoBehaviour
{
private static TcpClient link = null;
private static NetworkStream stream = null;
private static StreamReader reader = null;
private static StreamWriter writer = null;

private static int port = -1;
private static bool profiling = true;
private static bool error = false;

private Rect pos;
private GUIStyle style_r, style_g, style_b;

private float last_command = -1;

public MonoProfilerToggle()
{
if (link != null)
return;

var profargs = System.Environment.GetEnvironmentVariable("MONO_PROFILE");
if (profargs == null || profargs == "")
return;

if (Connect(profargs))
DontDestroyOnLoad(this);
}

private bool Connect(string profargs)
{
Regex port_re = new Regex(@"command-port=(?<port>\d+)");
MatchCollection matches = port_re.Matches(profargs);

foreach (Match match in matches)
{
if (match.Groups["port"].Success)
port = int.Parse(match.Groups["port"].Value);
}

if (port < 0)
return false;

if (profargs.Contains("start-disabled"))
profiling = false;

try
{
link = new TcpClient("127.0.0.1", port);
link.ReceiveTimeout = 5000;

stream = link.GetStream();
reader = new StreamReader(stream, Encoding.ASCII);
writer = new StreamWriter(stream, Encoding.ASCII);

return true;
}
catch (Exception e)
{
Debug.LogError("Cannot connect to profiler: "+e);
link = null;
error = true;
return false;
}
}

private void SendEnable(bool on)
{
try
{
error = false;

try
{
while (stream.DataAvailable)
Debug.Log("profiler: "+reader.ReadLine());
}
catch (SocketException e)
{
Debug.LogError("profiler read: "+e);
}

reader.DiscardBufferedData();

writer.WriteLine(on ? "enable" : "disable");
writer.Flush();

var reply = reader.ReadLine();

if (reply.StartsWith("DONE"))
profiling = on;
else
{
Debug.LogError("Profiler reply: "+reply);
error = true;
}
}
catch (Exception e)
{
Debug.LogError("Profiler control: "+e);
error = true;
}
}

public void Update()
{
if (link != null && link.Connected)
{
if (Input.GetKeyDown(KeyCode.F10) && Input.GetKey(KeyCode.RightAlt))
{
// Don't send commands too often
if (Time.realtimeSinceStartup < last_command+1)
return;

last_command = Time.realtimeSinceStartup;
SendEnable(!profiling);
}
}
}

public void OnGUI()
{
if (link == null && !error)
return;

if (style_r == null)
{
pos = new Rect(Screen.width - 60, Screen.height - 60, 50, 60);

style_r = new GUIStyle(GUI.skin.label);
style_r.alignment = TextAnchor.LowerRight;
style_r.normal.textColor = new Color(1.0f, 0.0f, 0.0f, 0.7f);

style_g = new GUIStyle(style_r);
style_g.normal.textColor = new Color(0.0f, 1.0f, 0.0f, 0.7f);

style_b = new GUIStyle(style_r);
style_b.normal.textColor = new Color(0.0f, 0.0f, 1.0f, 0.7f);
}

if (!error && !link.Connected)
error = true;

if (error)
GUI.Label(pos, "ERR", style_r);
else if (profiling)
GUI.Label(pos, "On", style_g);
else
GUI.Label(pos, "Off", style_b);
}
}

10 changes: 9 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,18 @@ The script contains three sample sets of options:
that after using the ``disable`` command, and waiting a bit, it is
mostly safe to quit the game with Alt-F4.

The ``Misc`` subfolder includes a *MonoProfilerToggle* utility, which
implements an in-game way to send these commands. When loaded into the game
with this mode of profiling enabled, it automatically establishes the TCP
control connection, and then shows the estimated current state in the bottom
right corner of the screen, while allowing it to be toggled by pressing
*Right Alt + F10*.

**Note:** Shutting down the game and then quickly restarting
it may cause a failure to listen on the port due to a reuse timeout.
The only way you will know is that telnet won't be able to connect.
Also, you cannot reconnect if you close telnet by mistake.
Also, it does not support simultaneous connections, or reconnecting
if you close telnet by mistake.


OS specifics
Expand Down
1 change: 1 addition & 0 deletions package.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ compile_ksp() {

compile_ksp Misc/FPS.dll Misc/FPS.cs
compile_ksp Misc/UnityObjectTree.dll Misc/UnityObjectTree.cs
compile_ksp Misc/MonoProfilerToggle.dll Misc/MonoProfilerToggle.cs

MONODIR=mono/builds/embedruntimes/

Expand Down

0 comments on commit bb9d0a7

Please sign in to comment.