// grafcet.cc // buzz - Programme du robot Efrei Robotique I1-I2 2003 // Copyright (C) 2003 Nicolas Schodet // #include "grafcet.h" #include "erreur/erreur.h" Automate::Grafcet *parse_file (const char *filename); namespace Automate { // Pointeur vers l'instance unique du grafcet. Grafcet *Grafcet::m_instance = 0; // Constructeur. Grafcet::Grafcet () { } Grafcet::Grafcet (const char *filename) { Grafcet *g = parse_file (filename); if (!g) throw ErreurFatale ("Impossible de lire le grafcet"); m_grafcet = g->m_grafcet; delete g; } // Destructeur. Grafcet::~Grafcet () { for (vector::iterator i = m_grafcet.begin (); i != m_grafcet.end (); ++i) { switch (i->type) { case etape: delete i->elem.etape; break; case action: delete i->elem.action; break; case receptivite: delete i->elem.receptivite; break; case transition: delete i->elem.transition; break; } } } // Lance l'execution d'un pas, c'est à dire, retourne le plus vite // possible. void Grafcet::run (void) { // Parcours le programme et évalue les receptivitées. int e = 0; // Étape courante. vector::const_iterator i; for (i = m_grafcet.begin (); i != m_grafcet.end ();) { switch (i->type) { case etape: e = i->elem.etape->num; ++i; break; case receptivite: if (m_active_etapes[e] == active && i->elem.receptivite->test ()) { m_active_etapes[e] = stop; for (++i; i != m_grafcet.end () && i->type == transition; ++i) { int g = i->elem.transition->num; m_active_etapes[g > 0 ? g : -g] = g > 0 ? start : stop; } } break; case action: case transition: ++i; break; } } // Arrète les actions en stop. for (i = m_grafcet.begin (); i != m_grafcet.end ();) { if (i->type == etape) { e = i->elem.etape->num; if (m_active_etapes[e] == stop) { for (++i; i != m_grafcet.end () && i->type == action; ++i) i->elem.action->stop (); } m_active_etapes[e] = inactive; } else ++i; } // Initialise les actions pour les etapes en start. for (i = m_grafcet.begin (); i != m_grafcet.end ();) { if (i->type == etape) { e = i->elem.etape->num; if (m_active_etapes[e] == start) { for (++i; i != m_grafcet.end () && i->type == action; ++i) i->elem.action->start (); } m_active_etapes[e] = active; } else ++i; } // Fait fonctionner les actions. for (i = m_grafcet.begin (); i != m_grafcet.end ();) { if (i->type == etape) { e = i->elem.etape->num; if (m_active_etapes[e] == active) { for (++i; i != m_grafcet.end () && i->type == action; ++i) i->elem.action->run (); } } else ++i; } } } // namespace Automate