SFML community forums

Help => General => Topic started by: ElysianShadow on June 29, 2014, 10:48:40 pm

Title: State Machine Question
Post by: ElysianShadow on June 29, 2014, 10:48:40 pm
So reading through the SFML book, I came across some code regarding the Finite State Machine that I do not comprehend. I understand that what I am about to ask may be a C++ question and not necessarily an SFML question but I couldn't find any helpful resources online anywhere that would better my understanding.

My question is in regards to these bits of code:


// StateStack.hpp

typedef std::unique_ptr< State > StatePtr;

class StateStack
{
     //.....

     std::map< States::ID, std::function< State::StatePtr() > > m_factories;
};

template< typename T >
void StateStack::registerState( States::ID )
{
     m_factories[ id ] = [ this ] () { return State::StatePtr( new T(*this, m_context ) ); };
}

 


//StateStack.cpp

State::StatePtr StateStack::createState( States::ID id )
{
     auto found = m_factories.find( id );
     
     assert( found != m_factories.end() );

     return found -> second();
}

 

I guess you could say I'm wondering why std::function is used inside of the m_factories map instead of just say, an std::unique_ptr< State > ? Would it not be possible to use that method and store a new smart pointer in the registerState() method, then just return the smart pointer stored in there by reference in the createState() method? Or is there a specific reason as to why using std::function is more effective? Also I thought that std::function was to be used with functors or functions? Does this mean that a unique_ptr can be used as one of those?

Again sorry if this is more of a C++ question but seeing as it's part of an SFML project I thought I could get some help here. Thanks
Title: Re: State Machine Question
Post by: Nexus on June 30, 2014, 12:29:35 am
As implied by the name, those are factories. The Factory design pattern is used to give an object the responsibility of constructing another object. Like this, we can construct states exactly when we need them, and not before. It also allows us to abstract construction details from the state stack.
Title: Re: State Machine Question
Post by: ElysianShadow on June 30, 2014, 02:44:42 am
I guess what I'm wondering is whether or not it would be perfectly fine to do something like this instead:


     m_factories[ id ] = std::move( State::StatePtr state( new T( *this, m_context ) ) );

 
Title: Re: State Machine Question
Post by: Nexus on June 30, 2014, 07:58:40 am
Then you would construct the state at the time of registering, not at the time you want to create it. Why construct states that are possibly never needed and keep them in memory all the time?

Besides, std::move() isn't necessary if you have temporary (RValue) expressions.