0

I was wandering if you could offer any guidance. I am currently writing a sprite class for a simple game engine. Previous engines I have used allow functionality to "Connect" an external function to a signal, emitted when an animation finishes.

E.g.

  • create the sprite object
  • create the external function
  • connect the external function to the sprites completion signal
  • When the signal is emitted the external function is called.

This function does not necessarily share any data with the sprite, its purely game logic timing functionality. E.g player scores a goal, "Congrats" sprite animation is triggered, then the on completion function will add an amount to the players score.

I have looked into it and it looks like I need to use a callback function/ function ptr but I don't have any experience using them as of yet.

Any help would be greatly appreciated.

Linus Kleen
  • 33,871
  • 11
  • 91
  • 99

2 Answers2

1

In c++ a function pointer can be used like this:

#include <iostream>

//defining a type that is a 'function that returns void and takes an int'
typedef void FnPtr( int i ); 

//this is a 'function that returns void and takes an int'
void AFunction( int i )
{
    std::cout << "AFunction Called!";
}

//a function that accepts a pointer to a 'function that returns void and takes an int'
void AFunctionThatTakesAFnPtrAsAnArg( FnPtr* fn )
{
    //store the pointer to use "later".
    FnPtr* local = fn;
    .
    .
    .
    //use it.
    local( 3 );
}

int main( int, char** )
{
    AFunctionThatTakesAFnPtrAsAnArg( AFunction );
}

Note the function can be global, or a static class member. If you want to call into a function in an object instance then see this - particularly my answer! :-) What is a C++ delegate?

EDIT: To better fit questions asked in comments:

    #include <iostream>

typedef void FnPtr(); 

void AFunction()
{
    std::cout << "Animation done";
}

class Sprite
{
public:
    void SetFnPointer( FnPtr* fn )
    {
        m_Fn = fn;
    }

    void DoAnimation()
    {
        m_Fn();
    }

private:
    FnPtr* m_Fn;
};

int main( int, char** )
{
    Sprite s;
    s.SetFnPointer( AFunction );
    s.DoAnimation();
}
Community
  • 1
  • 1
Grimm The Opiner
  • 1,778
  • 11
  • 29
  • Thanks, to actually use the function will you just call *fn(). Also what is the Local(3) call. I am unfamiliar with this. – Martin Smith Apr 03 '12 at 10:28
  • Also to fit this into my scenario, my function will not return anything and take no parameters so will my sprite class contain typdef void FnPtr(void) and then the void AFunctionThatTakesAFnPtrAsAnArg( FnPtr *fn). on sprite creation I will pass in my function pointer whcih i will store, then at the right time call AFunctionThatTakesAFnPtrAsAnArg(savedFunctionPtr). – Martin Smith Apr 03 '12 at 10:36
  • @Martin Smith I've added more to the answer to fit your issue; yes, you are right about your typedef if you have no arguments. HTH. – Grimm The Opiner Apr 03 '12 at 11:14
  • you don't want to implement the slots/signals yourself. trust me :-) – Alex Kremer Apr 03 '12 at 11:23
0

Take a look at http://www.boost.org/doc/libs/1_49_0/doc/html/signals.html or http://libsigc.sourceforge.net/

The boost::signals library is really easy to use:

boost::signal<void(float)> update_sig;

Then somewhere in your game logic (some_client_class):

update_sig.connect( boost::bind(&some_client_class::callback, this, _1) );

And finally in your core update (main run loop of your game for example):

float delta = cur_time - last_update_time;
update_sig(delta); // executes all connected slots

Good luck :)

Alex Kremer
  • 1,876
  • 17
  • 18