Changes

Jump to: navigation, search

State

12,281 bytes added, 23:39, 12 April 2007
References
== Code Samples ==
 === Greeting Message Generator === '''[http://matrix.senecac.on.ca/~rmwang/btppresentation/statesamplesunsample.html Click here to see the UML diagram for this example]''' '''State class interface definition'''<pre>class CBaseState{public: virtual CBaseState* GetNextState() = 0; virtual char* ToString() = 0;};</pre>'''Concrete class definitions'''
<pre>
class CMorning : public CBaseState{
public:
virtual CBaseState* GetNextState();
virtual char* ToString();
};
class CEvening : public CBaseState{
public:
virtual CBaseState* GetNextState();
virtual char* ToString();
};
 
class CNight: public CBaseState{
public:
virtual CBaseState* GetNextState();
virtual char* ToString();
};
</pre>
'''Context class structure'''
<pre>
class CSun{
public:
CSun();
CSun(CBaseState* pContext);
~CSun();
void StateChanged();
char* GetStateName();
protected:
void DoCleanUp();
CBaseState* m_pState;
};
</pre>
'''Function definition for state change'''
<pre>
void CSun::StateChanged(){
if (m_pState){
CBaseState* pState = m_pState->GetNextState();
delete m_pState;
m_pState = pState;
}
}
</pre>
'''Code that changes state'''
<pre>
CBaseState* CMorning::GetNextState(){return new CEvening;}
CBaseState* CEvening::GetNextState(){return new CNight;}
CBaseState* CNight::GetNextState(){return new CMorning;}
</pre>
'''Simple example of actual implementation'''
<pre>
CSun objSun(new CMorning);
printf("\n\nSun Says Good %s !!!",objSun.GetStateName());
objSun.StateChanged();
printf("\n\nSun Says Good %s !!!",objSun.GetStateName());
objSun.StateChanged();
printf("\n\nSun Says Good %s !!!",objSun.GetStateName());
objSun.StateChanged();
printf("\n\nSun Says Good %s !!!",objSun.GetStateName());
</pre>
=== Game programming: Character Status ===
'''[http://matrix.senecac.on.ca/~rmwang/btppresentation/statesample.html Click here to see the UML diagram for this example]'''
 
<br />
'''Header File Content'''
<pre>
class IState;
class cDarkElf : public cUnit {
IState* _pState;
void ChangeState(IState*);
public:
cDarkElf();
~cDarkElf();
void Attack(cUnit* Target);
void Move(int x, int y);
void Stop();
void HoldPosition();
void Slaughter(cUnit* Target);
void Update();
};
</pre>
'''Class Definitions for State objects'''
<pre>
class IState {
const ID_STATE _ID;
public:
enum ID_STATE {STATE_ATTACK, STATE_MOVE, STATE_STOP,
STATE_HOLDPOSITION, STATE_SLAUGHTER};
IState(ID_STATE state) : _ID(state) {}
ID_STATE GetID() {return _ID;}
virtual void Operate() = 0;
};
 
class cState_Attack : public IState {
cUnit* _pTarget;
cUnit* _pUnit;
public:
cState_Attack(cUnit* target, cUnit* pUnit) :
IState(STATE_ATTACK), _pTarget(target), _pUnit(pUnit){}
void Operate();
};
 
class cState_Move : public IState {
int _x, _y;
cUnit* _pUnit;
public:
cState_Move(int x, int y, cUnit* pUnit);
void Operate();
};
 
class cState_Stop : public IState {
public:
void Operate();
};
 
class cState_HoldPosition : public IState {
public:
void Operate();
};
 
class cState_SLAUGHTER : public IState {
cUnit* _pTarget;
cUnit* _pUnit;
public:
cState_Slaughter(cUnit* target, cUnit* pUnit) :
IState(STATE_SLAUGHTER), _pTarget(target),
_pUnit(pUnit) {}
void Operate();
};
</pre>
'''Functions that changes character status'''
<pre>
cDarkElf::cDarkElf() {_pState = new cState_Stop;}
 
