合并代表以顺序运行而不是同时运行?

时间:2018-12-21 19:21:05

标签: c# unity3d delegates

我遇到了一个有趣的问题,我很难找到解决方法。

在Unity3D中,您可以延迟要在编辑器上运行的动作,因为立即运行该动作不会执行任何操作,即,用户界面执行该动作为时过早。

对于大多数操作而言,单个延迟呼叫通常就足够了,但有时并非如此。我不想手动链接多个EditorApplication.delayCall,而是想使用一个delay参数。

但是我很难找到必要的代码。

示例:

public static void RunDelayed([NotNull] Action action, int delay)
{
    if (action == null)
        throw new ArgumentNullException(nameof(action));

    if (delay <= 0)
        throw new ArgumentOutOfRangeException(nameof(delay));

    // 1. expected usage, action will run at next editor update
    EditorApplication.delayCall += () => { action(); };

    // 2. wanted usage, be able to delay it by N times, here by 3 times
    // as you can see, to delay by 3 times you have to build a chain of calls
    // which while simple, the number of delays are hard-coded by the amount of times
    // you pasted EditorApplication.delayCall += () =>

    EditorApplication.delayCall += () =>
        EditorApplication.delayCall += () =>
            EditorApplication.delayCall += () => { action(); };

    // 3. how can the statement above (no. 2) be modeled in a for loop instead ?
    for (var i = 0; i < delay; i++)
    {
        // here I want to do away with manually chaining
        // EditorApplication.delayCall += () => ... statements
        // in turn it allows me to delay by arbitrary N updates
    }
}

问题:

是否可以创建这样的委托,如果可以,那么如何?

参考:

https://docs.unity3d.com/ScriptReference/EditorApplication-delayCall.html

1 个答案:

答案 0 :(得分:1)

EditorApplication.delayCall += DelayCall.ByNumberOfEditorFrames(4, () => print("Foo"));

实施:

public static class DelayCall
{
    public static EditorApplication.CallbackFunction ByNumberOfEditorFrames(int n, Action a)
    {
        EditorApplication.CallbackFunction callback = null;

        callback = new EditorApplication.CallbackFunction(() =>
        {
            if (n-- <= 0)
            {
                a();
            }
            else
            {
                EditorApplication.delayCall += callback;
            }
        });

        return callback;
    }
}

工作原理:

返回维护计数器的回调。当回调被调用时,计数器递减。如果计数器大于零,则回调将自动重新订阅。如果计数器小于或等于零,则调用延迟的动作。