Finite State Machine Confusion

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
	class Chara {
	public:
		Chara(int x,int y) : m_x(x), m_y(y) {}
		
		void patrol();
		void run();
		void attack();
		
		void update(){
			switch( m_state ){
			case PATROL_STATE: patrol();
				break;
			case RUN_STATE: run();
				break;
			case ATTACK_STATE: attack();
				break;
			}
		
		}
		
	private:
		int m_x;
		int m_y;
		state_t m_state;
	};


I am trying to make an AI for my game...
I read some stuff and I think FSM is what I need

Now, I am trying to remove the switch

I got the implementation in AS3 which allow function pointer to member function.. which is not really possible in C++

I google and find
http://www.boost.org/doc/libs/1_54_0/libs/statechart/doc/index.html
to be mention a lot

which I don't really understand what it does...
It just looks complicated


Can someone please explain to me what does the boost statechart do ?
or perhaps provide the solution without switch without using and sophisticated template or anything that looks hard

Last edited on
I got the implementation in AS3 which allow function pointer to member function.. which is not really possible in C++

It is really possible in C / C++

http://www.cprogramming.com/tutorial/function-pointers.html
no no,
I am talking about pointer to a member function of a class

perhaps an example could help
1
2
3
4
5
6
7
class X{
public:
   X() : q(p){}
   int p(){}
   int (*q)();
};


I don't think this is possible in C++
My C++ isn't as shiny as it used to be, but it's definitely possible.
http://www.umich.edu/~eecs381/handouts/Pointers_to_memberfuncs.pdf

-Albatross
wow, I just know that was possible...
They are just new to me

More question about this new thing then

Do I have to call this member function pointer from inside a class function
or can I call it from outside the class ??
Surely it would be of no use if it could not be called outside class. However it is OK:


Calling the member function on an object using a pointer-to-member-function
result = (object.*pointer_name)(arguments);
closed account (3qX21hU5)
Instead of using just a basic function pointer I would suggest the use of std::function which resides in #include <functional> . This will allow you to point to a member function and is using nice and tidy C++ code :). For example

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <iostream>
#include <functional>

using namespace std;

class Hello
{
    public:
        void sayHello() { std::cout << "Hello!!"; }
};


// There is a few ways to do it with member functions
int main()
{
    // This is for std::bind
    using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

    // This way you specify which object you wish to use every time for the function.
    Hello hello;
    
    // The first argument for std::bind is the member function you wish to use. The second argument is
    // the object you wish to use.
    std::function<void()> myFunction = std::bind(&Hello::sayHello, hello);
    myFunction();



    // This way you can pass in which object to use. I also used auto to save some space on this one.
    Hello hello2;
    
    // As before the first is the member function you wish to use, but this time the second argument is left open
    // and _1 means that you are expecting to pass in the extra argument he wants (In this case the object)
    // when you call the function object.
    auto myFunction2 = std::bind(&Hello::sayHello, _1);
    myFunction2(hello); // We are passing in the object "hello". So that object takes the place of the _1 argument.
    myFunction2(hello2); // This time the hello2 object takes the place of the _1 argument.
}


It is mainly the same as function pointers but I prefer to use function and bind instead. They also provide some extra benefits that just plain function pointers don't.

Here is the reference for each of them if you want to look up how they work.
http://www.cplusplus.com/reference/functional/bind/
http://www.cplusplus.com/reference/functional/function/function/
Last edited on
@rodiongork
It just that I never expose any pointer the outside the class
Because I think it's rather not safe
I just want to know
because When I try to call it from main it say something like
updatef is not declared in this scope

@Zereo
That was great,
I didn't know <functional> STL has this kind of functionality
I only know small portion of STL after all
Thanks for your advice
I will look more into functional ....
Thanks for now, I'll be back


closed account (D80DSL3A)
Interesting problem. I'm thinking the intent is to avoid the binding actions within main, but to automate the bindings in a class member function.

I picture the intent to be this:
A setState() function is called on an object in response to an event (mouse click, keystroke, etc.) which assigns a desired function to be called in an act() function being called at the frame rate.

@Zereo. Thanks for the intro to <functional> and std::bind.

@rmxhaha. Is this what you're trying to achieve?

Class A: Uses <functional> and std::bind to select the desired member function for the action. The functional is always bound to *this
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include <iostream>
#include <functional>

using namespace std;

// using functional and bind *this to a member function
class A
{
    private:
    void patrol(){ cout << "patrol "; }
    void run(){  cout << "run "; }
    void attack(){  cout << "attack "; }
    std::function<void()> actFunc;

    public:

