P4Connect.ChangeManager.cs #1

  • //
  • guest/
  • anis_sg/
  • perforce_software/
  • p4connect/
  • src/
  • P4Connect/
  • P4Connect/
  • P4Connect.ChangeManager.cs
  • View
  • Commits
  • Open Download .zip Download (9 KB)
using UnityEngine;
using UnityEditor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Perforce.P4;
using log4net;

namespace P4Connect
{

    public static class ChangeManager
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(ChangeManager));

        public static int DEFAULT_CHANGE = -1;

        static Dictionary<int, Changelist> _changes = new Dictionary<int, Changelist>();

        static float poll_rate = 3 * 60;
        static DateTime last_refresh;

        public static void Initialize()
        {
            last_refresh = DateTime.Now;

            Engine.OnOperationPerformed += OnEngineOperationPerformed;
        }

        /// <summary>
        /// This functions gets called when P4Connect does *something* to files
        /// In this case we refresh the involved change list
        /// </summary>
        static void OnEngineOperationPerformed(PerforceConnection aConnection, List<FileAndMeta> aFilesAndMetas)
        {
            // ToDo: Check the changelist associated to the files  DEFAULT_CHANGE for now....
            // ToDo: Refresh the involved changelist in prep for a localOpenedFiles() call later

            RefreshChange(aConnection, DEFAULT_CHANGE);
        }

        /// <summary>
		/// Periodic Update method, triggers refreshes, not used 
		/// </summary>
        static void Update()
        {
            if (Config.ValidConfiguration)
            {
                DateTime now = DateTime.Now;
                TimeSpan delta = now - last_refresh;

                if (delta.TotalSeconds > poll_rate)
                {
                    last_refresh = now;
                    log.Debug("ChangeManager Tick");
                    RefreshAll();
                }
            }
        }

        // Update the list of change lists
        public static void Refresh()
        {
            if (Config.ValidConfiguration)
            {
                using (PerforceConnection con = new PerforceConnection())
                {
                    RefreshChangeLists(con);
                }
            }         
        }

        // Refresh the files in a specific change lists
        public static void Refresh(int changeId)
        {
            if (Config.ValidConfiguration)
            {
                if (_changes.Count == 0 || (!_changes.ContainsKey(changeId)))
                {
                    RefreshAll();
                }
                using (PerforceConnection con = new PerforceConnection())
                {
                    RefreshChange(con, changeId);
                }
            } 
        }

        // Get all changelists and all files in them
        public static void RefreshAll()
        {
            if (Config.ValidConfiguration)
            {
                using (PerforceConnection con = new PerforceConnection())
                {
                    RefreshChangeLists(con, true);
                }
            }
        }

        public static IList<Changelist> Changelists
        {
            get
            {
                if (_changes.Count == 0 )
                {
                    RefreshAll();
                }

                return (_changes.Values.ToList());
            }
        }

        public static Changelist GetChangelist(int id)
        {
            if (_changes.ContainsKey(id))
            {
                return (_changes[id]);
            }
                
            return null;
        }

        public static string ChangeIdToString(int id)
        {
            if (id <= DEFAULT_CHANGE)
                return "default";

            return id.ToString();
        }

        public static IEnumerable<string> LocalOpenedFiles
        {
            get
            {
                if (!Config.ValidConfiguration)
                    yield break;

                if (_changes.Count == 0 || (! _changes.ContainsKey(DEFAULT_CHANGE)))
                {
                    Refresh();
                    Refresh(DEFAULT_CHANGE);
                }
                //log.DebugFormat("Changelists: {0}", _changes.Count);

                IList<FileMetaData> files = _changes[DEFAULT_CHANGE].Files;
                
                if (files != null && files.Count > 0)
                {
                    //log.DebugFormat("file: {0}", Logger.ToStringNullSafe(files[0].ClientPath.Path));
                    for (int i = 0; i < files.Count; ++i)
                    {
                        yield return Utils.ClientPathToLocalPath(files[i].ClientPath.Path);
                    }
                }
            }
        }

        /// <summary>
        /// Helper method to check if a file is in the depot list
        /// </summary>
        /// <param name="arOpenedFiles"></param>
        /// <param name="match"></param>
        /// <returns></returns>
        public static bool Contains(Predicate<FileMetaData> aMatch)
        {
            foreach (FileMetaData fmd in _changes[DEFAULT_CHANGE].Files)
            {
                if (aMatch(fmd))
                    return true;
            }
            return false;
        }

        // Collect all the Changelists and put them in the _changes dictionary
        static void RefreshChangeLists(PerforceConnection p4conn, bool all = false)
        {
            if (Config.ValidConfiguration)
            {
                //log.DebugFormat("RefreshChangeLists {0}", all.ToString());

                _changes.Clear();

                // Create a placeholder for the default change
                Changelist dchange = new Changelist() { Description = "Default", OwnerName = Config.Username, ClientId = Config.Workspace };
                dchange.initialize(p4conn.P4Connection);
                _changes.Add(DEFAULT_CHANGE, dchange);
                if (all)
                {
                    RefreshChange(p4conn, DEFAULT_CHANGE);
                }
                

                // Now go get the numbered change lists
                ChangesCmdOptions opts = new ChangesCmdOptions(ChangesCmdFlags.FullDescription, null, 0, ChangeListStatus.Pending, null);

                IList<Changelist> allChanges = p4conn.P4Depot.GetChangelists(opts, null);
                if (allChanges != null)
                {
                    foreach (var change in allChanges)
                    {
                        change.initialize(p4conn.P4Connection);
                        _changes.Add(change.Id, change);
                        if (all)
                        {
                            RefreshChange(p4conn, change.Id);
                        }
                    }
                }
            }
        }

        // Collect all the files and shelves for a specific changelist
        static void RefreshChange( PerforceConnection p4conn, int changeId)
        {
            if (Config.ValidConfiguration)
            {
                //log.DebugFormat("RefreshChange {0}", changeId);

                if (changeId <= DEFAULT_CHANGE)
                {
                    RefreshDefaultChange(p4conn);
                    return;
                }

                // Get files for the specified changeId
                _changes[changeId].initialize(p4conn.P4Connection);

                // Get shelves too
                P4Command cmd = new P4Command(p4conn.P4Connection, "describe", true, "-S", changeId.ToString());

                P4CommandResult results = cmd.Run();
                if ((results.Success) && (results.TaggedOutput != null) && (results.TaggedOutput.Count > 0))
                {
                    _changes[changeId].FromChangeCmdTaggedOutput(results.TaggedOutput[0], true, string.Empty, false);  // FIXME: the time zone is wrong.
                }
            }
        }

        static void RefreshDefaultChange(PerforceConnection p4conn)
        {
            if (Config.ValidConfiguration)
            {
                // Use "p4 opened -c default"  to get the opened files in the default changelist
                Options opts = new Options();
                opts["-c"] = "default";
                opts["-C"] = Config.Workspace;
                IList<File> allOpenedFiles = p4conn.P4Depot.GetOpenedFiles(null, opts);

                if (!_changes.ContainsKey(DEFAULT_CHANGE))
                {
                    RefreshChangeLists(p4conn, false);    // Changelists dictionary needs to be constructed first
                }

                //Debug.Log("Resetting Default Change");
                _changes[DEFAULT_CHANGE].Files.Clear();  // Clear out old list of files

                if (allOpenedFiles != null)
                {
                    foreach (File fd in allOpenedFiles)
                    {
                        FileMetaData fmd = fd;
                       // log.Debug("file: " + Logger.ToStringNullSafe(fmd.ClientPath));
                        _changes[DEFAULT_CHANGE].Files.Add(fmd);
                    }
                }
                else
                {
                    //log.Debug("allOpenedFiles returned null");
                }
            }
        }
    }
}
# 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.ChangeManager.cs
#4 12862 Norman Morse Fixed problem with an empty default change list not refresshing.
Fixed crash in is_ignored
Removed a lot of log output
#3 12565 Norman Morse Integrated from Dev Branch
Made ChangeManager into Static Class.
Improved close window behavior for when connection is invalid
Fixed localOpenFiles not updating on submit
#2 12553 Norman Morse integrate from internal main
Build fixes for EC.
Major changes to Configuration and re-initialization code.
Bug fixes
#1 12512 Norman Morse Integrate from Dev branch, preparing for Beta3 release
//guest/norman_morse/dev/p4connect/src/P4Connect/P4Connect/P4Connect.ChangeManager.cs
#4 12501 Norman Morse Rewrote Configuration Window.

Provided buttons to read values and to save configurations.
Removed P4Config settings, replaced with P4Config button and reports to Debug.Log()
Removed SaveConfigurationAsset Setting,  replaced with "Save as Asset" button.

Made Connection Configuration read only while connected.

Made dialogs disappear if they become disconnected during OnGui()
Bumped Beta Value.
#3 12480 Norman Morse Fixed crash in logging.
Worked on UI issues.
Cleaned up some connection usage.
Still looking for the problem with pending changes.
#2 12473 Norman Morse More minor fixes to logging and config
#1 12445 Norman Morse Integrated log4net and nunit into P4Connect.

Still need cleanup and debugging,  good enough for dev tree

Also added ChangeManager and ChangeLists Classes for future use with multiple changes.