Search code examples
c#encapsulationcoroutineyield-return

What is the most elegant way of encapsulating a multi-step calculation?


As a more specific example - I have a game loop and I want to have a method handle an animation.

This animation is, for the sake of this example, a call to a movement function.

Is there a way I can call this function and have it do... something when the animation is complete automatically?

The more basic implementation would be to have it return a value when completed, and have the caller continually check for this, but I seem to remember there are more elegant tricks.

I know nothing about co-routines or the yield keyword. could they be relevant here?


Solution

  • The answer largely is: it depends

    If the code is, as you say, a simple method call (that you have no control over), and that method call is being run in a loop (as opposed to being long-running), you are pretty much stuck with the "check return value" method.

    If it only a function, but is long-running, you can pass it a callback. Your function signature becomes:

    public void foo MyFunc(Action callback)
    {
       ...
       callback();
    }
    

    And you would call it with an Action delegate (of course any other delegate would be fine as long as you update the function signature). The callback would be called by foo when the operation was completed. This is usually done in a threading environment, since you could just wait for the call to return on a single thread.

    In a threaded environment, you could also just wait for the thread to Join if the thread termination would coincide with your "completion" condition.

    In the best case, this functionality is encapsulated into a class that manages the state between the looped method calls. In this case, you can simply raise an event that the using class registers for when the operation completes.

    The last is the most verbose option, but does allow for looped calls (as in a game loop) or threading and can call multiple functions on completion. If it makes sense in your use case, I would go with this option.