Skip to content

Instantly share code, notes, and snippets.

@kimsama
Last active March 21, 2016 14:05
Show Gist options
  • Select an option

  • Save kimsama/a0cf529f5e9f97bfa5a0 to your computer and use it in GitHub Desktop.

Select an option

Save kimsama/a0cf529f5e9f97bfa5a0 to your computer and use it in GitHub Desktop.
scrapped from http://answers.unity3d.com/questions/305882/how-do-i-invoke-functions-on-the-main-thread.html "If anyone is interested I reworked the Loom Class from @whydoidoit 's Unity Gems link to an EditorWindow. This way you can easily thread long processes without locking up the editor window."
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using System.Threading;
using System;
using System.IO;
using System.Linq;
public class LoomEditorWindow : EditorWindow {
public int maxThreads = 8;
private int numThreads;
private int _count;
private bool m_HasLoaded = false;
private List<Action> _actions = new List<Action>();
private List<DelayedQueueItem> _delayed = new List<DelayedQueueItem>();
private List<DelayedQueueItem> _currentDelayed = new List<DelayedQueueItem>();
private List<Action> _currentActions = new List<Action>();
public struct DelayedQueueItem
{
public float time;
public Action action;
}
protected void QueueOnMainThread(Action action)
{
QueueOnMainThread( action, 0f);
}
protected void QueueOnMainThread(Action action, float time)
{
if(time != 0)
{
lock(_delayed)
{
_delayed.Add(new DelayedQueueItem { time = Time.time + time, action = action});
}
}
else
{
lock (_actions)
{
_actions.Add(action);
}
}
}
protected Thread RunAsync(Action a)
{
while(numThreads >= maxThreads)
{
Thread.Sleep(1);
}
Interlocked.Increment(ref numThreads);
ThreadPool.QueueUserWorkItem(RunAction, a);
return null;
}
private void RunAction(object action)
{
try
{
((Action)action)();
}
catch
{
}
finally
{
Interlocked.Decrement(ref numThreads);
}
}
protected virtual void Start()
{
m_HasLoaded = true;
}
protected virtual void Update()
{
if(m_HasLoaded == false)
Start();
lock (_actions)
{
_currentActions.Clear();
_currentActions.AddRange(_actions);
_actions.Clear();
}
foreach(var a in _currentActions)
{
a();
}
lock(_delayed)
{
_currentDelayed.Clear();
_currentDelayed.AddRange(_delayed.Where(d=>d.time <= Time.time));
foreach(var item in _currentDelayed)
_delayed.Remove(item);
}
foreach(var delayed in _currentDelayed)
{
delayed.action();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment