using UnityEditor; using UnityEngine; using System; using System.Collections.Generic; using System.Linq; using System.Text; using log4net; namespace P4Connect { public class PostProcessorRequest { public DateTime Created; public HashSet<string> Imported; public HashSet<string> Deleted; public string[] MovedTo; public string[] MovedFrom; public PostProcessorRequest( String[] importedAssets, String[] deletedAssets, String[] movedToAssets, String[] movedFromAssets) { Imported = new HashSet<string>(importedAssets); Deleted = new HashSet<string>(deletedAssets); MovedTo = (string[]) movedToAssets.Clone(); MovedFrom = (string[]) movedFromAssets.Clone(); Created = DateTime.Now; } public new string ToString() { return string.Format("time: {0} import: {1} delete: {2} moveTo: {3} moveFrom: {4}", Created.ToShortTimeString(), Logger.StringArrayToString(Imported.ToArray()), Logger.StringArrayToString(Deleted.ToArray()), Logger.StringArrayToString(MovedTo), Logger.StringArrayToString(MovedFrom)); } } /// <summary> /// This class hooks onto the Asset Save/Delete/Move process and makes sure that /// Perforce is updated accordingly. It uses the perforce connection class /// (which internally uses Config to retrieve the connection settings) /// to open a connection to the server and add the required changes (add/checkout/delete/move). /// </summary> public class AssetPostProcessor : UnityEditor.AssetPostprocessor { private static readonly ILog log = LogManager.GetLogger(typeof(AssetPostProcessor)); public AssetPostProcessor() { EditorApplication.update += OnUpdate; // enable timer. // Initial setting of PostProcessorRequestQueue if (Config.PostProcessorRequestQueue == null) Config.PostProcessorRequestQueue = new Queue<PostProcessorRequest>(); } /// <summary> /// This function allows us to process the queue when we want to. /// </summary> /// <returns> Count of Pending PostProcessorRequests</returns> public static int DoPendingPostProcessorRequest() { if (!Config.ValidConfiguration) return -1; var cnt = Config.PostProcessorRequestQueue.Count; if (cnt > 0) { PostProcessorRequest request = Config.PostProcessorRequestQueue.Dequeue(); ProcessRequest(request); } return cnt; } /// <summary> /// Called from the Update() function /// </summary> public void OnUpdate() { // Periodically look for pending work. if (Config.ValidConfiguration) { DoPendingPostProcessorRequest(); } } [MenuItem("Assets/Perforce/DoPostprocessorWork", false, 100)] public static void DoWorkMenu() { if (DoPendingPostProcessorRequest() <= 0) Debug.Log("Nothing Pending"); } /// <summary> /// Actually process the Post Processor Event /// The Event is stored in the req structure /// </summary> /// <param name="req">Unity OnPostProcess Request</param> public static void ProcessRequest(PostProcessorRequest req) { #if DEBUG // Debug.Log("Processing: " + req.ToString()); #endif // Find all files which are both deleted and imported. These are "replaced" - They should be Checked Out. var replaced = req.Deleted.Intersect(req.Imported).ToList(); if (replaced.Count > 0) { req.Deleted.ExceptWith(replaced); // remove replaced files from the delete list req.Imported.ExceptWith(replaced); // remove replaced files from the imported list Engine.CheckoutAssets(replaced.ToArray()); } if (req.Deleted.Any()) { Engine.DeleteAssets(req.Deleted.ToArray()); } req.Imported.RemoveWhere(Utils.IsDirectoryAsset); // Perforce doesn't support directories, file paths create directories as side effects if (req.Imported.Any()) { Engine.CreateAssets(req.Imported.ToArray()); } if (req.MovedTo.Length > 0) { Engine.MoveAssets(req.MovedTo, req.MovedFrom); } } public static void OnPostprocessAllAssets( String[] aImportedAssets, String[] aDeletedAssets, String[] aMovedAssets, String[] aMovedFromAssetPaths) { // set up PostProcessorRequestQueue if needed if (Config.PostProcessorRequestQueue == null) Config.PostProcessorRequestQueue = new Queue<PostProcessorRequest>(); var req = new PostProcessorRequest(aImportedAssets, aDeletedAssets, aMovedAssets, aMovedFromAssetPaths); #if DEBUG // Debug.Log("Queuing: " + req.ToString()); #endif Config.PostProcessorRequestQueue.Enqueue(req); } } }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#1 | 21852 | cswiedler | Branch //guest/cswiedler/p4connect | ||
//guest/perforce_software/p4connect/main/src/P4Connect/P4Connect/P4Connect.AssetPostProcessor.cs | |||||
#3 | 20275 | Norman Morse |
Update source to match 2016.2 patch 2 release Much thrashing of source during refactor. Proper caching of asset statuses, reducing fstats issued. Some bug fixes by Liz Lam Cleanup of Pending changes, rework of initialization and play/stop play transitions |
||
#2 | 16350 | Norman Morse |
Minor Code Clean Up Minor Documentation Clean Up Changed Post Processor callback to ignore directories Added option to use Server Typemap |
||
#1 | 16209 | Norman Morse | Move entire source tree into "main" branch so workshop code will act correctly. | ||
//guest/perforce_software/p4connect/src/P4Connect/P4Connect/P4Connect.AssetPostProcessor.cs | |||||
#5 | 14193 | Norman Morse |
GA.7 release Refactor Pending Changes Resolve Submit issues. Fixed Menu entries. Handle mismatched file and meta states. |
||
#4 | 12553 | Norman Morse |
integrate from internal main Build fixes for EC. Major changes to Configuration and re-initialization code. Bug fixes |
||
#3 | 12512 | Norman Morse | Integrate from Dev branch, preparing for Beta3 release | ||
#2 | 12362 | Norman Morse |
Added Debug Logging for p4log Fixed some path comparison issues. Created a CaseSensitivity test |
||
#1 | 10940 | Norman Morse |
Inital Workshop release of P4Connect. Released under BSD-2 license |