using System; using LibGit2Sharp.Core; using LibGit2Sharp.Handlers; namespace LibGit2Sharp { /// /// Class to handle the mapping between libgit2 progress_cb callback on the git_checkout_opts /// structure to the CheckoutProgressHandler delegate. /// internal class CheckoutCallbacks { /// /// The managed delegate (e.g. from library consumer) to be called in response to the checkout progress callback. /// private readonly CheckoutProgressHandler onCheckoutProgress; /// /// The managed delegate (e.g. from library consumer) to be called in response to the checkout notify callback. /// private readonly CheckoutNotifyHandler onCheckoutNotify; /// /// Constructor to set up native callback for given managed delegate. /// /// delegate to call in response to checkout progress_cb /// delegate to call in response to checkout notification callback. private CheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify) { this.onCheckoutProgress = onCheckoutProgress; this.onCheckoutNotify = onCheckoutNotify; } /// /// The method to pass for the native checkout progress callback. /// public progress_cb CheckoutProgressCallback { get { if (this.onCheckoutProgress != null) { return this.OnGitCheckoutProgress; } return null; } } /// /// The method to pass for the native checkout notify callback. /// public checkout_notify_cb CheckoutNotifyCallback { get { if (this.onCheckoutNotify != null) { return this.OnGitCheckoutNotify; } return null; } } /// /// Generate a delegate matching the signature of the native progress_cb callback and wraps the delegate. /// /// that should be wrapped in the native callback. /// delegate to call in response to checkout notification callback. /// The delegate with signature matching the expected native callback. internal static CheckoutCallbacks GenerateCheckoutCallbacks(CheckoutProgressHandler onCheckoutProgress, CheckoutNotifyHandler onCheckoutNotify) { return new CheckoutCallbacks(onCheckoutProgress, onCheckoutNotify); } /// /// The delegate with a signature that matches the native checkout progress_cb function's signature. /// /// The path that was updated. /// The number of completed steps. /// The total number of steps. /// Payload object. private void OnGitCheckoutProgress(IntPtr str, UIntPtr completedSteps, UIntPtr totalSteps, IntPtr payload) { if (onCheckoutProgress != null) { // Convert null strings into empty strings. FilePath path = LaxFilePathMarshaler.FromNative(str) ?? FilePath.Empty; onCheckoutProgress(path.Native, (int)completedSteps, (int)totalSteps); } } private int OnGitCheckoutNotify( CheckoutNotifyFlags why, IntPtr pathPtr, IntPtr baselinePtr, IntPtr targetPtr, IntPtr workdirPtr, IntPtr payloadPtr) { bool result = true; if (this.onCheckoutNotify != null) { FilePath path = LaxFilePathMarshaler.FromNative(pathPtr) ?? FilePath.Empty; result = onCheckoutNotify(path.Native, why); } return Proxy.ConvertResultToCancelFlag(result); } } }