Clean up cancellation patterns in callbacks and other small cleanups.

This commit is contained in:
Jameson Miller 2013-10-18 14:56:24 -04:00
Родитель 981f43909c
Коммит bd736e2d13
14 изменённых файлов: 47 добавлений и 74 удалений

Просмотреть файл

@ -116,7 +116,7 @@ namespace LibGit2Sharp.Tests
var scd = BuildSelfCleaningDirectory();
Repository.Clone(url, scd.DirectoryPath,
onTransferProgress: _ => { transferWasCalled = true; return 0; },
onTransferProgress: _ => { transferWasCalled = true; return true; },
onCheckoutProgress: (a, b, c) => checkoutWasCalled = true);
Assert.True(transferWasCalled);

Просмотреть файл

@ -61,7 +61,7 @@ namespace LibGit2Sharp.Tests
public void CanPushABranchTrackingAnUpstreamBranch()
{
bool packBuilderCalled = false;
Handlers.PackBuilderProgressHandler packBuilderCb = (x, y, z) => { packBuilderCalled = true; return false; };
Handlers.PackBuilderProgressHandler packBuilderCb = (x, y, z) => { packBuilderCalled = true; return true; };
AssertPush(repo => repo.Network.Push(repo.Head));
AssertPush(repo => repo.Network.Push(repo.Branches["master"]));

Просмотреть файл

@ -78,8 +78,8 @@ namespace LibGit2Sharp.Tests.TestHelpers
/// <param name="referenceName">Name of reference being updated.</param>
/// <param name="oldId">Old ID of reference.</param>
/// <param name="newId">New ID of reference.</param>
/// <returns>0 on success; a negative value to abort the process.</returns>
public int RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId)
/// <returns>True to continue, false to cancel.</returns>
public bool RemoteUpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId)
{
// assert that we have not seen this reference before
Assert.DoesNotContain(referenceName, ObservedReferenceUpdates.Keys);
@ -97,7 +97,7 @@ namespace LibGit2Sharp.Tests.TestHelpers
Assert.Equal(referenceUpdate.NewId, newId);
}
return 0;
return true;
}
/// <summary>

Просмотреть файл

@ -100,14 +100,14 @@ namespace LibGit2Sharp
IntPtr workdirPtr,
IntPtr payloadPtr)
{
int result = 0;
bool result = true;
if (this.onCheckoutNotify != null)
{
FilePath path = LaxFilePathMarshaler.FromNative(pathPtr) ?? FilePath.Empty;
result = onCheckoutNotify(path.Native, why) ? 0 : 1;
result = onCheckoutNotify(path.Native, why);
}
return result;
return Proxy.ConvertResultToCancelFlag(result);
}
}
}

Просмотреть файл

@ -3,7 +3,6 @@ using LibGit2Sharp.Handlers;
namespace LibGit2Sharp.Core
{
//
internal class PackbuilderCallbacks
{
private readonly PackBuilderProgressHandler onPackBuilderProgress;
@ -33,7 +32,7 @@ namespace LibGit2Sharp.Core
private int OnGitPackBuilderProgress(int stage, uint current, uint total, IntPtr payload)
{
return onPackBuilderProgress((PackBuilderStage) stage, (int)current, (int)total) ? -1 : 0;
return Proxy.ConvertResultToCancelFlag(onPackBuilderProgress((PackBuilderStage)stage, (int)current, (int)total));
}
}
}

Просмотреть файл

@ -1134,6 +1134,7 @@ namespace LibGit2Sharp.Core
return handle;
}
}
public static void git_push_set_callbacks(
PushSafeHandle push,
NativeMethods.git_push_transfer_progress pushTransferProgress,
@ -2524,6 +2525,19 @@ namespace LibGit2Sharp.Core
{ typeof(bool), value => git_config_parse_bool(value) },
{ typeof(string), value => value },
};
/// <summary>
/// Helper method for consistent conversion of return value on
/// Callbacks that support cancellation from bool to native type.
/// True indicates that function should continue, false indicates
/// user wants to cancel.
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
internal static int ConvertResultToCancelFlag(bool result)
{
return result ? 0 : -1;
}
}
}
// ReSharper restore InconsistentNaming

Просмотреть файл

@ -32,7 +32,7 @@ namespace LibGit2Sharp.Core
private int OnGitTransferProgress(uint current, uint total, UIntPtr bytes, IntPtr payload)
{
return onPushTransferProgress((int)current, (int)total, (long)bytes) ? -1 : 0;
return Proxy.ConvertResultToCancelFlag(onPushTransferProgress((int)current, (int)total, (long)bytes));
}
}
}

Просмотреть файл