    void setState(int State )
    {
        switch(State)
        {
            case 1: actFunc = std::bind(&A::patrol, *this); break;
            case 2: actFunc = std::bind(&A::run, *this); break;
            case 3: actFunc = std::bind(&A::attack, *this); break;
            default: actFunc = std::bind(&A::patrol, *this); break;
        }
    }

    void act() { actFunc(); }

    A(int State) { setState(State); }
};


For some reason, I like to see if I can perform a given task using only "elementary" methods. Class B below performs the same task using a regular function pointer to private static class functions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// using a plain pointer to static class functions. No need to #include<functional>
class B
{
    private:
    static void patrol(B* pA){ cout << "patrol "; }// these can be called only in class B member functions
    static void run(B* pA){  cout << "run "; }
    static void attack(B* pA){  cout << "attack "; }
    void(*pAct)(B*);// an ordinary function pointer

    public:

    void setState(int State )
    {
        switch(State)
        {
            case 1: pAct = B::patrol; break;
            case 2: pAct = B::run; break;
            case 3: pAct = B::attack; break;
            default: pAct = 0; break;
        }
    }

    void act()
    {
        if( pAct ) pAct(this);
        else cout << "no act specified \n";
    }

    B(int State) { setState(State); }
};

The usage for either class object in main() is the same:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
int main()
{
    //
	A a(1);// patrol
	a.act();
	a.setState(2);// run
	a.act();

	cout << endl;

	B b(3);// attack
	b.act();
	b.setState(1);// patrol
	b.act();

	cout << endl;
	return 0;
}

which produces (as hoped for):

patrol run
attack patrol
@fun2code
Yes, that's what I am trying to achieve

Looking at the code, I seem to like a raw pointer better than <functional>
Perhaps can someone explain to me the advantage of using <functional> bind and function ?

I know plenty enough about raw pointer but not <functional>
closed account (3qX21hU5)
Perhaps can someone explain to me the advantage of using <functional> bind and function ?


std::function can hold more then function pointers can. For example it can hold functors.

1
2
3
4
5
6
7
8
9
10
struct FooFunctor
{
    void operator()(int i) {
        std::cout << i;
    }
};

// Since `FooFunctor` defines `operator()`, it can be used as a function
FooFunctor func;
std::function<void (int)> f(func);


Also std::bind and std::function together are a very powerful tool and this is what really makes me favor std::function over function pointers. Lets say you have a function and you want to always have a fixed argument it passes the function. Well std::bind comes to your rescue. For example.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <functional>
#include <cmath>


int main()
{
    using namespace std::placeholders;

    // I'm using the pow function from cmath for this.

    // Notice how we always use a a certain number for the exponent and only need to enter the number when the std::function
    // object is called.
    std::function<long long(int)> powerOfTwo = std::bind(pow, _1, 2);
    std::function<long long(int)> powerOfThree = std::bind(pow, _1, 3);
    auto powerOfFour = std::bind(pow, _1, 4);

    // Of course we could always ask for both parameters when we call the std::function object to.
    std::function<long long(int, int)> powerOfWhatever = std::bind(pow, _1, _2);

    std::cout << powerOfTwo(10) << std::endl;
    std::cout << powerOfThree(10) << std::endl;
    std::cout << powerOfFour(10) << std::endl;
    std::cout << powerOfWhatever(5, 5) << std::endl;
}


I find them much more versatile then function pointers and easier to work with personally. I also much prefer the C++ syntax of std::function and std::bind over the C syntax of function pointers. But that is just a personal preference I guess.

I am still quite new to the functional header myself so this is just all from my experience. I am sure one of the more experienced members might be able to clear it up a bit more also.
so <functional> can handle function object...
and bind can change parameters order and default parameter value
it seems to be useful now...

@Zereo & @fun2code
Thanks for the explanation


Now I am trying to tackle more problem

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class P {
public:
    typedef void (P::*P_pmf_t)();

    P(){
        updatef = &P::go;
        setState( &P::go );
    }

    void setState( P_pmf_t Func ){
        updateF = bind( Func, *this );
    }

    void go(){ cout << "GO\n"; }
    void run(){ cout << "RUN\n"; }
    void attack(){ cout << "ATTACK\n"; }
    void update(){
        (this->*updatef) ();
        updateF();
    }

private:
    P_pmf_t updatef;
    function<void()> updateF;

};


I want a setState function to take
P::go
instead of
&P::go


I am guessing macro will do
1
2
3
#define setState( X ) { \
   updateF = bind(&X, *this); \
} 


but the thing is,
many people just said macro is not for C++

any suggestion on how to do this without macro ?
Topic archived. No new replies allowed.