using System; using System.Collections.Generic; using System.Collections.ObjectModel; using NaGet.SubCommands.SubTask; using NaGet.Tasks; namespace NaGet.SubCommands { /// /// NaGetタスク処理のパック /// public abstract class NaGetTaskSet2 : Task { /// /// サブタスクのハンドラ /// public virtual event EventHandler SubTaskEventRaised; /// /// タスク処理中の質問のハンドラ /// public event NaGetTaskQueryHandler TaskQueryRaised; /// /// サブタスクのリスト /// protected IList subTasks; /// /// 文字列で表現した作業一覧リスト /// protected IList taskSetNames; /// /// 現在実行中のサブタスクのインデックス /// private int currentSubTaskIndex = -1; /// /// 終了したか /// protected bool isDone = false; /// /// キャンセルされたか /// protected bool isCancelled = false; /// /// キャンセルが呼ばれたか /// protected bool cancelCalled = false; /// /// キャンセル呼び出し時のイベント。 /// protected event Action onCancelCalled; public NaGetTaskSet2() { } /// /// キャンセル処理を行う /// /// 成功したか否か public override bool Cancel() { if (Cancelable) { if (! cancelCalled && ! isDone) { cancelCalled = true; if (onCancelCalled != null) { onCancelCalled(null); } if (currentSubTask != null && currentSubTask.Cancelable) { return currentSubTask.Cancel(); } else { return true; } } else { return false; } } else { return false; } } public virtual int CurrentTaskSetIndex { get { return currentSubTaskIndex; } } public override bool Done { get { return isDone; } } public virtual bool Cancelled { get { return isCancelled; } } public override bool Running { get { return CurrentTaskSetIndex >= 0 && !Done; } } /// /// 文字列で表現した作業一覧リスト /// public virtual IList TaskSetNames { get { return new ReadOnlyCollection(taskSetNames); } } /// /// 現在の進捗を戻す。 /// /// 作業の状態 /// サブタスクの進捗 /// 現在の進捗 protected virtual float GetProgressPercent(TaskEventType type, float subTaskProgress) { if (CurrentTaskSetIndex >= 0) { if (subTaskProgress >= 0) { return (CurrentTaskSetIndex * 100 + subTaskProgress) / taskSetNames.Count; } switch (type) { case TaskEventType.STARTED: return 0; case TaskEventType.COMPLETED: return 100; case TaskEventType.COMPLETED_SUBTASK: return ((CurrentTaskSetIndex+1) * 100) / taskSetNames.Count; default: return (CurrentTaskSetIndex * 100) / taskSetNames.Count; } } return -1; } #region フラグ処理の便利メソッド /// /// 開始時に関するフラグの処理を行う /// protected virtual void NotifyStarted() { currentSubTaskIndex = 0; isDone = false; } /// /// キャンセル中断時に関するフラグの処理を行う /// protected virtual void NotifyCancelled() { isCancelled = true; isDone = true; } /// /// 成功終了時に関するフラグの処理を行う /// protected virtual void NotifyCompleted() { isDone = true; } /// /// サブタスク実行を次へ。 /// protected virtual void NotifyGoToNextSubTask() { currentSubTaskIndex ++; } /// /// サブタスク実行をジャンプする。 /// /// ジャンプ先のサブタスク番号 protected virtual void NotifyGoToSubTask(int subTaskIndex) { currentSubTaskIndex = subTaskIndex; } #endregion #region サブタスク実行時における便利メソッド protected virtual string currentSubTaskName { get { return taskSetNames[currentSubTaskIndex]; } } protected virtual NaGetSubTask currentSubTask { get { return subTasks[currentSubTaskIndex]; } } protected virtual bool hasMoreSubTask { get { return currentSubTaskIndex < taskSetNames.Count; } } #endregion #region TaskEvent便利メソッド protected virtual void RaiseTaskSetEvent(TaskEventType type, string message) { RaiseTaskSetEvent(type, message, GetProgressPercent(type, -1)); } protected virtual void ReceivedErrorData(object sender, NaGet.Utils.AnyDataEventArgs e) { if (! string.IsNullOrEmpty(e.Data)) { RaiseTaskSetEvent(TaskEventType.WARNING, e.Data); } } protected virtual void ReceivedOutputData(object sender, NaGet.Utils.AnyDataEventArgs e) { if (! string.IsNullOrEmpty(e.Data)) { RaiseTaskSetEvent(TaskEventType.INFO, e.Data); } } protected virtual NaGetTaskQueryResult RaiseTaskSetQueryEvent(string message, NaGetTaskQueryResult selection) { if (TaskQueryRaised != null) { return TaskQueryRaised(this, new NaGetTaskQueryArgs(message, selection)); } return NaGetTaskQueryResult.CANCELED_AUTOMATICALLY; } #endregion #region サブタスク初期化・登録便利メソッド protected void initSubTask() { taskSetNames = new List(); subTasks = new List(); } /// /// サブタスクを登録する /// /// 名称 /// サブタスクオブジェクト protected void registSubTask(string name, NaGetSubTask task) { taskSetNames.Add(name); subTasks.Add(task); // サブタスクのイベントをSubTaskEventRaised,TaskEventRaisedに転送 task.TaskEventRaised += new EventHandler(subtaskEventTransformer); } /// /// サブタスクのイベントをSubTaskEventRaised,TaskEventRaisedに転送する関数 /// /// 送信元のサブタスク /// イベントオブジェクト private void subtaskEventTransformer(object sender, TaskEventArgs e) { if (SubTaskEventRaised != null) { SubTaskEventRaised(sender, e); } if (e.ProgressPercent >= 0) { RaiseTaskSetEvent(TaskEventType.PING, null, GetProgressPercent(TaskEventType.PING, e.ProgressPercent)); } } #endregion } }