using System.IO ;
using System.Linq ;
using System.Text.RegularExpressions ;
using System.Threading ;
using System.Threading.Tasks ;
using UnityEngine ;
using UnityEngine.Perception.GroundTruth ;
= "datasetvisualizer" ;
#endif
static Task < int > InstallationCommand ( ref int exitCode , ref string output , string packagesPath )
{
var exitCodeCopy = exitCode ;
var outputCopy = output ;
#if UNITY_EDITOR_WIN
var task = Task . Run ( ( ) = > ExecuteCmd ( $"\" { packagesPath } \ "\\pip3.bat install --upgrade --no-warn-script-location unity-cv-datasetvisualizer" , ref exitCodeCopy , ref outputCopy , waitForExit : - 1 ) ) ;
#elif UNITY_EDITOR_OSX
var task = Task . Run ( ( ) = > ExecuteCmd ( $"cd \'{packagesPath}\'; ./python3.7 -m pip install --upgrade unity-cv-datasetvisualizer" , ref exitCodeCopy , ref outputCopy , waitForExit : - 1 ) ) ;
#endif
exitCode = exitCodeCopy ;
output = outputCopy ;
return task ;
}
/// Install visualizer (Assumes python3 and pip3 are already installed)
/// - installs virtualenv if it is not already installed
/// - and setups a virtual environment for visualizer
/// Install visualizer (Uses the python3.7 installation that comes with python for unity)
static void SetupVisualizer ( )
static async void SetupVisualizer ( )
{
var project = Application . dataPath ;
if ( pythonPid ! = - 1 & & ProcessAlive ( pythonPid , port , visualizerPid ) )
{
if ( EditorUtility . DisplayDialog ( "Kill visualizer?" ,
"The visualizer tool can't be running while you setup, would you like to kill the current instance?" ,
"Kill visualizer " ,
"Cancel " ) )
if ( EditorUtility . DisplayDialog ( "Shutdown visualizer?" ,
"The visualizer tool can't be running while you re-installs, would you like to shutdown the current instance?" ,
"Yes " ,
"No " ) )
{
Process . GetProcessById ( pythonPid + 1 ) . Kill ( ) ;
}
#if UNITY_EDITOR_WIN
var packagesPath = Path . GetFullPath ( Application . dataPath . Replace ( "/Assets" , "/Library/PythonInstall/Scripts" ) ) ;
#elif UNITY_EDITOR_OSX
string packagesPath = Path . GetFullPath ( Application . dataPath . Replace ( "/Assets" , "/Library/PythonInstall/bin" ) ) ;
var packagesPath = Path . GetFullPath ( Application . dataPath . Replace ( "/Assets" , "/Library/PythonInstall/bin" ) ) ;
#endif
#if UNITY_EDITOR_WIN
//==============================INSTALL VISUALIZER IN PYTHON FOR UNITY======================================
EditorUtility . DisplayProgressBar ( "Setting up the Visualizer" , "Installing Visualizer (This may take a few minutes)" , 2f / steps ) ;
#if UNITY_EDITOR_WIN
ExecuteCmd ( $"\" { packagesPath } \ "\\pip3.bat install --upgrade --no-warn-script-location unity-cv-datasetvisualizer" , ref exitCode , ref output , waitForExit : - 1 ) ;
#elif UNITY_EDITOR_OSX
ExecuteCmd ( $"cd \'{packagesPath}\'; ./python3.7 -m pip install --upgrade unity-cv-datasetvisualizer" , ref exitCode , ref output , waitForExit : - 1 ) ;
#endif
await InstallationCommand ( ref exitCode , ref output , packagesPath ) ;
if ( exitCode ! = 0 )
{
EditorUtility . ClearProgressBar ( ) ;
EditorUtility . ClearProgressBar ( ) ;
Debug . Log ( "Successfully installed visualizer" ) ;
Debug . Log ( "Successfully installed visualizer tool! " ) ;
}
/// <summary>
/// If no instance is found it launches a new process
/// </summary>
[MenuItem("Window/Visualizer/Run")]
public static void RunVisualizer ( )
public static async Task RunVisualizer ( )
{
if ( ! CheckIfVisualizerInstalled ( ) )
{
var errorCode = ExecuteVisualizer ( ) ;
if ( errorCode = = - 1 )
{
Debug . LogError ( "Could not launch visualizer tool" ) ;
EditorUtility . ClearProgressBar ( ) ;
return ;
}
var attempts = 0 ;
while ( newVisualizerPid = = - 1 )
{
Thread . Sleep ( 1 0 0 0 ) ;
await Task . Delay ( 1 0 0 0 ) ;
Debug . LogError ( "Failed to get visualizer ID" ) ;
Debug . LogWarning ( "Failed to get visualizer process ID after launch. Note that this does not necessarily mean the tool did not launch successfully. However, running the visualizer again will now create a new instance of the process. " ) ;
EditorUtility . ClearProgressBar ( ) ;
return ;
}
attempts = 0 ;
while ( newPythonPid = = - 1 )
{
Thread . Sleep ( 1 0 0 0 ) ;
await Task . Delay ( 1 0 0 0 ) ;
Debug . LogError ( "Failed to get python ID" ) ;
Debug . LogWarning ( "Failed to get python process ID after launch. Note that this does not necessarily mean the tool did not launch successfully. However, running the visualizer again will now create a new instance of the process. " ) ;
EditorUtility . ClearProgressBar ( ) ;
return ;
}
attempts = 0 ;
while ( newPort = = - 1 )
{
Thread . Sleep ( 1 0 0 0 ) ;
await Task . Delay ( 1 0 0 0 ) ;
Debug . LogError ( "Failed to get PORT " ) ;
Debug . LogWarning ( "Failed to get port number used by the visualizer tool after launch. Note that this does not necessarily mean the tool did not launch successfully. However, running the visualizer again will now create a new instance of the process. " ) ;
EditorUtility . ClearProgressBar ( ) ;
return ;
}
//Save this into the streamlit_instances.csv file
WriteEntry ( project , newPythonPid , newPort , newVisualizerPid ) ;
EditorUtility . DisplayProgressBar ( "Opening Visualizer" , "Opening" , 4f / 4 ) ;
/ * if ( EditorUtility . DisplayDialog ( "Opening Visualizer Tool" ,
if ( EditorUtility . DisplayDialog ( "Opening Visualizer Tool" ,
} * /
}
EditorUtility . DisplayProgressBar ( "Opening Visualizer" , "Opening" , 4f / 4 ) ;
LaunchBrowser ( newPort ) ;
EditorUtility . ClearProgressBar ( ) ;
}
}
var pid = ExecuteCmd ( command , ref exitCode , ref output , waitForExit : 0 , displayWindow : false ) ;
if ( exitCode ! = 0 )
{
Debug . LogError ( "Problem occured when launching the visualizer - Exit Code: " + exitCode ) ;
Debug . LogError ( "Failed launching the visualizer - Exit Code: " + exitCode ) ;
return - 1 ;
}
/// <returns></returns>
static int GetPortForPid ( int pid )
{
foreach ( var p in ProcessPorts . ProcessPortMap )
var processPortMap = PortProcessor . ProcessPortMap ;
if ( processPortMap = = null )
{
return - 1 ;
}
foreach ( var p in processPortMap . Where ( p = > p . ProcessId = = pid ) )
if ( p . ProcessId = = pid )
{
return p . PortNumber ;
}
return p . PortNumber ;
}
return - 1 ;
try
{
var proc = Process . GetProcessById ( pid + 1 ) ;
if ( proc . HasExited )
{
return false ;
}
return true ;
return ! proc . HasExited ;
}
catch ( ArgumentException )
{
/// <returns></returns>
static bool ProcessListensToPort ( int pid , int port )
{
var processes = ProcessP orts . ProcessPortMap . FindAll (
var processes = PortP rocessor . ProcessPortMap . FindAll (
x = > x . ProcessId = = pid + 1 & & x . PortNumber = = port
) ;
return processes . Count > = 1 ;
/// Static class that returns the list of processes and the ports those processes use.
/// </summary>
static class ProcessP orts
static class PortP rocessor
{
/// <summary>
/// A list of ProcessPorts that contain the mapping of processes and the ports that the process uses.
if ( netStatExitStatus ! = "0" )
{
Debug . LogError ( "NetStat command failed. This may require elevated permissions." ) ;
Debug . LogError ( $"NetStat command failed. Try running '{startInfo.FileName} {startInfo.Arguments}' manually to verify that you have permissions to execute this command." ) ;
return null ;
}
#if UNITY_EDITOR_WIN
{
if ( ex is IndexOutOfRangeException | | ex is FormatException | | ex is OverflowException )
{
Debug . LogError ( "Could not convert the following NetStat row to a Process to P ort mapping." ) ;
Debug . LogError ( "Could not convert the following NetStat row to a process to p ort mapping." ) ;
Debug . LogError ( netStatRow ) ;
}
else
{
if ( ! netStatRow . Trim ( ) . StartsWith ( "Proto" ) & & ! netStatRow . Trim ( ) . StartsWith ( "Active" ) & & ! String . IsNullOrWhiteSpace ( netStatRow ) )
{
Debug . LogError ( "Unrecognized NetStat row to a Process to P ort mapping." ) ;
Debug . LogError ( "Could not convert the following NetStat row to a process to p ort mapping." ) ;
Debug . LogError ( netStatRow ) ;
}
}
{
if ( ex is IndexOutOfRangeException | | ex is OverflowException )
{
Debug . LogError ( "Could not convert the following NetStat row to a Process to P ort mapping." ) ;
Debug . LogError ( "Could not convert the following NetStat row to a process to p ort mapping." ) ;
Debug . LogError ( netStatRow ) ;
}
else
/// <summary>
/// A mapping for processes to ports and ports to processes that are being used in the system.
/// </summary>
class ProcessPort
readonly struct ProcessPort
{
/// <summary>
/// Internal constructor to initialize the mapping of process to port.
}
[MenuItem("Window/Visualizer/Check For Updates")]
static void CheckForUpdates ( )
static async Task CheckForUpdates ( )
{
if ( ! CheckIfVisualizerInstalled ( ) )
{
return ;
}
var latestVersion = Task . Run ( PipAPI . GetLatestVersionNumber ) . Result ;
var latestVersion = await PipAPI . GetLatestVersionNumber ( ) ;
string packagesPath = Path . GetFullPath ( Application . dataPath . Replace ( "/Assets" , "/Library/PythonInstall/bin" ) ) ;
var packagesPath = Path . GetFullPath ( Application . dataPath . Replace ( "/Assets" , "/Library/PythonInstall/bin" ) ) ;
#endif
#if UNITY_EDITOR_WIN
if ( currentVersion = = null )
{
Debug . LogError ( "Could not parse the version of the current install of th e visualizer tool" ) ;
Debug . LogError ( "Could not parse the version of the currently installed visualizer tool. Cancelling update check. " ) ;
if ( EditorUtility . DisplayDialog ( "Update Found for Visualizer " ,
if ( EditorUtility . DisplayDialog ( "New Version Found! " ,
$"An update was found for the Visualizer" ,
"Install" ,
"Cancel" ) )
}
else
{
EditorUtility . DisplayDialog ( "Visualizer" , "No new updates found" , "close " ) ;
EditorUtility . DisplayDialog ( "Visualizer" , "No new updates found" , "OK " ) ;
}
}
#endif
if ( exitCode ! = 0 )
{
Debug . LogError ( "Could not list pip packages" ) ;
Debug . LogError ( "Could not list pip packages to check whether the visualizer is installed. Cancelling update check " ) ;
return false ;
}