@ -18,20 +18,15 @@
/// <param name="referenceName">Name of the updated reference.</param>
/// <param name="oldId">Old ID of the reference.</param>
/// <param name="newId">New ID of the reference.</param>
/// <returns>Return negative integer to cancel.</returns>
public delegate int UpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId);
/// <summary>
/// Delegate definition to handle Completion callback.
/// </summary>
public delegate int CompletionHandler(RemoteCompletionType remoteCompletionType);
/// <returns>True to continue, false to cancel.</returns>
public delegate bool UpdateTipsHandler(string referenceName, ObjectId oldId, ObjectId newId);
/// <summary>
/// Delegate definition for transfer progress callback.
/// </summary>
/// <param name="progress">The <see cref="TransferProgress"/> object containing progress information.</param>
/// <returns>Return negative integer to cancel.</returns>
public delegate int TransferProgressHandler(TransferProgress progress);
/// <returns>True to continue, false to cancel.</returns>
public delegate bool TransferProgressHandler(TransferProgress progress);
/// <summary>
/// Delegate definition for callback reporting push network progress.
@ -39,7 +34,7 @@
/// <param name="current">The current number of objects sent to server.</param>
/// <param name="total">The total number of objects to send to the server.</param>
/// <param name="bytes">The number of bytes sent to the server.</param>
/// <returns>True to cancel.</returns>
/// <returns>True to continue, false to cancel.</returns>
public delegate bool PushTransferProgressHandler(int current, int total, long bytes);
/// <summary>
@ -48,7 +43,7 @@
/// <param name="stage">The current stage progress is being reported for.</param>
/// <param name="current">The current number of objects processed in this this stage.</param>
/// <param name="total">The total number of objects to process for the current stage.</param>
/// <returns>True to cancel.</returns>
/// <returns>True to continue, false to cancel.</returns>
public delegate bool PackBuilderProgressHandler(PackBuilderStage stage, int current, int total);
/// <summary>

Просмотреть файл

