Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

State Machine implementations

[es] :: C/C++ programiranje :: State Machine implementations

[ Pregleda: 2028 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
*.dynamic.sbb.rs.

ICQ: 208550327


+14 Profil

icon State Machine implementations14.08.2010. u 14:42 - pre 166 meseci
State Machine je zanimljiv i veoma koristan, ako se tako moze reci, design pattern.

Pre nekoliko godina sam naucio nacin implementiranja state masine 'od nule' putem nasledjivanja ( koristio sam je u svojoj video igri )

Evo primera:

Code:

class Actor;
class State;

class Actor
{
public:
       void changeState(State * pState)
        {
             if(m_pCurrentState)
             {
                     m_pCurrentState->exit(this);
                     m_pCurrentState = pState;
                     m_pCurrentState->enter(this);
             }
         }

         void update(float dt)
         {
               m_pCurrentState->update(this, dt);
         }

         State * m_pCurrentState;
}

class State
{
public:
        virtual void enter(Actor * pActor);
        virtual void update(Actor * pActor);
        virtual void exit(Actor * pActor);
};


class MainPlayerStandingState; 

class MainPlayerMoveState : public State
{
public:
        virtual void enter(Actor * pActor)
        {
               pActor->setVelocity(2);    
        }
        virtual void update(Actor * pActor, float dt)
        {
               pActor->move(dt);

              if(pActor->pos < 0)
              {
                   pActor->changeState(MainPlayerStandingState::instance());
              }
        }
        virtual void exit(Actor * pActor)
        { 
              pActor->setVelocity(0);
        }

        static MainPlayerMoveState & instance()
        {  
                static MainPlayerMoveState state;
                return state;
        }
};


Meni se ovaj pristup dopada, naravno, mana je sto za svaki objekat i za svaki state objekta treba napraviti novu klasu ali to se da resiti skriptovanjem :)


Vidim da boost nudi state_chart, drugaciji pristup implementiranja state machine ali me odbija kompleksnost koda i, posebno, otkrivanje gresaka ( verovatno zato sto ne poznajem dovoljno templates ali planiram da ih izucim ).

Takodje, u boostu postoje events, transitions.

Posto ja zelim da koristim prethodno navedeni nacin implementacije state machine a ne sa boost, zanima me kako se moze unaprediti postojeci kod da koristi te evente, transitions, ako su mi uopste potrebni. Ako nije dovoljno jasno, mogu uploadovati primer da se bolje razume.

Verovatno postoji jos mnogo biblioteka koje nude state machine funkcionalnost ali bih ja voleo da se napravi funkcionalnost na ovaj nacin i da se sve to spakuje u biblioteku koju mozemo svi koristiti :)

Problem sa gomilanjem klasa se moze resiti integrisanjem Lua ili bilo kog script jezika u biblioteku. Mislim da je ovo jednostavan i elegantan nacin da se dobije mocna funkcionalnost state machine.
EOF
 
Odgovor na temu

mmix
Miljan Mitrović
Profesorkin muz
Passau, Deutschland

SuperModerator
Član broj: 17944
Poruke: 6042



+4631 Profil

icon Re: State Machine implementations14.08.2010. u 14:55 - pre 166 meseci
Iskreno, meni je ovo jedan od glupljih paterna. Svaki objekat koji ima bar jedno polje je state masina, emulirati state masinu preko necega sto je vec ocigledno state masina je, meni bar, kompletno izivljavanje. Gore i od MVCa
Sloba je za 12 godina promenio antropološki kod srpskog naroda. On je od jednog naroda koji je bio veseo, pomalo površan, od jednog naroda koji je bio znatiželjan, koji je voleo da vidi, da putuje, da upozna,
od naroda koji je bio kosmopolitski napravio narod koji je namršten, mrzovoljan, sumnjicav, zaplašen, narod koji se stalno nešto žali, kome je stalno neko kriv… - Z.Đinđić
 
Odgovor na temu

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
*.dynamic.sbb.rs.

ICQ: 208550327


+14 Profil

icon Re: State Machine implementations14.08.2010. u 15:00 - pre 166 meseci
Nisam te bas razumeo.
Meni je ovaja nacin dosta pomogao posto sam se gubio sa switch naredbama. Ovako, svaki state je zaseban i nezavisan i lako se odrzava.

Mozda bi mogao preciznije da mi odgovoris u cemu je problem kod ovog pristupa ili da das neku bolju ideju :)

EOF
 
Odgovor na temu

1jedini
Dejan Milosavljevic
BG

Član broj: 102721
Poruke: 74
91.185.102.*



Profil

