using UnityEditor;
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using System.Reflection;
using Perforce.P4;
namespace P4Connect
{
[InitializeOnLoad]
public class Main
{
// Path to the Asset folder
public static string DataPath { get; private set; }
// Path the project folder
public static string RootPath { get; private set; }
// The name of the current project
public static string ProjectName { get; private set; }
// Returns whether the system is initialized and we can access perforce
public static bool Initialized { get; private set; }
// Import this method to override the DLLImport search directory, so that P4API.NET can load P4Bridge
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool SetDllDirectory(string lpPathName);
// Import this method to retrieve the DLLImport search directory
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern int GetDllDirectory(int nBufferLength, StringBuilder lpPathName);
// Import this method to retrieve the DLLImport search directory
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern IntPtr LoadLibrary(string lpModuleName);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool FreeLibrary(IntPtr href);
///
/// Static constructor
///
static Main()
{
Initialized = false;
Initialize();
Initialized = true;
}
///
/// Initialize the different parts of P4Connect
///
static public void Initialize()
{
DateTime startTimestamp = DateTime.Now;
SetupRootDirectory();
SetDLLDirectory();
Config.Initialize();
InitializeLogging();
Engine.Initialize();
AssetBridge.Initialize();
UnityVSBridge.Initialize();
AssetStatusCache.Initialize();
Icons.Initialize();
// First time - always check out sln files
if (Config.IncludeSolutionFiles)
{
AssetBridge.CheckoutProjectFiles(false, true);
}
PendingChanges.UpdateDisplay();
if (Config.DisplayP4Timings)
{
double deltaTime = (DateTime.Now - startTimestamp).TotalMilliseconds;
StringBuilder builder = new StringBuilder();
Debug.Log("P4Connect - Initialization Time: " + deltaTime + " ms");
}
}
///
/// Initializes the root directory, asset directory and project name
///
static void SetupRootDirectory()
{
// Grab all the directories and project names from the asset folder
DataPath = Application.dataPath;
string[] path = DataPath.Split(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar);
RootPath = "";
for (int i = 0; i < path.Length - 1; ++i)
RootPath += path[i] + System.IO.Path.DirectorySeparatorChar;
ProjectName = path[path.Length - 2];
}
// Return the currently stored DLL Directory
public static string GetDLLDirectory()
{
StringBuilder tmp = new StringBuilder(10240);
if (GetDllDirectory(10240, tmp) == 0)
{
int err = Marshal.GetLastWin32Error();
Debug.Log("GetDllDirectory returned error:" + err.ToString());
return null;
}
return tmp.ToString();
}
public static IntPtr href = IntPtr.Zero;
///
/// Allow users to override the dll search directory
///
public static void SetDLLDirectory()
{
if (Application.platform == RuntimePlatform.WindowsEditor)
{
if (Utils.IsRunningUnity5()) // Unity 5.X on Windows
{
// Do nothing. Unity5 will mess up any SetDLLDirectory we try to do.
}
else // Unity 4.X on Windows
{
// Force the DLL search directory as soon as possible
string path = Utils.GetBridgeDirectory();
// Debug.Log("SetDLLDirectory to " + path);
SetDllDirectory(path);
href = LoadLibrary("p4bridge"); // This global handle is never freed
if (href == IntPtr.Zero)
{
int err = Marshal.GetLastWin32Error();
Debug.Log("p4bridge LoadLibrary Error: " + err.ToString());
}
else
{
Debug.Log("LoadLibrary Success!");
}
}
}
else if (Application.platform == RuntimePlatform.OSXEditor)
{
bool copyit = false;
string dylibSourcePath = System.IO.Path.Combine(Utils.GetBridgeDirectory(), Config.P4BridgeDYLIBName);
string dylibDestPath = System.IO.Path.Combine(RootPath, Config.P4BridgeDYLIBName);
//Debug.Log("src: " + dylibSourcePath);
//Debug.Log("dst: " + dylibDestPath);
if (System.IO.File.Exists(dylibDestPath)) // Check the modify time on the existing file
{
if (System.IO.File.GetLastWriteTime(dylibDestPath) < System.IO.File.GetLastWriteTime(dylibSourcePath))
copyit = true;
}
else
{
copyit = true;
}
if (copyit)
{
System.IO.File.Copy(dylibSourcePath, dylibDestPath, true);
EditorUtility.DisplayDialog("Restart Unity?",
"In order for P4Connect to function on OSX, P4Connect\n" +
"had to copy libP4Bridge.dylib to the root folder of your project\n" +
"You now have to restart Unity for it to properly load the dylib.", "Ok");
}
}
}
public static System.Diagnostics.DefaultTraceListener defaultListener;
public static void InitializeLogging()
{
if (Config.EnableLog)
{
//System.Console.WriteLine("Listeners: " + System.Diagnostics.Trace.Listeners.ToString());
//foreach( System.Diagnostics.TraceListener listener in System.Diagnostics.Trace.Listeners)
//{
// System.Console.WriteLine("Listener: " + listener.ToString());
//}
System.Diagnostics.Trace.Listeners.RemoveAt(0);
defaultListener = new System.Diagnostics.DefaultTraceListener();
defaultListener.LogFileName = Config.LogPath;
defaultListener.Name = "p4connect";
// Write the initial trace message to the console trace listener.
defaultListener.WriteLine(DateTime.Now.ToString() + " [" + defaultListener.Name + "] - Starting output to trace listener.");
// Add the new console trace listener to
// the collection of trace listeners.
System.Diagnostics.Trace.Listeners.Add(defaultListener);
LogFile.SetLoggingFunction(P4ConnectLog);
}
}
// Expose logging from within the bridge
public static void P4ConnectLog(int log_level, String source, String message)
{
string payload = DateTime.Now.ToString() + " lvl: " + log_level.ToString() + " [ " + source + " ] " + message;
Debug.Log(payload);
if (Config.EnableLog)
{
defaultListener.WriteLine(payload);
defaultListener.Flush();
}
}
public static void p4log(string message)
{
if (! String.IsNullOrEmpty(message))
P4ConnectLog(4, "p4log", message);
}
public static void p4logArray(string indent, string[] a)
{
foreach(string s in a)
{
p4log(indent + s);
}
}
}
}