If I recall correctly the example he used is a turn style. The starting state is locked waiting for the correct amount of change or a ticket. Once the transaction is processed, it triggers a transition to an unlocked state allowing for passage. Once the turn style has been used, the state is then transition to the locked state waiting for the next customer.
There are a couple ways to show this in code:
The boolean
Code: Select all
int main()
{
constexpr int admission = 50 // 50 cents
constexpr int maxRotation = 120 // 120 degrees
bool isLocked = true;
int deposit = 0;
int angle = 0;
while( true )
{
if( isLocked )
{
deposit -= GetAmountDeposited();
if( deposit >= admission )
{
isLocked = false;
UnlockTurnStyle();
MakeChange( std::abs( deposit ) );
continue;
}
}
angle += GetCurrentRotation();
if( angle == 120 || angle == 240 || angle == 360 )
{
angle %= 360;
isLocked = true;
LockTurnStyle();
}
}
}
Code: Select all
int main()
{
enum class TSState
{
Locked, Unlocked
};
TSState tsState = TSState::Locked;
while( true )
{
switch( tsState )
{
case TSState::Locked:
deposit -= GetAmountDeposited();
if( deposit >= admission )
{
tsState = TSState::Unlocked;
UnlockTurnStyle();
MakeChange( std::abs( deposit ) );
}
break;
case TSState::Unlocked:
angle += GetCurrentRotation();
if( angle == 120 || angle == 240 || angle == 360 )
{
angle %= 360;
tsState = TSState::Locked;
LockTurnStyle();
}
break;
}
}
}
Code: Select all
class TSState
{
public:
TSState( class TurnStyle& _turnstyle );
virtual void Do() = 0;
protected:
class TurnStyle& turnstyle;
int deposit = 0;
int angle = 0;
bool isLocked = true;
static constexpr int admission = 50; // 50 cents
static constexpr int maxRotation = 120; // 120 degrees
};
class TurnStyle
{
public:
TurnStyle()
:
m_state( std::make_unique<TSStateLocked>( *this ) )
{}
void Update()
{
m_state->Do();
}
private:
friend class TSStateLocked;
friend class TSStateUnlocked;
int GetAmountDeposited();
void MakeChange( int );
int GetCurrentRotation();
void LockTurnStyle();
void UnlockTurnStyle();
void Transition( std::unique_ptr<TSState> _state )
{
m_state = std::move( _state );
}
private:
std::unique_ptr<TSState> m_state;
};
class TSStateLocked : public TSState
{
public:
void Do() override;
};
class TSStateUnlocked : public TSState
{
public:
void Do() override;
};
TSState::TSState( TurnStyle& _turnstyle )
:
turnstyle( _turnstyle )
{}
void TSStateLocked::Do()
{
deposit -= turnstyle.GetAmountDeposited();
if( deposit >= admission )
{
turnstyle.UnlockTurnStyle();
turnstyle.MakeChange( std::abs( deposit ) );
turnstyle.Transition( std::make_unique<TSStateUnlocked>( turnstyle ) );
}
}
void TSStateUnlocked::Do()
{
angle += GetCurrentRotation();
if( angle == 120 || angle == 240 || angle == 360 )
{
angle %= 360;
turnstyle.LockTurnStyle();
turnstyle.Transition( std::make_unique<TSStateLocked>( turnstyle ) );
}
}
int main()
{
TurnStyle turnstyle;
while( true )
{
turnstyle.Update();
}
return 0;
}
Code: Select all
class TurnStyle;
class TSStateLocked
{
public:
void Do( TurnStyle& _turnstyle );
private:
static constexpr int admission = 50;
int deposit = 0;
};
class TSStateUnlocked
{
public:
void Do( TurnStyle& _turnstyle );
private:
int GetCurrentRotation()const noexcept;
private:
int angle = 0;
};
using TSState = std::variant<TSStateLocked, TSStateUnlocked>;
class TurnStyle
{
public:
TurnStyle()
:
m_state( TSStateLocked{} )
{}
void Update()
{
auto doState = [ this ]( auto& _state ) { _state.Do( *this ); };
std::visit( doState, m_state );
}
private:
friend class TSStateLocked;
friend class TSStateUnlocked;
int GetAmountDeposited();
void MakeChange( int );
int GetCurrentRotation();
void LockTurnStyle();
void UnlockTurnStyle();
template<typename T>
void Transition( T _state )
{
m_state = _state;
}
private:
TSState m_state;
};
void TSStateLocked::Do( TurnStyle& _turnstyle )
{
deposit -= _turnstyle.GetAmountDeposited();
if( deposit >= admission )
{
_turnstyle.UnlockTurnStyle();
_turnstyle.MakeChange( std::abs( deposit ) );
_turnstyle.Transition( TSStateUnlocked() );
}
}
void TSStateUnlocked::Do( TurnStyle& _turnstyle )
{
angle += GetCurrentRotation();
if( angle == 120 || angle == 240 || angle == 360 )
{
angle %= 360;
_turnstyle.LockTurnStyle();
_turnstyle.Transition( TSStateLocked() );
}
}
int main()
{
TurnStyle turnstyle;
while( true )
{
turnstyle.Update();
}
}