Aceria_
Aceria_

Reputation: 13

Accept any type as delegate parameter

I'm trying to set up a system that allows me to easily set up delays in Unity3D (in C#), doing this without any parameters or simple parameters works just fine, but I'd like the system to be flexible enough to allow for any kind of callback.

For example, in the Start method it should call PrintString after 5 seconds:

public string str = "something";
void Start(){
    SB.Delay(5, PrintString, str);
}

public void PrintString(string pr){
    Debug.Log(pr);
}

The Delay method creates a new SBTimer that's added to a list of SBTimer. I then loop over that list elsewhere to run all the

public static void Delay<T>(float delay, SBTimer.CallbackParam<T> cb, T arg){
    delays.Add(new SBTimer(delay, cb, arg));
}

This is where the issue arises, and I have no clue how to proceed. This is the SBTimer class, or at least how I'd like it to work:

public class SBTimer{
public delegate void Callback();
public Callback _callback = null;

public delegate void CallbackParam<T>(T arg);
public Callback _callbackparam = null;
public T _arg;


public float _delay = 0f;

public SBTimer(float delay, Callback cb){
    _delay = delay;
    _callback = cb;
}

public SBTimer(float delay, CallbackParam<T> cb, T arg){
    _delay = delay;
    _callback = cb;
    _arg = arg;
}

public DoUpdate(){ //stuff here }
}

The only way I've gotten this to work so far is if I make SBTimer a generic class, but that would then complicate the update loop (which is simply this right now: )

void Update () {
    SB.OnUpdate();
}

Does anyone know how to solve this issue or perhaps know of a different way to get a similar result?

Upvotes: 1

Views: 106

Answers (1)

Servy
Servy

Reputation: 203817

This type doesn't need to bother supporting this. Simply accept an Action and support no other delegates. If the caller would like to call a method that has parameters and provide those parameters they can use a lambda to close over the values in question, giving you your Action but actually calling the method they want when it is invoked:

public class SBTimer
{
    private Action callback;
    private float delay;

    public SBTimer(float delay, Action callback)
    {
        this.delay = delay;
        this.callback = callback;
    }
    //todo actual implementation
}

public class Foo
{
    public string str = "something";
    void Start()
    {
        new SBTimer(5, () => PrintString(str));
    }

    public void PrintString(string pr)
    {
    }
}

Upvotes: 1

Related Questions