P4Connect.UnityVSBridge.cs #1

  • //
  • guest/
  • anis_sg/
  • perforce_software/
  • p4connect/
  • src/
  • P4Connect/
  • P4Connect/
  • P4Connect.UnityVSBridge.cs
  • View
  • Commits
  • Open Download .zip Download (6 KB)
using UnityEditor;
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using Perforce.P4;
using System.Linq;
using System.Reflection;

namespace P4Connect
{
	/// <summary>
	/// This class hooks up to and handles UnityVS modifying the project files
	/// </summary>
	public class UnityVSBridge
	{
		// A bunch of strings used to find the project file generation event through reflection
		public const string UnityVSAssemblyName = "SyntaxTree.VisualStudio.Unity.Bridge";
		public const string UnityVSProjectFileGeneratorTypename = "SyntaxTree.VisualStudio.Unity.Bridge.ProjectFilesGenerator";
		public const string UnityVSProjectFileGenerationEventName = "ProjectFileGeneration";
		public const string UnityVSProjectFileGenerationEventHandlerType = "SyntaxTree.VisualStudio.Unity.Bridge.FileGenerationHandler";

		/// <summary>
		/// Static constructor 
		/// </summary>
		public static void Initialize()
		{
			// And hook us up to UnityVS
			if (Config.UnityVSSupport)
				SetupUnityVSHook();

			// Hook the connection settings event
			Config.PrefsChanged += OnConnectionSettingsChanged;

			// Register for project changes
			EditorApplication.projectWindowChanged += OnProjectWindowChanged;
		}

		/// <summary>
		/// Event handler called when the connection settings change
		/// </summary>
		static void OnConnectionSettingsChanged()
		{
			// Setup the root directories based on the updated path
			if (Config.UnityVSSupport)
				SetupUnityVSHook();
		}

		/// <summary>
		/// Hook up to UnityVS ProjectFile event through reflection
		/// </summary>
		static void SetupUnityVSHook()
		{
			// First, find the UnityVS assembly
			Assembly unityVSAssembly = null;
			Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
			for (int i = 0; unityVSAssembly == null && i < assemblies.Length; ++i)
			{
				if (assemblies[i].FullName.Contains(UnityVSAssemblyName))
					unityVSAssembly = assemblies[i];
			}

			if (unityVSAssembly != null)
			{
				// Now that we have the assembly, find the project file generator class
				Type projectFileGeneratorType = unityVSAssembly.GetType(UnityVSProjectFileGeneratorTypename);
				if (projectFileGeneratorType != null)
				{
					// Then the project file generation event itself
					FieldInfo projectGeneration = projectFileGeneratorType.GetField(UnityVSProjectFileGenerationEventName);
					if (projectGeneration != null)
					{
						// Make a bridge delegate to our function
						Func<string, string, string> currentDelegate = OnUnityVSProjectFilesChange;
						Type handlerType = unityVSAssembly.GetType(UnityVSProjectFileGenerationEventHandlerType);
						Delegate unityVSBridgeDelegate = Delegate.CreateDelegate(handlerType, currentDelegate.Target, currentDelegate.Method);
						if (unityVSBridgeDelegate != null)
						{
							// Register with the event handler
							projectGeneration.SetValue(null, unityVSBridgeDelegate);
						}
						else
						{
							Debug.LogError("P4Connect - Could not create conversion delegate to UnityVS ProjectFileGenerator");
						}
					}
					else
					{
						Debug.LogError("P4Connect - Could not find ProjectFileGeneration.ProjectFileGeneration() in UnityVS namespace");
					}
				}
				else
				{
					Debug.LogError("P4Connect - Could not find ProjectFileGeneration class in UnityVS namespace");
				}
			}
			else
			{
				Debug.LogError("P4Connect - UnityVS Assembly doesn't appear to be loaded");
			}
		}

		/// <summary>
		/// Called when unityVS re-creates project files
		/// </summary>
		/// <param name="name">The project being modified</param>
		/// <param name="content">The content of the project file</param>
		/// <returns>modified content if desired, we don't, we just use this method as an event</returns>
		static string OnUnityVSProjectFilesChange(string name, string content)
		{
			if (Config.UnityVSSupport)
			{
				string[] files = new string[2];

				// First file is the solution file, which we derive from the project name
				files[0] = "UnityVS." + Main.ProjectName + ".sln";

				// Second file is the project file itself
				files[1] = name;

				Engine.CheckoutAssets(files);
			}

			// We don't touch the content
			return content;
		}

		// Called whenever the project files change
		public static void OnProjectWindowChanged()
		{
			// The following files don't exist unless you have UnityVS
			if (Config.UnityVSSupport)
			{
				// Build a list of project and solution files we may want to check out
				List<string> filesToTryAndCheckOut = new List<string>(10);

				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".CSharp.csproj"));
				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".CSharp.Editor.csproj"));
				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".CSharp.Plugins.csproj"));
				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".sln"));
				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".sln.DotSettings"));
				filesToTryAndCheckOut.Add(System.IO.Path.Combine(Main.RootPath, "UnityVS." + Main.ProjectName + ".UnityScript.Plugins.unityproj"));

				// These files may not exist (the -vs ones only exist if you have Visual Studio set up)
				// so don't try to add them and get an error if they don't exist
				List<string> filesToCheckOut = new List<string>(filesToTryAndCheckOut.Where(file => System.IO.File.Exists(file)));

				// Now pass those off to the Add method
				// The using statement will make sure the connection is Disposed (i.e. closed)
				Engine.CheckoutAssets(filesToCheckOut.ToArray());
			}
		}
	}
}
# Change User Description Committed
#1 12954 anis_sg Populate -o //guest/perforce_software/p4connect/...
//guest/anis_sg/perforce_software/p4connect/....
//guest/perforce_software/p4connect/src/P4Connect/P4Connect/P4Connect.UnityVSBridge.cs
#1 10940 Norman Morse Inital Workshop release of P4Connect.
Released under BSD-2 license