Changes

Jump to: navigation, search

State

12,429 bytes added, 23:39, 12 April 2007
References
== Code Samples ==
[http://matrix.senecac.on.ca/~rmwang/btppresentation/statesample.html Click here to see the UML diagram for this example]
=== Greeting Message Generator === '''[http://matrix.senecac.on.ca/~rmwang/btppresentation/sunsample.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; }  public void SetCurrentLevel(int level) { currentState.CurrentLevel = level; } }}</PRE>
== References ==
<ul>
<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>
 
== Links ==
[[BTP600]]
1
edit

Navigation menu