Modelowanie_Wirtualnych_Swi.../Library/PackageCache/com.unity.collab-proxy@1.3.9/Editor/Presenters/ChangesPresenter.cs

319 lines
11 KiB
C#
Raw Normal View History

2021-04-11 20:41:04 +02:00
using System;
using System.Linq;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Unity.Cloud.Collaborate.Assets;
using Unity.Cloud.Collaborate.Components.Menus;
using Unity.Cloud.Collaborate.Models;
using Unity.Cloud.Collaborate.Models.Structures;
using Unity.Cloud.Collaborate.Utilities;
using Unity.Cloud.Collaborate.Views;
using UnityEngine;
using UnityEngine.Assertions;
namespace Unity.Cloud.Collaborate.Presenters
{
internal class ChangesPresenter : IChangesPresenter
{
[NotNull]
readonly IChangesView m_View;
[NotNull]
readonly IChangesModel m_Model;
[NotNull]
readonly IMainModel m_MainModel;
bool m_IsStarted;
public ChangesPresenter([NotNull] IChangesView view, [NotNull] IChangesModel model, [NotNull] IMainModel mainModel)
{
m_View = view;
m_Model = model;
m_MainModel = mainModel;
}
/// <inheritdoc />
public void Start()
{
Assert.IsFalse(m_IsStarted, "The presenter has already been started.");
m_IsStarted = true;
m_Model.UpdatedChangeList += OnUpdatedChangeList;
m_Model.OnUpdatedSelectedChanges += OnUpdatedPartiallySelectedChanges;
m_Model.BusyStatusUpdated += OnBusyStatusUpdated;
m_Model.StateChanged += OnStateChanged;
m_MainModel.RemoteRevisionsAvailabilityChange += OnRemoteRevisionsAvailabilityChange;
m_MainModel.ConflictStatusChange += OnConflictStatusChange;
PopulateInitialData();
}
/// <inheritdoc />
public void Stop()
{
Assert.IsTrue(m_IsStarted, "The presenter has already been stopped.");
m_IsStarted = false;
m_Model.UpdatedChangeList -= OnUpdatedChangeList;
m_Model.OnUpdatedSelectedChanges -= OnUpdatedPartiallySelectedChanges;
m_Model.BusyStatusUpdated -= OnBusyStatusUpdated;
m_Model.StateChanged -= OnStateChanged;
m_MainModel.RemoteRevisionsAvailabilityChange -= OnRemoteRevisionsAvailabilityChange;
m_MainModel.ConflictStatusChange -= OnConflictStatusChange;
}
/// <summary>
/// Refresh state from the model.
/// </summary>
void OnStateChanged()
{
PopulateInitialData();
}
/// <summary>
/// Populate the view with the initial data from the model.
/// </summary>
void PopulateInitialData()
{
m_View.SetRevisionSummary(m_Model.SavedRevisionSummary);
m_View.SetSearchQuery(m_Model.SavedSearchQuery);
m_View.SetBusyStatus(m_Model.Busy);
m_Model.RequestInitialData();
}
/// <summary>
/// Event handler to receive updated remote changes available status.
/// </summary>
/// <param name="available">Whether or not remote changes are available.</param>
protected void OnRemoteRevisionsAvailabilityChange(bool available)
{
UpdatePublishButton();
}
/// <summary>
/// Event handler to receive updated busy status.
/// </summary>
/// <param name="busy">New busy status.</param>
void OnBusyStatusUpdated(bool busy)
{
m_View.SetBusyStatus(busy);
}
/// <summary>
/// Event handler for when the model reports an updated change list.
/// </summary>
protected void OnUpdatedChangeList()
{
UpdatePublishButton();
UpdateChangeList();
}
/// <summary>
/// Request the change or conflict list depending on the state of the model. The result is then given to the
/// view to populate itself. Fire and forget method -- must be run on main thread.
/// </summary>
void UpdateChangeList()
{
Assert.IsTrue(Threading.IsMainThread, "Updating the change lists must be done from the main thread.");
// Fetch and send data to the UI depending on what's the current display mode.
if (m_Model.Conflicted)
{
Task.Run(() => m_Model.GetConflictedEntries(m_Model.SavedSearchQuery))
.ContinueWith(r => m_View.SetConflicts(r.Result), TaskScheduler.FromCurrentSynchronizationContext());
}
else
{
Task.Run(() => m_Model.GetAllEntries(m_Model.SavedSearchQuery))
.ContinueWith(r => m_View.SetChanges(r.Result), TaskScheduler.FromCurrentSynchronizationContext());
}
}
/// <summary>
/// Inform view to refresh its selections.
/// </summary>
protected void OnUpdatedPartiallySelectedChanges()
{
UpdatePublishButton();
m_View.SetSelectedChanges();
}
/// <summary>
/// Update changelist display in response to the conflict status changing.
/// </summary>
/// <param name="conflicted">New conflicted status.</param>
protected void OnConflictStatusChange(bool conflicted)
{
UpdatePublishButton();
UpdateChangeList();
}
/// <inheritdoc />
public bool UpdateEntryToggle(string path, bool toggled)
{
var result = m_Model.UpdateEntryToggle(path, toggled);
m_View.SetToggledCount(ToggledCount);
UpdatePublishButton();
return result;
}
/// <inheritdoc />
public int ToggledCount => m_Model.ToggledCount;
/// <inheritdoc />
public int TotalCount => m_Model.TotalCount;
/// <inheritdoc />
public int ConflictedCount => m_Model.ConflictedCount;
/// <inheritdoc />
public bool Searching => !string.IsNullOrEmpty(m_Model.SavedSearchQuery);
/// <inheritdoc />
public void RequestPublish()
{
Assert.IsFalse(Searching, "Cannot publish while searching");
m_Model.RequestPublish(m_Model.SavedRevisionSummary, m_Model.GetToggledEntries().Select(i => i.Entry).ToList());
}
/// <inheritdoc />
public void RequestDiscard(IChangeEntry entry)
{
if (m_View.DisplayDialogue(StringAssets.confirmDiscardChangesTitle,
StringAssets.confirmDiscardChangeMessage, StringAssets.discardChanges,
StringAssets.cancel))
{
m_Model.RequestDiscard(entry);
}
}
/// <summary>
/// Discard all toggled entries. Fire and forget method -- must be called on main thread.
/// </summary>
void RequestDiscardToggled()
{
var entries = m_Model.GetToggledEntries(m_Model.SavedSearchQuery).Select(e => e.Entry).ToList();
if (m_View.DisplayDialogue(StringAssets.confirmDiscardChangesTitle,
string.Format(StringAssets.confirmDiscardChangesMessage, entries.Count), StringAssets.discardChanges,
StringAssets.cancel))
{
m_Model.RequestBulkDiscard(entries);
}
}
/// <summary>
/// Update the state of the publish button in the view based on the state of the model.
/// </summary>
void UpdatePublishButton()
{
if (m_Model.Conflicted)
{
m_View.SetPublishEnabled(false, StringAssets.cannotPublishWhileConflicted);
}
else if (m_MainModel.RemoteRevisionsAvailable)
{
m_View.SetPublishEnabled(false, StringAssets.cannotPublishWithIncomingChanges);
}
else if (m_Model.ToggledCount < 1)
{
m_View.SetPublishEnabled(false, StringAssets.cannotPublishWithoutFiles);
}
else if (Searching)
{
m_View.SetPublishEnabled(false, StringAssets.cannotPublishWhileSearching);
}
else
{
m_View.SetPublishEnabled(true);
}
}
/// <inheritdoc />
public void RequestDiffChanges(string path)
{
m_Model.RequestDiffChanges(path);
}
/// <inheritdoc />
public void SetSearchQuery(string query)
{
var value = StringUtility.TrimAndToLower(query);
m_Model.SavedSearchQuery = value;
m_View.SetSearchQuery(query);
UpdateChangeList();
UpdatePublishButton();
}
/// <inheritdoc />
public void SetRevisionSummary(string message)
{
m_View.SetRevisionSummary(message);
m_Model.SavedRevisionSummary = message;
}
/// <inheritdoc />
public int GroupOverflowEntryCount => 1;
/// <inheritdoc />
public void OnClickGroupOverflow(float x, float y)
{
new FloatingMenu()
.AddEntry(StringAssets.menuDiscardToggledChanges, RequestDiscardToggled, ToggledCount > 0)
.SetOpenDirection(MenuUtilities.OpenDirection.DownLeft)
.Open(x, y);
}
/// <inheritdoc />
public int ConflictGroupOverflowEntryCount => 2;
/// <inheritdoc />
public void OnClickConflictGroupOverflow(float x, float y)
{
new FloatingMenu()
.AddEntry(StringAssets.useMyChanges, OnBulkUseMine, true)
.AddEntry(StringAssets.useRemoteChanges, OnBulkUseRemote, true)
.SetOpenDirection(MenuUtilities.OpenDirection.DownLeft)
.Open(x, y);
}
/// <summary>
/// Perform bulk choose mine on all conflicted entries.
/// </summary>
void OnBulkUseMine()
{
m_Model.RequestChooseMine(m_Model.GetConflictedEntries().Select(e => e.Entry.Path).ToArray());
}
/// <summary>
/// Perform bulk choose theirs on all conflicted entries.
/// </summary>
void OnBulkUseRemote()
{
m_Model.RequestChooseRemote(m_Model.GetConflictedEntries().Select(e => e.Entry.Path).ToArray());
}
/// <inheritdoc />
public void RequestShowConflictedDifferences(string path)
{
m_Model.RequestShowConflictedDifferences(path);
}
/// <inheritdoc />
public void RequestChooseMerge(string path)
{
m_Model.RequestChooseMerge(path);
}
/// <inheritdoc />
public void RequestChooseMine(string path)
{
m_Model.RequestChooseMine(new [] { path });
}
/// <inheritdoc />
public void RequestChooseRemote(string path)
{
m_Model.RequestChooseRemote(new [] { path });
}
}
}