icon Re: State Machine implementations15.08.2010. u 12:31 - pre 166 meseci
Ako ti ne smeta da dodas jos jedan podatak tipa int koji ce da numerise stanje onda mozes i ovako.

Ovo bi bio neki najspecijalniji slucaj, ili poznat pod imenom DFA.

Code:

int trenutno_stanje = 0;
std::vector< std::vector< std::pair<int, void (*)( /*parametri*/ ) >  > > tablica;

void odradi( int ulaz ) 
 {
  tablica[trenutno_stanje][ulaz].second( /*parametri*/);

  trenutno_stanje = tablica[trenutnostanje][ulaz].first;
 }


Opsti slucaj:

Code:

int trenutno_stanje = 0;
std::vector< std::vector< int (*)( /*parametri*/ ) > > tablica;

void odradi( int ulaz ) 
 {
  trenutno_stanje = tablica[trenutno_stanje][ulaz]( /*parametri*/);
 }

AKA DDMM
 
Odgovor na temu

VladimirCDT
VladimirCDT
programer
Beograd

Član broj: 220281
Poruke: 45
*.cpe.vektor.net.



+2 Profil

icon Re: State Machine implementations17.08.2010. u 08:30 - pre 166 meseci
@glorius

Ja sam odvjec star da bih te savjetovao, ali pocuj ono sto cu ti reci...

State machine je toliko opsta, a sama stanja mogu od slucaja do slucaja da idu od prostih tipova (neki celobrojni podatak) do slozenih struktura, da je neko zatvaranje u biblioteku nesvsishodno. Slicno vazi i za tranzicije izmedju raznih stanja.

Primera radi, u jednom proizvodu jedne velike kompanije, covek koji je pisao kod, realizovao je state machine samo kroz enum-e. Pravila tranzicije nisu postojala kao takva jer su vrlo linearna i svela su se na par if-else blokova unutar nekih drugih metoda. Sama stanja, dakle oni enumi, su bili podatak pridruzen drugoj klasi objekata koja je prolazila kroz nekakav ciklus obrade. Covek koji je pisao taj kod nije neki autolimar, vec vrlo iskusan programer, koji je sada glavni arhitekta u delu kompanije koji razvija doticni proizvod.

Dakle, u zavisnosti od konkretnog problema mozes tu state machine da implementiras na razlicite nacine. Tvoj cilj je da implementacija bude jednostavna, robustna i da se brzo izvrsava.

U java svetu mozes videti da se prave frameworks za sve i svasta i to je u izvesnom broju slucajeva obicno teska glupost koja nigde ne vodi i moze samo da predstavlja bespotrebno usloznjavanje, usporenje i uopste komplikaciju.

Savetujem ti takodje, ako koristis C++, da savladas template-e sto pre. Neverovatno koliko su korisni i kako umeju da ti pruze elegantna i zaista dobra resenja cak i u nekim vrlo nezgodnim situacijama.
 
Odgovor na temu

glorius
Damir Nikolic
C++ developer
SR

Član broj: 4366
Poruke: 428
*.dynamic.sbb.rs.

ICQ: 208550327


+14 Profil

icon Re: State Machine implementations17.08.2010. u 19:30 - pre 166 meseci
Citat:


Dakle, u zavisnosti od konkretnog problema mozes tu state machine da implementiras na razlicite nacine. Tvoj cilj je da implementacija bude jednostavna, robustna i da se brzo izvrsava.



Ovo je, otprilike, i bila ideja. Zelim da napravim genericku state machine koja ce funkcionisati kao boost-ova ali da se ne koriste templates vec preko nasledjivanja. To bi verovatno evoluiralo u neki slozeniji sistem sa ciljem da se poveca fleksibilnost.

Samo da napomenem da mi templates nisu veliki problem. Izucio sam Modern C++ design i Loki biblioteku pa se snalazim. Tako da mi ne smeta da koristim boost-ov state chart ali sam mislio da to implementiram na drugi nacin.

Na ideju sam dosao kada sam pravio platformu u kojoj player ima razlicite state-ove. APPEARING, STANDING, MOVING, RUNNING, SHOOTING, DUCKING, JUMPING, DIEING...

Verujem da je ovo primer enumeracije state-ova koji si spominjao, mada se ja nisam snasao kao doticni ne-autolimar :)))

Radeci na taj nacin ( if/else, switch) dosao sam u state :) u kojem vise nisam mogao da se snadjem u kodu... Onda sam naisao na onaj pristup koji sam objasnio na pocetku teme i to mi je dosta pomoglo da kontrolisem ceo sistem. Tako da me sada zbunjuju ovi odgovori jer ne razumem sta je to lose u ovom pristupu.

Citat:

