|
using System.Collections; |
|
using System.Collections.Generic; |
|
using UnityEngine; |
|
|
|
using JobTodo = AT.JobManager.JobRepeatBase.JobTodo; |
|
using JobToDoCondition = AT.JobManager.JobRepeatBase.JobToDoCondition; |
|
using JobAutoDropCondition = AT.JobManager.JobRepeatBase.JobAutoDropCondition; |
|
using JobEndAction = AT.JobManager.JobRepeatBase.JobEndAction; |
|
using JOB_STATE = AT.JobManager.JobRepeatBase.JOB_STATE; |
|
|
|
#if UNITY_EDITOR |
|
using UnityEditor; |
|
namespace AT.JobManager |
|
{ |
|
[CustomEditor(typeof(JobRepeatManager))] |
|
public class JobRepeatManagerEditor : Editor |
|
{ |
|
private JobRepeatManager manager; |
|
public override void OnInspectorGUI() |
|
{ |
|
manager = (JobRepeatManager)target; |
|
|
|
EditorGUILayout.BeginHorizontal(); |
|
if (GUILayout.Button("Add Empty Job")) |
|
{ |
|
int EmptyJobCount = manager.JobList.FindAll(job => job.key.Contains("EmptyJob")).Count; |
|
manager.AddDelegateJob(string.Format("EmptyJob_{0}", EmptyJobCount), null); |
|
} |
|
|
|
if (GUILayout.Button("Drop All Job")) |
|
{ |
|
if(manager.JobList.Count > 0) |
|
{ |
|
foreach(var jobItem in manager.JobList) |
|
{ |
|
DestroyImmediate(jobItem.gameObject); |
|
} |
|
manager.JobList.Clear(); |
|
} |
|
} |
|
|
|
EditorApplication.update(); |
|
|
|
EditorGUILayout.EndHorizontal(); |
|
DrawDefaultInspector(); |
|
} |
|
} |
|
} |
|
#endif |
|
|
|
namespace AT.JobManager |
|
{ |
|
[ExecuteInEditMode] |
|
public class JobRepeatManager : SingletonBase<JobRepeatManager> |
|
{ |
|
// Job Information Container - Job Data Struct With Delegate Job |
|
[SerializeField] protected List<JobRepeatBase> _jobList = new List<JobRepeatBase>(); |
|
public List<JobRepeatBase> JobList { get { return _jobList; } } |
|
|
|
// Coroutine Job Information Container - Job Data Struct With Coroutine Job |
|
[SerializeField] protected Dictionary<string, Coroutine> _coroutineJobList = new Dictionary<string, Coroutine>(); |
|
|
|
// Min DelayTime |
|
protected float m_MinDelayTime = 0.1f; |
|
public float MinDelayTime { get { return m_MinDelayTime; } set { m_MinDelayTime = value; } } |
|
|
|
/// <summary> |
|
/// Job RepeatManager > Adding Job |
|
/// <para>key = JobKeyName, |
|
/// todo = ExecuteFunctionPointer, |
|
/// delay = Update Sequence Delay(Seconds), |
|
/// repeatCount = Total Execute Count, |
|
/// parameter = params object[] : Your Parameter |
|
/// todoCondition = Execute Condition(true = Available Execute, false = Block Execute), |
|
/// autoDropCondition = Job Drop Condition(Flag : true = Drop, false = MoveNext)</para> |
|
/// </summary> |
|
public bool AddDelegateJob(string key, JobTodo toDo, float delay = 1.0f, int repeatCount = 0, object[] parameter = null, |
|
JobEndAction endActionWhenDrop = null, |
|
JobToDoCondition toDoCondition = null, JobAutoDropCondition autoDropCondition = null, bool isImmediately = true) |
|
{ |
|
// Already Registered Job Check |
|
if (JobList.Find(job => job.key.Equals(key)) != null) |
|
return false; |
|
|
|
GameObject JobObject = new GameObject(key); |
|
JobObject.transform.parent = this.transform; |
|
JobRepeatBase newJob = JobObject.AddComponent<JobRepeatBase>(); |
|
newJob.key = key; |
|
newJob.jobCoroutine = null; |
|
newJob.jobTodo = toDo; |
|
newJob.repeatDelay = delay; |
|
newJob.repeatCount = repeatCount; |
|
newJob.excuteCount = 0; |
|
newJob.jobToDoCheck = toDoCondition; |
|
newJob.jobAutoDropCheck = autoDropCondition; |
|
newJob.jobEndAction = endActionWhenDrop; |
|
newJob.state = JOB_STATE.JOB_STANDBY; |
|
newJob.worker = CoJobHandle(key); |
|
newJob.parameter = parameter; |
|
|
|
if(toDo == null) |
|
{ |
|
Debug.LogWarningFormat("Are You Sure Adding Empty Job? Todo Parameter is null (key:{0})", key); |
|
newJob.state = JOB_STATE.JOB_EMPTY; |
|
} |
|
|
|
newJob.repeatDelay = newJob.repeatDelay < m_MinDelayTime ? m_MinDelayTime : newJob.repeatDelay; |
|
JobList.Add(newJob); |
|
|
|
if (isImmediately) |
|
{ |
|
StartCoroutine(newJob.worker); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
/// <summary> |
|
/// Job RepeatManager > Coroutine Type Adding Job |
|
/// <para>key = JobKeyName, |
|
/// todo = Coroutine Type Todo, |
|
/// delay = Update Sequence Delay(Seconds), |
|
/// repeatCount = Total Execute Count, |
|
/// parameter = params object[] : Your Parameter |
|
/// todoCondition = Execute Condition(Flag : true = Available Execute, false = Block Execute), |
|
/// autoDropCondition = Job Drop Condition(Flag : true = Drop, false = MoveNext), |
|
/// </summary> |
|
public bool AddCoroutineJob(string key, IEnumerator coroutineJobTodo, float delay = 1.0f, int repeatCount = 0, object[] param = null, |
|
JobToDoCondition toDoCondition = null, JobAutoDropCondition autoDropCondition = null, |
|
bool isImmediately = true) |
|
{ |
|
// Already Registered Job Check |
|
if (JobList.Find(job => job.key.Equals(key)) != null) |
|
return false; |
|
|
|
GameObject JobObject = new GameObject(key); |
|
JobObject.transform.parent = this.transform; |
|
JobRepeatBase newJob = JobObject.AddComponent<JobRepeatBase>(); |
|
newJob.key = key; |
|
newJob.jobCoroutine = coroutineJobTodo; |
|
newJob.jobTodo = null; |
|
newJob.repeatDelay = delay; |
|
newJob.repeatCount = repeatCount; |
|
newJob.excuteCount = 0; |
|
newJob.jobToDoCheck = toDoCondition; |
|
newJob.jobAutoDropCheck = autoDropCondition; |
|
newJob.state = JOB_STATE.JOB_STANDBY; |
|
newJob.worker = CoJobHandle(key); |
|
newJob.parameter = param; |
|
|
|
if (coroutineJobTodo == null) |
|
{ |
|
Debug.LogWarningFormat("Are You Sure Adding Empty Job? Todo Parameter is null (key:{0})", key); |
|
newJob.state = JOB_STATE.JOB_EMPTY; |
|
} |
|
|
|
newJob.repeatDelay = newJob.repeatDelay < m_MinDelayTime ? m_MinDelayTime : newJob.repeatDelay; |
|
JobList.Add(newJob); |
|
|
|
if (isImmediately) |
|
{ |
|
StartCoroutine(newJob.worker); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
private void Start() |
|
{ |
|
StartCoroutine(CoAutoDropWorkers()); |
|
} |
|
|
|
public bool RemoveJob(string key) |
|
{ |
|
JobRepeatBase findJob = JobList.Find(job => job.key.Equals(key)); |
|
if (findJob == null) |
|
return false; |
|
|
|
DestroyImmediate(findJob.gameObject); |
|
return JobList.Remove(findJob); |
|
} |
|
|
|
public bool JobStart(string key) |
|
{ |
|
JobRepeatBase findJob = JobList.Find(job => job.key.Equals(key)); |
|
if (findJob == null) |
|
return false; |
|
|
|
StopCoroutine(findJob.worker); |
|
|
|
findJob.state = JOB_STATE.JOB_STANDBY; |
|
StartCoroutine(findJob.worker); |
|
return true; |
|
} |
|
|
|
public int JobDropAll() |
|
{ |
|
int droppedJobCount = 0; |
|
if(JobList.Count > 0) |
|
{ |
|
JobList.Clear(); |
|
droppedJobCount = transform.childCount; |
|
transform.DestroyAllChildren(); |
|
} |
|
|
|
return droppedJobCount; |
|
} |
|
|
|
public bool ChangeJobDelay(string key, float newDelay) |
|
{ |
|
JobRepeatBase findJob = JobList.Find(job => job.key.Equals(key)); |
|
if (findJob == null) |
|
return false; |
|
|
|
findJob.repeatDelay = newDelay; |
|
StopCoroutine(findJob.worker); |
|
|
|
findJob.state = JOB_STATE.JOB_STANDBY; |
|
StartCoroutine(findJob.worker); |
|
return true; |
|
} |
|
|
|
public bool ChangeRepeatCount(string key, int repeatCount) |
|
{ |
|
JobRepeatBase findJob = JobList.Find(job => job.key.Equals(key)); |
|
if (findJob == null) |
|
return false; |
|
|
|
findJob.repeatCount = repeatCount; |
|
StopCoroutine(findJob.worker); |
|
|
|
findJob.state = JOB_STATE.JOB_STANDBY; |
|
StartCoroutine(findJob.worker); |
|
return true; |
|
} |
|
|
|
public bool AddFunctionChain(string key, JobTodo Todo = null, JobToDoCondition toDoCheck = null, JobAutoDropCondition autoDropCondition = null, bool isExecuteImmediately = true) |
|
{ |
|
JobRepeatBase Job = JobList.Find(job => job.key.Equals(key)); |
|
if (Job == null) |
|
return false; |
|
|
|
StopCoroutine(Job.worker); |
|
|
|
Job.jobTodo += Todo; |
|
Job.jobToDoCheck += toDoCheck; |
|
Job.jobAutoDropCheck += autoDropCondition; |
|
|
|
if (Job.jobTodo == null) |
|
{ |
|
Job.state = JOB_STATE.JOB_EMPTY; |
|
return true; |
|
} |
|
|
|
if (isExecuteImmediately) |
|
{ |
|
Job.state = JOB_STATE.JOB_STANDBY; |
|
StartCoroutine(Job.worker); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
public bool RemoveFunctionChain(string key, JobTodo Todo = null, JobToDoCondition toDoCheck = null, |
|
JobAutoDropCondition autoDropCondition = null, bool isExecuteImmediately = true) |
|
{ |
|
JobRepeatBase Job = JobList.Find(job => job.key.Equals(key)); |
|
if (Job == null) |
|
return false; |
|
|
|
StopCoroutine(Job.worker); |
|
|
|
Job.jobTodo -= Todo; |
|
Job.jobToDoCheck -= toDoCheck; |
|
Job.jobAutoDropCheck -= autoDropCondition; |
|
|
|
if (Job.jobTodo == null) |
|
{ |
|
Job.state = JOB_STATE.JOB_EMPTY; |
|
return true; |
|
} |
|
|
|
if (isExecuteImmediately) |
|
{ |
|
Job.state = JOB_STATE.JOB_STANDBY; |
|
StartCoroutine(Job.worker); |
|
} |
|
return true; |
|
} |
|
|
|
public JobRepeatBase GetJobBase(string key) |
|
{ |
|
return JobList.Find(x => x.key == key); |
|
} |
|
|
|
private WaitForSeconds _dropManagingDelay = new WaitForSeconds(3.0f); |
|
private IEnumerator CoAutoDropWorkers() |
|
{ |
|
while (gameObject.activeSelf) |
|
{ |
|
var dropItems = JobList.FindAll(Job => Job.state == JOB_STATE.JOB_DROP); |
|
foreach(var dropItem in dropItems) |
|
{ |
|
dropItem.jobEndAction?.Invoke(dropItem.parameter); |
|
JobList.Remove(dropItem); |
|
DestroyImmediate(dropItem.gameObject); |
|
} |
|
yield return _dropManagingDelay; |
|
} |
|
} |
|
|
|
private IEnumerator CoJobHandle(string key) |
|
{ |
|
yield return null; |
|
|
|
JobRepeatBase findJob = JobList.Find(x => x.key == key); |
|
if (findJob == null) |
|
yield break; |
|
|
|
switch (findJob.state) |
|
{ |
|
case JOB_STATE.JOB_EMPTY: |
|
yield break; |
|
case JOB_STATE.JOB_STANDBY: |
|
if (findJob.jobToDoCheck != null) |
|
{ |
|
if (findJob.jobToDoCheck(findJob.parameter)) |
|
{ |
|
findJob.state = JOB_STATE.JOB_WORKING; |
|
|
|
findJob.jobTodo?.Invoke(findJob.parameter); |
|
if (findJob.jobCoroutine != null) |
|
yield return StartCoroutine(findJob.jobCoroutine); |
|
|
|
findJob.excuteCount++; |
|
if (findJob.excuteCount >= findJob.repeatCount && findJob.repeatCount != 0) |
|
findJob.state = JOB_STATE.JOB_DROP; |
|
else |
|
findJob.state = JOB_STATE.JOB_WAITING; |
|
} |
|
} |
|
else |
|
{ |
|
findJob.state = JOB_STATE.JOB_WORKING; |
|
findJob.jobTodo?.Invoke(findJob.parameter); |
|
if (findJob.jobCoroutine != null) |
|
yield return StartCoroutine(findJob.jobCoroutine); |
|
|
|
findJob.excuteCount++; |
|
if (findJob.excuteCount >= findJob.repeatCount && findJob.repeatCount != 0) |
|
findJob.state = JOB_STATE.JOB_DROP; |
|
else |
|
findJob.state = JOB_STATE.JOB_WAITING; |
|
} |
|
|
|
if (findJob.jobAutoDropCheck != null) |
|
{ |
|
if (findJob.jobAutoDropCheck(findJob.parameter)) |
|
{ |
|
findJob.state = JOB_STATE.JOB_DROP; |
|
break; |
|
} |
|
} |
|
break; |
|
case JOB_STATE.JOB_WAITING: |
|
WaitForSeconds WaitForDelay = new WaitForSeconds(findJob.repeatDelay); |
|
yield return WaitForDelay; |
|
findJob.state = JOB_STATE.JOB_STANDBY; |
|
break; |
|
case JOB_STATE.JOB_DROP: |
|
yield break; |
|
} |
|
|
|
yield return StartCoroutine(CoJobHandle(findJob.key)); |
|
} |
|
} |
|
|
|
} |
|
|