22 Ağustos 2017 Salı

Gömülü Proje - Finite State Machine

FSM
Bu sınıfları tasarlarken iki tane daha önce yaptığım projeden faydalandım.

İlk projede FSM sadece dışarıdan gelen mesajlarla tetikleniyordu. Her state gelen mesajı işlerken bir sonraki state'i bir enum olarak dönüyordu. FSM bir sonraki state current state değerinden farklı ise bir sonraki state'e geçebiliyordu.

Aşağıdaki örnekte biraz daha farklı bir durum var. State'ler içinde timer'lar çalıştırmak gerekiyordu. Bu yüzden State kendi kendine FSM'yi tetikleyerek başka State'e geç emri verebiliyor. Dolayısıyla
State <-->> FSM
şeklinde çift yönlü bir ilişki var

1. Context Sınıfı
FSM'nin çalışması için gerekli bilgileri saklar.

2. BaseState Sınıfı
Bu sınıf std::enable_shared_from_this sınıfından kalıtır. Böylece Bir state FSM'yi başka state'e geçmek için tetikleyince nesnemiz yaşamaya devam edebilir.

m_pFSMPtr Alanı
FSM ile olan çift yönlü ilişki. Bir State FSM'nin başka bir State'e geçmesini istiyorsa önce
auto pState = shared_from_this ();
ile kendinin silinmemesini sağlar.Daha sonra
m_FSMPtr->gotoXState ();
şeklinde bir metod çağrı yapar.

onEnter metodu
Her state ilk girişte yapacağı şeyleri onEnter () metodu içinde yapar. State'ten çıkarken yapılacak işler onExit() metodunda yapar diye düşünmüştük anca bu metoda ihtiyaç olmadı.

setContext metodu
State yaratılırken context nesnesi atanır.

processMessage metodu
Bu metod bir template. Dışarıdan gelen mesajları kalıtan State nesnelerine geçmek için kullanlır. İçin şöyledir.
template <class T>
void processMessage (const T& msg)
{
  processInternal (msg)
}
Bu template metodu şöyle iç metodlara dağıtım yapar.
virtual processInternal (const A& msg)
{
}
virtual processInternal (const B& msg)
{
}

Bu metodlar boştur. Böylece sadece  mesaj ile ilgilenen State gerekli metodu override eder.

3. FSM Sınıfı
Bu sınfın gotoStateA (); gotoStateB () gibi metodları vardır. Bu metodlar çağrılınca
1. m_CurrentState enum değişkeni güncellenir.
2. Eski State nesnesinin onExit() metodu çağrılır.
3. Yeni State nesnesi yaratılır ve onEnter() metodu çağrılır. onEnter metodu en son çağrılan şey olmalı yoksa bir State hemen bir başka State'e geçişi tetiklerse ortalık karışabilir.

isXState metodu
FSM sınıfı dışarından hangi state içinde olduğunun sorgulanabilmesi için isXState() gibi metodlar sunar.

processMessage metodu
Şöyledir
template <class T>
void processMessage (const T& msg)
{
  m_pCurrentState->processMessage (msg)
}



Hiç yorum yok:

Yorum Gönder