public static void PollOnUpdateUntilComplete(Func <bool> condition) { object obj = RunOnMainThread.pollingJobs; lock (obj) { RunOnMainThread.pollingJobs.Add(condition); } if (RunOnMainThread.ExecuteNow && RunOnMainThread.OnMainThread) { RunOnMainThread.RunAction(delegate { while (true) { RunOnMainThread.ExecuteAll(); object obj2 = RunOnMainThread.pollingJobs; lock (obj2) { if (RunOnMainThread.pollingJobs.Count == 0) { break; } } Thread.Sleep(100); } }); } }
private static void RemoveOnUpdateCallback(EditorApplication.CallbackFunction callback) { RunOnMainThread.Run(delegate { EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, callback); }, true); }
/// <summary> /// Enables / disables external package registries for Package Manager. /// </summary> static PackageManagerResolver() { logger.Log("Loaded PackageManagerResolver", level: LogLevel.Verbose); RunOnMainThread.Run(() => { // Load log preferences. VerboseLoggingEnabled = VerboseLoggingEnabled; }, runNow: false); }
public static bool TryExecuteAll() { if (RunOnMainThread.OnMainThread) { RunOnMainThread.ExecuteAll(); return(true); } return(false); }
/// <summary> /// Schedule the execution of a job. /// </summary> /// <param name="job">Action that will be called in future. This job should call /// Complete() to signal the end of the operation.</param> public void Schedule(Action job) { RunOnMainThread.Run(() => { jobs.Enqueue(job); if (jobs.Count == 1) { ExecuteNext(); } }, runNow: false); }
/// <summary> /// Start a web request on the main thread. /// </summary> /// <param name="method">Method to use.</param> /// <param name="url">Target URL.</param> /// <param name="headers">Headers to use when performing the request.</param> /// <param name="payload">Payload to send if this is a Post request, ignored otherwise.</param> /// <returns>PortableWebRequest instance that provides the status of the request.</returns> private static IPortableWebRequestStatus StartRequestOnMainThread( HttpMethod method, string url, IDictionary <string, string> headers, WWWForm form) { var requestStatus = new RequestStatus(); RunOnMainThread.Run(() => { requestStatus.Request = StartRequest(method, url, headers, form); }); return(requestStatus); }
/// <summary> /// Render the dialog according to the context. /// </summary> void OnGUI() { // Close the window if Option0String is empty. // After Unity reload assemblies, the EditorWindow will remain open but all the content // in the dialog will be cleared because dialogContext is not serializable. Therefore, // close the dialog after assembly reload. Close in the next editor frame or it may // generate error message like "OpenGL Context became invalid during rendering". // This is for Unity 5. if (String.IsNullOrEmpty(dialogContext.Option0String) && !terminating) { terminating = true; RunOnMainThread.Run(() => { Close(); }, runNow: false); } InitializeStyles(); Rect rect = EditorGUILayout.BeginVertical(); if (!String.IsNullOrEmpty(dialogContext.Title)) { GUILayout.Label(dialogContext.Title, EditorStyles.boldLabel); EditorGUILayout.Space(); } // Render the dialog message. GUILayout.Label(dialogContext.Message, DefaultMessageStyle); EditorGUILayout.Space(); // Render the additional context. if (dialogContext.RenderContentAction != null) { dialogContext.RenderContentAction(this); EditorGUILayout.Space(); } EditorGUILayout.BeginHorizontal(); // Render additional buttons before the option buttons. if (dialogContext.RenderButtonsAction != null) { dialogContext.RenderButtonsAction(this); } // Render option buttons. RenderOptionButtons(); EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); // Adjust the dialog window size according to the rendered content. // Rect returned by BeginVertical() can be zeroes for a couple of frames, therefore // ignoring resizing for those frames. if (rect.width != 0.0f && rect.height != 0.0f) { // Additional space at the bottom of the window. const float FILLER_WINDOWS_HEIGHT = 15.0f; float windowHeight = rect.height + FILLER_WINDOWS_HEIGHT; minSize = new Vector2(dialogContext.WindowWidth, windowHeight); maxSize = new Vector2(dialogContext.WindowWidth, windowHeight); } }
private static void AddOnUpdateCallback(EditorApplication.CallbackFunction callback) { RunOnMainThread.Run(delegate { EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Remove(EditorApplication.update, callback); EditorApplication.update = (EditorApplication.CallbackFunction)Delegate.Combine(EditorApplication.update, callback); if (ExecutionEnvironment.InBatchMode) { callback(); } }, true); }
/// <summary> /// Execute the condition and if it isn't complete, schedule the next execution. /// </summary> public void Execute() { if (condition != null) { if (!condition()) { jobId = RunOnMainThread.Schedule(() => { Execute(); }, IntervalInMilliseconds); } else { Stop(); } } }
/// <summary> /// Signal the end of job execution. /// </summary> public void Complete() { RunOnMainThread.Run(() => { var remaining = jobs.Count; if (remaining > 0) { jobs.Dequeue(); } if (remaining > 1) { ExecuteNext(); } }, runNow: false); }
/// <summary> /// Call initialization function on the main thread only when the condition is met. /// </summary> /// <param name="condition">When it returns true, call the initializer once. /// If null, initializer will be called in the next editor update.</param> /// <param name="initializer">Initialization function to be called when condition is met. /// </params> /// <param name="name">Name of the component to be initialized, for debug purpose.</param> /// <param name="logger">Logger to be used to report when initialization is finished.</param> public static void InitializeOnMainThread( Func <bool> condition, Func <bool> initializer, string name, Logger logger = null) { if (initializer == null) { return; } // Cache the flag to prevent string comparison in every frame during // PollOnUpdateUntilComplete() bool isExecuteMethodEnabled = ExecutionEnvironment.ExecuteMethodEnabled; // Delay initialization until condition is met. RunOnMainThread.PollOnUpdateUntilComplete(() => { if (condition != null && !condition()) { // If Unity is launched with -executeMethod, in some Unity versions, editor // update will never be called. As a result, PollOnUpdateUntilComplete() will // attempt to call this poll function repeating on current thread until it returns // true. Therefore, return true immediately and stop the polling in executeMethod // mode. return(isExecuteMethodEnabled); } bool result = false; try { result = initializer(); } catch (Exception e) { string errorMsg = String.Format("Exception thrown when initializing {0}: {1}", name, e.ToString()); if (logger != null) { logger.Log(errorMsg, level: LogLevel.Error); } else { Debug.LogError(errorMsg); } } if (logger != null) { logger.Log(String.Format("{0} initialization {1}", name, result ? "succeeded." : "failed."), level: result ? LogLevel.Verbose : LogLevel.Error); } return(true); }); }
public static void Run(Action job, bool runNow = true) { object obj = RunOnMainThread.jobs; bool flag; lock (obj) { flag = (RunOnMainThread.jobs.Count == 0); RunOnMainThread.jobs.Enqueue(job); } if ((flag || RunOnMainThread.ExecuteNow) && runNow && RunOnMainThread.OnMainThread) { RunOnMainThread.ExecuteAll(); } }
private static void ExecuteAll() { if (!RunOnMainThread.OnMainThread) { Debug.LogError("ExecuteAll must be executed from the main thread."); return; } RunOnMainThread.RunAction(delegate { while (RunOnMainThread.ExecuteNext()) { } int num; do { num = RunOnMainThread.ExecutePollingJobs(); }while (num > 0 && ExecutionEnvironment.InBatchMode); }); }
/// <summary> /// Schedule a job which is executed after the specified delay. /// </summary> /// <param name="job">Action to execute.</param> /// <param name="delayInMilliseconds">Time to wait for execution of this job.</param> /// <returns>ID of the scheduled job (always non-zero).</returns> public static int Schedule(Action job, double delayInMilliseconds) { ScheduledJob scheduledJob; lock (scheduledJobs) { scheduledJob = new ScheduledJob { Job = job, JobId = nextJobId, DelayInMilliseconds = ExecutionEnvironment.ExecuteMethodEnabled ? 0.0 : delayInMilliseconds }; scheduledJobs[nextJobId++] = scheduledJob; if (nextJobId == 0) { nextJobId++; } } RunOnMainThread.PollOnUpdateUntilComplete(scheduledJob.PollUntilExecutionTime); return(scheduledJob.JobId); }
public static int Schedule(Action job, double delayInMilliseconds) { object obj = RunOnMainThread.ScheduledJob.scheduledJobs; RunOnMainThread.ScheduledJob scheduledJob; lock (obj) { scheduledJob = new RunOnMainThread.ScheduledJob { Job = job, JobId = RunOnMainThread.ScheduledJob.nextJobId, DelayInMilliseconds = (!ExecutionEnvironment.InBatchMode) ? delayInMilliseconds : 0.0 }; RunOnMainThread.ScheduledJob.scheduledJobs[RunOnMainThread.ScheduledJob.nextJobId++] = scheduledJob; if (RunOnMainThread.ScheduledJob.nextJobId == 0) { RunOnMainThread.ScheduledJob.nextJobId++; } } RunOnMainThread.PollOnUpdateUntilComplete(new Func <bool>(scheduledJob.PollUntilExecutionTime)); return(scheduledJob.JobId); }
/// <summary> /// Stop periodic execution of the job. /// </summary> public void Stop() { RunOnMainThread.Cancel(jobId); jobId = 0; condition = null; }