State machine je toliko opsta, a sama stanja mogu od slucaja do slucaja da idu od prostih tipova (neki celobrojni podatak) do slozenih struktura, da je neko zatvaranje u biblioteku nesvsishodno. Slicno vazi i za tranzicije izmedju raznih stanja.


Po meni, stanje bi moglo biti opisano prostom promenljivom ( koja bi mogla biti i kombinacija stanja , npr. JUMPING | SHOOTING ). Nisam naisao na neki primer gde je stanje opisano slozenom strukturom podataka, tako da bi neki primer pomogao da bolje shvatim.






EOF
 
Odgovor na temu

VladimirCDT
VladimirCDT
programer
Beograd

Član broj: 220281
Poruke: 45
*.cpe.vektor.net.



+2 Profil

icon Re: State Machine implementations19.08.2010. u 00:12 - pre 166 meseci
@glorius

Hajde da krene s kraja...

Sto se tice primera gde bi stanje bilo opisano slozenom strukturom, ne mogu sada da se setim konkretnog primera da je tako implementirano, ali evo necega sto bi moglo da se posmatra na taj nacin.

Na primer, prozori. Neki prozor moze biti minimizovan, maximizovan ili da ima neku normalnu velicinu. To bi bio jedan parametar stanja prozora. Drugi parametar bi se odnosi na to da li je prozor aktivan, tj. da li je fokus na njemu, ili je neaktivan. Mogli bismo da uvedemo i treci parametar koji bi govorio nesto tipa: running, waiting for user action, not responding. Dakle, imamo (ne tako slozenu) strukturu od 3 parametra koji govore o stanju prozora. Pri svemu tome, postoje medjuzavisnosti izmedju ovih stanja i pojedine akcije korisnika dovesce do promene nekada ne samo jednog, vec vise "podstanja", u zavosnosti od prethodnog stanja.
Dakle, ti bi u ovom slucaju mogao sva tri parametra da strpas u jednu klasu koja bi opisala stanje prozora.
E sad, zamisli da je jedan od ovih parametara takodje neki slozeniji objekat.

Sta je lose u pristupu ?
Samo po sebi, nista. Medjutim, stvar je u tome da nesto sto je relativno jednostavno, trpas u klase, dalje usloznjavas nasledjivanjem i uopsteno, gradis citav sistem klasa gde to nije potrebno. Tacno, to sve deluje elegantno, u slozenim slucajevima je cak i nuzno. Sve ove genericke biblioteke koje se bave ovim problem uopsteno, verovatno ima smisla koristiti u nekim slozenijim slucajevima, dok bi kod jednostavnih i linearnih modela predstavljale overkill.

U tvom konkretnom primeru, mozda je zaista postojala nuzda da se poteze neki sistem klasa. Medjutim, pre nego se pribegne koriscenju nekog gotovog resenja za konkretan problem, valja razmisliti da li to resenje unosi bespotrebnu kompleksnost, previse koda, da li lose utice na performanse. Da li postoji jednostavnije resenje ?
Da li je u onom tvom slucaju sve moralo da ide preko nekog switcha ili kompleksnih if/else blokova ?

Bez obzira sto je jedno od prvih pravila u softverskom inzenjeringu da se ne pravi ponovo ono sto je vec neko odradio, tom pravilu ne treba pristupati slepo, vec razmisliti nad problemom i proceniti da li je nekada bolje pisati neko konkretno resenje od pocetka.

Ja sam u svojoj praksi vec video slucajeve pogresnih izbora da se koristi neko gotovo resenje. U jednom slucaju je bila u pitanju biblioteka koja jeste skratila posao u pocetku, ali je tako ubila performanse sistema da ovaj nije mogao da ispuni projektni zahtev (maximalni broj opsluzenih embeded uredjaja). Drugi slucaj je bio izbor pogresnog paterna u service oriented arhitekturi: taj izbor gotovog paterna je doveo do eksplozije ogromnog broja identicnih (copy/paste) klasa, sto je ucinilo kod neodrzivim.
Sa druge strane, bas onaj, vec pomenuti ne-autolimar, je u jednom dokumentu, obrazlazuci svoje projektne odluke, na jednom mestu izneo odluku da umesto koriscenja gotovog resenja, sam napise novo, prilagodjeno datoj situaciji. Njegova procena da ce ga pisanje resenja manje kostati i dati bolje rezultate od koriscenja gotovog, bila je veoma tacna.

U principu, a to ne vazi samo za ovaj slucaj, o svakom paternu razmisli da li je dovoljno dobar za tvoj slucaj, da li mozes da smislis bolje resenje. Budi kreativan.
 
Odgovor na temu

[es] :: C/C++ programiranje :: State Machine implementations

[ Pregleda: 2028 | Odgovora: 6 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.