@ -95,7 +95,6 @@ namespace LibGit2Sharp
/// <param name="remote">The remote to fetch</param>
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
/// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param>
/// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param>
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
@ -104,7 +103,6 @@ namespace LibGit2Sharp
Remote remote,
TagFetchMode? tagFetchMode = null,
ProgressHandler onProgress = null,
CompletionHandler onCompletion = null,
UpdateTipsHandler onUpdateTips = null,
TransferProgressHandler onTransferProgress = null,
Credentials credentials = null)
@ -113,7 +111,7 @@ namespace LibGit2Sharp
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true))
{
var callbacks = new RemoteCallbacks(onProgress, onTransferProgress, onCompletion, onUpdateTips, credentials);
var callbacks = new RemoteCallbacks(onProgress, onTransferProgress, onUpdateTips, credentials);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
if (tagFetchMode.HasValue)
@ -212,7 +210,7 @@ namespace LibGit2Sharp
// Load the remote.
using (RemoteSafeHandle remoteHandle = Proxy.git_remote_load(repository.Handle, remote.Name, true))
{
var callbacks = new RemoteCallbacks(null, null, null, null, pushOptions.Credentials);
var callbacks = new RemoteCallbacks(null, null, null, pushOptions.Credentials);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
Proxy.git_remote_set_callbacks(remoteHandle, ref gitCallbacks);

Просмотреть файл

@ -16,13 +16,11 @@ namespace LibGit2Sharp
/// </summary>
/// <param name="network">The <see cref="Network"/> being worked with.</param>
/// <param name="branch">The branch to push.</param>
/// <param name="onPushStatusError">Handler for reporting failed push updates.</param>
/// <param name="pushOptions"><see cref="PushOptions"/> controlling push behavior</param>
/// <exception cref="LibGit2SharpException">Throws if either the Remote or the UpstreamBranchCanonicalName is not set.</exception>
public static void Push(
this Network network,
Branch branch,
PushStatusErrorHandler onPushStatusError = null,
PushOptions pushOptions = null)
{
network.Push(new[] { branch }, pushOptions);

Просмотреть файл

@ -27,12 +27,16 @@ namespace LibGit2Sharp
public PushStatusErrorHandler OnPushStatusError { get; set; }
/// <summary>
/// Delegate to report push network transfer progress.
/// Delegate that progress updates of the network transfer portion of push
/// will be reported through. The frequency of progress updates will not
/// be more than once every 0.5 seconds (in general).
/// </summary>
public PushTransferProgressHandler OnPushTransferProgress { get; set; }
/// <summary>
/// Delagate to report pack builder progress.
/// Delegate that progress updates of the pack building portion of push
/// will be reported through. The frequency of progress updates will not
/// be more than once every 0.5 seconds (in general).
/// </summary>
public PackBuilderProgressHandler OnPackBuilderProgress { get; set; }
}

Просмотреть файл

@ -15,13 +15,11 @@ namespace LibGit2Sharp
internal RemoteCallbacks(
ProgressHandler onProgress = null,
TransferProgressHandler onDownloadProgress = null,
CompletionHandler onCompletion = null,
UpdateTipsHandler onUpdateTips = null,
Credentials credentials = null)
{
Progress = onProgress;
DownloadTransferProgress = onDownloadProgress;
Completion = onCompletion;
UpdateTips = onUpdateTips;
Credentials = credentials;
}
@ -38,11 +36,6 @@ namespace LibGit2Sharp
/// </summary>
private readonly UpdateTipsHandler UpdateTips;
/// <summary>
/// Completion callback. Corresponds to libgit2 Completion callback.
/// </summary>
private readonly CompletionHandler Completion;
/// <summary>
/// Managed delegate to be called in response to a git_transfer_progress_callback callback from libgit2.
/// This will in turn call the user provided delegate.
@ -70,11 +63,6 @@ namespace LibGit2Sharp
callbacks.update_tips = GitUpdateTipsHandler;
}
if (Completion != null)
{
callbacks.completion = GitCompletionHandler;
}
if (Credentials != null)
{
callbacks.acquire_credentials = GitCredentialHandler;
@ -122,36 +110,15 @@ namespace LibGit2Sharp
private int GitUpdateTipsHandler(IntPtr str, ref GitOid oldId, ref GitOid newId, IntPtr data)
{
UpdateTipsHandler onUpdateTips = UpdateTips;
int result = 0;
bool shouldContinue = true;
if (onUpdateTips != null)
{
string refName = LaxUtf8Marshaler.FromNative(str);
result = onUpdateTips(refName, oldId, newId);
shouldContinue = onUpdateTips(refName, oldId, newId);
}
return result;
}
/// <summary>
/// Handler for libgit2 completion callback. Converts values
/// received from libgit2 callback to more suitable types
/// and calls delegate provided by LibGit2Sharp consumer.
/// </summary>
/// <param name="remoteCompletionType">Which operation completed.</param>
/// <param name="data">IntPtr to optional payload passed back to the callback.</param>
/// <returns>0 on success; a negative value to abort the process.</returns>
private int GitCompletionHandler(RemoteCompletionType remoteCompletionType, IntPtr data)
{
CompletionHandler completion = Completion;
int result = 0;
if (completion != null)
{
result = completion(remoteCompletionType);
}
return result;
return Proxy.ConvertResultToCancelFlag(shouldContinue);
}
/// <summary>
@ -162,14 +129,14 @@ namespace LibGit2Sharp
/// <returns>the result of the wrapped <see cref="TransferProgressHandler"/></returns>
private int GitDownloadTransferProgressHandler(ref GitTransferProgress progress, IntPtr payload)
{
int result = 0;
bool shouldContinue = true;
if (DownloadTransferProgress != null)
{
result = DownloadTransferProgress(new TransferProgress(progress));
shouldContinue = DownloadTransferProgress(new TransferProgress(progress));
}
return result;
return Proxy.ConvertResultToCancelFlag(shouldContinue);
}
private int GitCredentialHandler(out IntPtr cred, IntPtr url, IntPtr username_from_url, uint types, IntPtr payload)

Просмотреть файл

@ -560,7 +560,7 @@ namespace LibGit2Sharp
{
CheckoutCallbacks checkoutCallbacks = CheckoutCallbacks.GenerateCheckoutCallbacks(onCheckoutProgress, null);
var callbacks = new RemoteCallbacks(null, onTransferProgress, null, null, credentials);
var callbacks = new RemoteCallbacks(null, onTransferProgress, null, credentials);
GitRemoteCallbacks gitCallbacks = callbacks.GenerateCallbacks();
var cloneOpts = new GitCloneOptions

Просмотреть файл

@ -227,7 +227,6 @@ namespace LibGit2Sharp
/// <param name="remoteName">The name of the <see cref="Remote"/> to fetch from.</param>
/// <param name="tagFetchMode">Optional parameter indicating what tags to download.</param>
/// <param name="onProgress">Progress callback. Corresponds to libgit2 progress callback.</param>
/// <param name="onCompletion">Completion callback. Corresponds to libgit2 completion callback.</param>
/// <param name="onUpdateTips">UpdateTips callback. Corresponds to libgit2 update_tips callback.</param>
/// <param name="onTransferProgress">Callback method that transfer progress will be reported through.
/// Reports the client's state regarding the received and processed (bytes, objects) from the server.</param>
@ -235,7 +234,6 @@ namespace LibGit2Sharp
public static void Fetch(this IRepository repository, string remoteName,
TagFetchMode tagFetchMode = TagFetchMode.Auto,
ProgressHandler onProgress = null,
CompletionHandler onCompletion = null,
UpdateTipsHandler onUpdateTips = null,
TransferProgressHandler onTransferProgress = null,
Credentials credentials = null)
@ -244,7 +242,7 @@ namespace LibGit2Sharp
Ensure.ArgumentNotNullOrEmptyString(remoteName, "remoteName");
Remote remote = repository.Network.Remotes.RemoteForName(remoteName, true);
repository.Network.Fetch(remote, tagFetchMode, onProgress, onCompletion, onUpdateTips,
repository.Network.Fetch(remote, tagFetchMode, onProgress, onUpdateTips,
onTransferProgress, credentials);
}