Advertisement
Guest User

Untitled

a guest
Feb 22nd, 2017
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.94 KB | None | 0 0
  1. using UnityEngine;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System;
  5.  
  6. /// <summary>
  7. ///
  8. /// Delay actions. Keeps all actions in a sorted list to minimize overhead.
  9. ///
  10. /// </summary>
  11. /// <usage>
  12. ///
  13. /// DelayedAction.time.Delay( 0.2f, MyAction );
  14. /// DelayedAction.unscaledTime.Delay( 0.3f, () => Debug.Log("Hello!") );
  15. ///
  16. /// DelayedAction.time.At( 13.37f, WinGame );
  17. /// </usage>
  18. public class DelayedAction : MonoBehaviour
  19. {
  20.  
  21. static GameObject CreateGhost (string name)
  22. {
  23. var go = new GameObject (name);
  24. GameObject.DontDestroyOnLoad (go);
  25. go.hideFlags = HideFlags.HideAndDontSave;
  26. return go;
  27. }
  28.  
  29. static DelayedActionTime _time;
  30.  
  31. public static DelayedActionTime time {
  32. get {
  33. if (_time == null)
  34. _time = CreateGhost ("DelayedAction").AddComponent<DelayedActionTime> ();
  35. return _time;
  36. }
  37. }
  38.  
  39. static DelayedActionUnscaledTime _unscaledTime;
  40.  
  41. public static DelayedActionUnscaledTime unscaledTime {
  42. get {
  43. if (_unscaledTime == null)
  44. _unscaledTime = CreateGhost ("DelayedActionUnscaledTime").AddComponent<DelayedActionUnscaledTime> ();
  45. return _unscaledTime;
  46. }
  47. }
  48.  
  49. static DelayedActionRealtimeSinceStartup _realtimeSinceStartup;
  50.  
  51. public static DelayedActionRealtimeSinceStartup realtimeSinceStartup {
  52. get {
  53. if (_realtimeSinceStartup == null)
  54. _realtimeSinceStartup = CreateGhost ("DelayedActionRealtimeSinceStartup").AddComponent<DelayedActionRealtimeSinceStartup> ();
  55. return _realtimeSinceStartup;
  56. }
  57. }
  58.  
  59. /// <summary>
  60. /// Creates the using custom time. You are responsible for this object! it does not go away by itself
  61. /// </summary>
  62. /// <returns>The using custom time.</returns>
  63. /// <param name="timeProvider">Time provider.</param>
  64. public static DelayedActionCustomTime CreateUsingCustomTime (Func <float> timeProvider)
  65. {
  66. var component = CreateGhost ("DelayedActionCustomTime").AddComponent<DelayedActionCustomTime> ();
  67. component.timeProvider = timeProvider;
  68. return component;
  69. }
  70.  
  71. }
  72.  
  73. public struct TimedAction
  74. {
  75. public Action action;
  76. public float time;
  77. public int id;
  78.  
  79. public TimedAction (float time, Action action, int id)
  80. {
  81. this.time = time;
  82. this.action = action;
  83. this.id = id;
  84. }
  85. }
  86.  
  87. public class DelayedActionRealtimeSinceStartup : DelayedActionBase
  88. {
  89.  
  90. public float now{ get { return Time.realtimeSinceStartup; } }
  91.  
  92. void Update ()
  93. {
  94. while (sortedActions.Count > 0 && sortedActions [0].time < Time.realtimeSinceStartup) {
  95. var a = sortedActions [0];
  96. sortedActions.RemoveAt (0);
  97. a.action.Invoke ();
  98. }
  99. }
  100.  
  101. public int Delay (float delay, Action action)
  102. {
  103. return At (Time.realtimeSinceStartup + delay, action);
  104. }
  105.  
  106. public override int At (float time, Action action)
  107. {
  108.  
  109. if (time <= Time.realtimeSinceStartup) { //Execute directly
  110. action.Invoke ();
  111. uniqueId++; //Had to return a valid id even if not added to sortedActions
  112. return uniqueId - 1;
  113. }
  114.  
  115. return base.At (time, action);
  116. }
  117.  
  118. }
  119.  
  120. public class DelayedActionTime : DelayedActionBase
  121. {
  122.  
  123. public float now{ get { return Time.time; } }
  124.  
  125. void Update ()
  126. {
  127. while (sortedActions.Count > 0 && sortedActions [0].time < Time.time) {
  128. var a = sortedActions [0];
  129. sortedActions.RemoveAt (0);
  130. a.action.Invoke ();
  131. }
  132. }
  133.  
  134. public int Delay (float delay, Action action)
  135. {
  136. return At (Time.time + delay, action);
  137. }
  138.  
  139. public override int At (float time, Action action)
  140. {
  141.  
  142. if (time <= Time.time) { //Execute directly
  143. action.Invoke ();
  144. uniqueId++; //Had to return a valid id even if not added to sortedActions
  145. return uniqueId - 1;
  146. }
  147.  
  148. return base.At (time, action);
  149. }
  150.  
  151. }
  152.  
  153. public class DelayedActionUnscaledTime : DelayedActionBase
  154. {
  155.  
  156. public float now{ get { return Time.unscaledTime; } }
  157.  
  158. void Update ()
  159. {
  160. while (sortedActions.Count > 0 && sortedActions [0].time < Time.unscaledTime) {
  161. var a = sortedActions [0];
  162. sortedActions.RemoveAt (0);
  163. a.action.Invoke ();
  164. }
  165. }
  166.  
  167. public int Delay (float delay, Action action)
  168. {
  169. return At (Time.unscaledTime + delay, action);
  170. }
  171.  
  172. public override int At (float time, Action action)
  173. {
  174.  
  175. if (time <= Time.unscaledTime) { //Execute directly
  176. action.Invoke ();
  177. uniqueId++; //Had to return a valid id even if not added to sortedActions
  178. return uniqueId - 1;
  179. }
  180.  
  181. return base.At (time, action);
  182. }
  183.  
  184. }
  185.  
  186. public class DelayedActionBase : MonoBehaviour
  187. {
  188. internal int uniqueId = int.MinValue;
  189. internal List<TimedAction> sortedActions = new List<TimedAction> (32);
  190.  
  191. internal float lastTime { get; private set; }
  192.  
  193. public virtual int At (float time, Action action)
  194. {
  195.  
  196. if (time < lastTime) { //Optimization, lastTime can be removed
  197. for (int i = 0; i < sortedActions.Count; ++i) {
  198. if (sortedActions [i].time > time) {
  199. sortedActions.Insert (i, new TimedAction (time, action, uniqueId++));
  200. return uniqueId - 1;
  201. }
  202. }
  203. }
  204. lastTime = time;
  205. sortedActions.Add (new TimedAction (time, action, uniqueId++));
  206. return uniqueId - 1;
  207. }
  208.  
  209. public void Remove (int? id)
  210. {
  211. if (id.HasValue) {
  212. Remove (id.Value);
  213. }
  214. }
  215.  
  216. public void Remove (int id)
  217. {
  218. for (int i = 0; i < sortedActions.Count; ++i) {
  219. if (sortedActions [i].id == id) {
  220. sortedActions.RemoveAt (i);
  221. return;
  222. }
  223. }
  224. }
  225.  
  226. }
  227.  
  228. public class DelayedActionCustomTime : DelayedActionBase
  229. {
  230.  
  231. static float stub ()
  232. {
  233. return 0;
  234. }
  235.  
  236. public Func<float> timeProvider = stub;
  237. //Set this to something useful at runtime.
  238.  
  239. public float now{ get { return timeProvider (); } }
  240.  
  241. void Update ()
  242. {
  243. while (sortedActions.Count > 0 && sortedActions [0].time < timeProvider ()) {
  244. var a = sortedActions [0];
  245. sortedActions.RemoveAt (0);
  246. a.action.Invoke ();
  247. }
  248. }
  249.  
  250. public int Delay (float delay, Action action)
  251. {
  252. return At (timeProvider () + delay, action);
  253. }
  254.  
  255. public override int At (float time, Action action)
  256. {
  257.  
  258. if (time <= timeProvider ()) { //Execute directly
  259. action.Invoke ();
  260. uniqueId++; //Had to return a valid id even if not added to sortedActions
  261. return uniqueId - 1;
  262. }
  263.  
  264. return base.At (time, action);
  265. }
  266. }
  267.  
  268. public class DelayedTest : MonoBehaviour
  269. {
  270. void Start ()
  271. {
  272. float now = Time.time;
  273. var t = DelayedAction.time;
  274.  
  275. t.At (10f, () => LogTime ("G 10"));
  276. t.At (1f, () => LogTime ("C 1"));
  277. t.At (3f, () => LogTime ("F 3"));
  278. t.At (2f, () => LogTime ("E 2"));
  279. t.At (1.5f, () => LogTime ("D at time 115"));
  280. t.At (0.1f, () => LogTime ("B 0.1"));
  281. int id = t.Delay (0.0f, () => LogTime ("A unremovable 0"));
  282. t.Remove (id);
  283. id = t.Delay (0.0000001f, () => LogTime ("A removable 0.0000001"));
  284. t.Remove (id);
  285.  
  286. t.At ((int)Time.time + 1, SpawnDelay);
  287.  
  288. var u = DelayedAction.unscaledTime;
  289.  
  290. // u.At (1, () => Time.timeScale = 0f);
  291. // u.At (1, () => LogTime ("--------- Timescale at " + Time.timeScale));
  292. // u.At (2, () => LogTime ("Unscaled 2"));
  293. // u.At (5, () => Time.timeScale = 2f);
  294. // u.At (5, () => LogTime ("--------- Timescale at " + Time.timeScale));
  295. // u.At (6, () => LogTime ("Unscaled 6"));
  296.  
  297. var r = DelayedAction.realtimeSinceStartup;
  298. r.At (2, () => LogTime ("Realtime At 2"));
  299. r.At (r.now + 1, () => LogTime ("Realtime At >now< + 1"));
  300.  
  301. var c = DelayedAction.CreateUsingCustomTime (GetMusicTime);
  302. c.Delay (1, () => LogTime ("Custom time 1"));
  303.  
  304. t.Delay (0.1f, () => Heavy (3));
  305. }
  306.  
  307. void Heavy (int left)
  308. {
  309. var t = DelayedAction.time;
  310.  
  311. if (left <= 0) {
  312. t.At (t.lastTime, Done);
  313. return;
  314. }
  315.  
  316. LogTime ("Heavy add random delays " + countMax);
  317.  
  318. for (int i = 0; i < countMax; ++i) {
  319. t.Delay (UnityEngine.Random.value * 5, Add);
  320. }
  321. t.Delay (2.5f, () => Heavy (left - 1));
  322.  
  323. }
  324.  
  325. void Done ()
  326. {
  327. LogTime ("Added " + count + "/" + countMax);
  328. }
  329.  
  330. void Add ()
  331. {
  332. count++;
  333. }
  334.  
  335. int countMax = 1000;
  336. int count = 0;
  337.  
  338. float GetMusicTime ()
  339. {
  340. return 0;
  341. }
  342.  
  343. void LogTime (string message = null)
  344. {
  345. Debug.LogFormat ("{3} | time {0:0.00} unscaled {1:0.00} realtime {2:0.00}", Time.time, Time.unscaledTime, Time.realtimeSinceStartup, message);
  346. }
  347.  
  348. bool on;
  349.  
  350. void SpawnDelay ()
  351. {
  352. Debug.Log ("SpawnDelay " + Time.time);
  353.  
  354. on = !on;
  355.  
  356. if (on) {
  357. DelayedAction.time.At ((int)Time.time + 1, SpawnDelay);
  358. } else {
  359. DelayedAction.time.Delay (1, SpawnDelay);
  360. }
  361. }
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement