Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

replay a list of functions and parameters

I have a series of functions that I want to have the following functionality.

  • When the function is called, add itself to a list of functions remembering the parameters and values
  • Allow the list of functions to be called at a later date

The different functions have a variety of different parameters and I'm struggling to think of an elegant way to do this. Any help would be appreciated.

like image 859
probably at the beach Avatar asked Dec 21 '11 01:12

probably at the beach


People also ask

What is function parameter in JavaScript?

Function parameters are the names listed in the function definition. Function arguments are the real values passed to (and received by) the function.

Which of the following function returns an array of all parameters provided to function?

func_get_args( ) returns an array of all parameters provided to the function, func_num_args( ) returns the number of parameters provided to the function, and func_get_arg( ) returns a specific argument from the parameters.

Which keyword is used to access the array of arguments of a function?

You can access specific arguments by calling their index. var add = function (num1, num2) { // returns the value of `num1` console. log(arguments[0]); // returns the value of `num2` console.

How can you get the type of arguments passed to a function?

There are two ways to pass arguments to a function: by reference or by value. Modifying an argument that's passed by reference is reflected globally, but modifying an argument that's passed by value is reflected only inside the function.


2 Answers

I think this would meet your needs, however the functions are not "adding themselves".

public class Recorder
{
    private IList<Action> _recording;
    public Recorder()
    {
        _recording = new List<Action>();
    }
    public void CallAndRecord(Action action)
    {
        _recording.Add(action);
        action();
    }
    public void Playback()
    {
        foreach(var action in _recording)
        {
            action();
        }
    }
}

//usage
var recorder = new Recorder();
//calls the functions the first time, and records the order, function, and args
recorder.CallAndRecord(()=>Foo(1,2,4));
recorder.CallAndRecord(()=>Bar(6));
recorder.CallAndRecord(()=>Foo2("hello"));
recorder.CallAndRecord(()=>Bar2(0,11,true));
//plays everything back
recorder.Playback();

One way to make the functions "add themselves" would be to use an AOP lib such as postsharp or linfu dynamic proxy, and add an interceptor which adds the function and args to the array. To do this would probably be more work than it would be worth IMO, as the above is much simpler and still achieves the desired functionality.

like image 103
Brook Avatar answered Sep 28 '22 06:09

Brook


There's hardly an elegant solution to this. Since you said the methods would all have different signature, there's no way to store them in a single array as delegates. With that out of the way, next you can try is using reflection, storing each parameter value in object[], storing the method as MethodInfo, and then invoking it.

Edit: This is what I could come up with:

    private Dictionary<MethodBase, object[]> methodCollection = new Dictionary<MethodBase, object[]>();

    public void AddMethod(MethodBase method, params object[] arguments)
    {
        methodCollection.Add(method, arguments);
    }

    private void MyMethod(int p1, string p2, bool p3)
    {
        AddMethod(System.Reflection.MethodInfo.GetCurrentMethod(), new object[] { p1, p2, p3 });
    }

    private void MyOtherMethod()
    {
        AddMethod(System.Reflection.MethodInfo.GetCurrentMethod(), new object[] { });
    }

Then just invoke with method.Invoke(method.ReflectedType, args)

like image 24
Tomislav Markovski Avatar answered Sep 28 '22 05:09

Tomislav Markovski