cDarkElf::~cDarkElf() {delete _pState;}
 
void cDarkElf::ChangeState(IState* pState) {
delete _pState;
_pState = pState;
}
void cDarkElf::Attack(cUnit* Target) {
ChangeState(new cState_Attack(Target, this));
}
void cDarkElf::Move(int x, int y) {
ChangeState(new cState_Move(x, y, this));
}
void cDarkElf::Stop() {
ChangeState(new cState_Stop);
}
 
void cDarkElf::HoldPosition() {
ChangeState(new cState_HoldPosition);
}
 
void cDarkElf::Patrol(int x1, int y1, int x2, int y2) {
ChangeState(new cState_Patrol(x1, y1, x2, y2));
}
 
void cDarkElf::Update() {
_pState->Operate();
}
</pre>
 
=== State Pattern Example: C# ===
'''Abstract Class'''
<pre>
using System;
using System.Drawing;
 
namespace StatePatternApp
{
public abstract class State
{
public State()
{
}
public State(State state)
{
this.CurrentLevel = state.CurrentLevel;
this.Deviation = state.Deviation;
this.MaxLevel = state.MaxLevel;
this.MinLevel = state.MinLevel;
this.Machine = state.Machine;
this.SetParams();
}
public State(Machine machine, int iCurrentLevel,
int iDeviation, int iMaxLevel, int iMinLevel)
{
this.CurrentLevel = iCurrentLevel;
this.Deviation = iDeviation;
this.MaxLevel = iMaxLevel;
this.MinLevel = iMinLevel;
this.Machine = machine;
this.SetParams();
}
private Machine machine;
private int minLevel = 0;
private int maxLevel = 0;
private int currentLevel = 0;
private int deviation = 0;
private Color messageColor = Color.Green;
private string messageText = "";
public virtual void SetParams(){}
public virtual void CheckEfficiency()
{
Transition t = Transition.GetInstance();
t.Transform(this);
}
 
protected virtual void ChangeState(Machine m, State s)
{
m.ChangeState(s);
}
 
public Machine Machine
{
get
{
return this.machine;
}
set
{
this.machine = value;
}
}
public int MinLevel
{
get
{
return this.minLevel;
}
set
{
this.minLevel = value;
}
}
 
public int MaxLevel
{
get
{
return this.maxLevel;
}
set
{
this.maxLevel = value;
}
}
 
public int CurrentLevel
{
get
{
return this.currentLevel;
}
set
{
this.currentLevel = value;
// Is the machine value set?
if(this.Machine != null)
{
this.CheckEfficiency();
}
}
}
 
public int Deviation
{
get
{
return this.deviation;
}
set
{
this.deviation = value;
}
}
 
public int MaxDeviaton
{
get
{
return this.MaxLevel - this.Deviation;
}
}
 
public int MinDeviaton
{
get
{
return this.MinLevel + this.Deviation;
}
}
 
public Color MessageColor
{
get
{
return this.messageColor;
}
set
{
this.messageColor = value;
}
}
 
public string MessageText
{
get
{
return this.messageText;
}
set
{
this.messageText = value;
}
}
}
}
</pre>
'''Transition class'''
<PRE>
using System;
 
