Търся някакъв генерал
- Оптимизация
- Коректност
- Разширяемост
съвет относно моето текущо внедряване на C++ Hierarchical State Machine.
проба
variable isMicOn = false
variable areSpeakersOn = false
variable stream = false
state recording
{
//override block for state recording
isMicOn = true //here, only isMicOn is true
//end override block for state recording
}
state playback
{
//override block for state playback
areSpeakersOn = true //here, only areSpeakersOn = true
//end override block for state playback
state alsoStreamToRemoteIp
{
//override block for state alsoStreamToRemoteIp
stream = true //here, both areSpeakersOn = true and stream = true
//end override block for state alsoStreamToRemoteIp
}
}
goToState(recording)
goToState(playback)
goToState(playback.alsoStreamToRemoteIp)
Внедряване
Понастоящем HSM се изпълнява като дървовидна структура, където всяко състояние може да има променлив брой състояния като деца.
Всяко състояние съдържа променлив брой блокове за "замяна" (в std::map), които заменят базовите стойности. В основното състояние машината на състоянието има набор от променливи (функции, свойства...), инициализирани на някои стойности по подразбиране. Всеки път, когато влизаме в дъщерно състояние, списък с "замени" дефинира променлива и стойности, които трябва да заменят променливите и стойностите със същото име в родителското състояние. Актуализиран оригинал за яснота.
Рефериране на променливи
По време на изпълнение текущите състояния се съхраняват в стек.
Всеки път, когато се препраща към променлива, се извършва низходящ стек в търсене на най-високата отмяна или в случай на липса на отмяна, стойността по подразбиране.
Превключване на състояния
Всеки път, когато се превключи към рамка на едно състояние, състоянието се избутва в стека.
Всеки път, когато се превключи към състояние, аз проследявам низходящо дърво, което ме отвежда от текущото състояние до основното състояние. След това правя дървовидно слизане от целевото състояние до основното състояние, докато видя, че текущата следа съвпада с предишната. Декларирам пресечна точка, където се срещат тези 2 следи. След това, за да превключа към целевото състояние, се спускам от източника, изваждайки рамки на състоянието от стека, докато стигна до пресечната точка. След това се изкачвам до целевия възел и избутвам рамки на състоянието върху стека.
Така че за примерния код по-горе
Проследяване на изпълнение за превключване на състояние
- Състояние на източника = запис
Целево състояние = alsoStreamToRemoteIp
спускане от източник = запис->корен (следа = [корен])
слизане от target = alsoStreamToRemoteIp->playback->root (trace = [playback, root])
Пресича се в корена.
За да превключите от запис към също StreamToRemoteIp,
- Извадете "запис" от стека (и извикайте неговата функция за изход... не е дефинирана тук).
- Натиснете "възпроизвеждане" върху стека (и извикайте функцията за въвеждане).
- Натиснете "alsoStreamToRemoteIp" в стека (и извикайте функцията enter).