namespace StatePatternApp
{
class Transition
{
private static Transition getInstance;
protected Transition() {}
 
public static Transition GetInstance()
{
if(getInstance == null)
{
getInstance = new Transition();
}
return getInstance;
}
 
public void Transform(State state)
{
if(state == null)
{
return;
}
 
// Get the type of state.
string stateType = state.GetType().Name;
 
// Are we in normal state?
if(state.CurrentLevel < state.MaxDeviaton &&
state.CurrentLevel > state.MinDeviaton)
{
if(stateType.ToUpper() != "NORMALSTATE")
{
state.ChangeState(state.Machine,
new NormalState(state));
}
}
// Are we in warning?
if(state.Deviation > 0)
{
if((state.CurrentLevel < state.MaxLevel &&
state.CurrentLevel >= state.MaxDeviaton) ||
state.CurrentLevel > state.MinLevel &&
state.CurrentLevel <= state.MinDeviaton)
{
if(stateType.ToUpper() != "WARNINGSTATE")
{
state.ChangeState(state.Machine,
new WarningState(state));
}
}
}
// Are we in alert state?
if(state.CurrentLevel >= state.MaxLevel ||
state.CurrentLevel <= state.MinLevel)
{
if(stateType.ToUpper() != "ALERTSTATE")
{
state.ChangeState(state.Machine,
new AlertState(state));
}
}
}
}
}
</PRE>
'''NormalState - derived state class'''
<PRE>using System;
using System.Drawing;
 
namespace StatePatternApp
{
public class NormalState : State
{
public NormalState(State state) : base(state)
{
}
 
public NormalState(Machine machine, int iCurrentLevel,
int iDeviation, int iMaxLevel, int iMinLevel) :
base(machine, iCurrentLevel, iDeviation,
iMaxLevel, iMinLevel)
{
}
 
public override void SetParams()
{
this.MessageColor = Color.Green;
this.MessageText = "Normal";
}
}
}</PRE>
'''WarningState - derived state class'''
<PRE>using System;
using System.Drawing;
 
namespace StatePatternApp
{
public class WarningState : State
{
public WarningState(State state) : base(state)
{
}
 
public WarningState(Machine machine, int iCurrentLevel,
int iDeviation, int iMaxLevel, int iMinLevel) :
base(machine, iCurrentLevel, iDeviation, iMaxLevel,
iMinLevel)
{
}
 
public override void SetParams()
{
this.MessageColor = Color.Yellow;
this.MessageText = "Warning";
}
}
}</PRE>
'''AlertState - derived state class'''
<PRE>using System;
using System.Drawing;
 
namespace StatePatternApp
{
public class AlertState : State
{
public AlertState(State state) : base(state)
{
}
 
public AlertState(Machine machine, int iCurrentLevel,
int iDeviation, int iMaxLevel, int iMinLevel) :
base(machine, iCurrentLevel, iDeviation, iMaxLevel,
iMinLevel)
{
}
 
public override void SetParams()
{
this.MessageColor = Color.Red;
this.MessageText = "Alert";
}
}
}</PRE>
'''Machine class - This class maintains an instance of state'''
<PRE lang=cs id=pre5 style="MARGIN-TOP: 0px">using System;
 
namespace StatePatternApp
{
public class Machine
{
public State currentState;
 
public Machine(int iCurrentLevel, int iDeviation,
int iMaxLevel, int iMinLevel)
{
currentState = new NormalState(this, iCurrentLevel,
iDeviation, iMaxLevel, iMinLevel);
currentState.CheckEfficiency();
}
 
public void ChangeState(State setState)
{
currentState = setState;
}
[http://matrix.senecac public void SetCurrentLevel(int level) { currentState.on.caCurrentLevel = level; } }}</~rmwang/btppresentation/sunsample.html Click here to see the UML diagram for this example]PRE>
== References ==
<li>Erich, Gamma. Design Patterns : elements of reusable object-oriented software. Upper Saddle River: Pearson Education Corporate Sales Division, 2000.</li>
<li>"4th Lecture about Design Patterns". Ssamdark's Homepage. March 20, 2007 <http://www.misofruit.co.kr/seojewoo/programming/designpattern4.htm>.
</li>
<li>Young, Kenny. "C# - State Pattern Example". The Code Project. April 2nd, 2007 <http://www.codeproject.com/cs/design/statepatterncsharp.asp>.
</li>
</ul>
1
edit

Navigation menu