Comunicazione tra macchina di stato e GUI

4

Sto scrivendo una macchina a stati finiti in C ++, progettata come una libreria. Inoltre, ho una GUI implementata come progetto separato che ha bisogno di aggiornare l'interfaccia utente in base ai cambiamenti di stato che si verificano nella libreria.

Il modo in cui implemento la comunicazione ora è che la GUI sta chiamando una funzione di libreria che restituisce una struttura contenente informazioni sullo stato della macchina a stati finiti (e altre informazioni necessarie).

Ma trovo questa soluzione piuttosto ad hoc e dato che sembra una situazione frequente, sono curioso di sapere se esiste un modello di design / libro di testo per gestirlo.

    
posta user695652 23.06.2015 - 17:53
fonte

3 risposte

5

Il metodo più semplice è passare una funzione di callback alla macchina a stati che viene chiamata quando uno stato cambia (o accade un altro evento).

Quindi quando viene chiamato puoi aggiornare il gui in quella funzione (o inoltrare il messaggio al thread gui se la macchina di stato funziona in un thread separato).

La firma sarebbe qualcosa come void callback(State oldstate, State newstate, void* userData)

il puntatore userData viene fornito contemporaneamente al puntatore della funzione e fornisce un contesto per la funzione di callback (statico). Se lo desideri, puoi anche utilizzare std::Function e mantenere il puntatore funzione + metodo userData come sovraccarico.

    
risposta data 23.06.2015 - 17:59
fonte
2

Le librerie della GUI (come ad esempio Qt) utilizzano una sorta di modello di progettazione del sottoscrittore-editore, che è basato su eventi. Ciò significa che su un evento tutti gli abbonati saranno avvisati.

Quindi, in cambio di stato, pubblica l'evento. Ogni oggetto che si è iscritto all'evento, sta per eseguire una richiamata.

    
risposta data 23.06.2015 - 17:58
fonte
2

Penso che Observer Pattern sia una soluzione semplice e pulita per aggiornare la tua GUI.

È un modello di comportamento che ti consente di implementare un evento come un sistema. Manterrà la GUI ben disaccoppiata dalla tua libreria.

Normalmente lo uso in combinazione con un pattern Adapter in altro per disaccoppiare l'implementazione concreta di "aggiornamento" dalla mia Entità principale. In questo modo posso combinare diversi comportamenti di aggiornamento senza dover ereditare da IObserver

link

Il vantaggio rispetto all'implementazione di "callback" sarebbe il seguente:

  • è possibile avere più osservatori che ricevono una notifica, ognuno risponde in modo diverso
  • la classe che ha avviato l'operazione può essere diversa dalla classe che reagisce, implementando così il paradigma model-view-controller.
  • È possibile implementare elenchi diversi per eventi diversi consentendo Gli osservatori scelgono su cosa reagire anche

Puoi ad esempio usarlo per aggiornare la GUI, accedere a un file e qualcos'altro, tutti questi in thread separati

    
risposta data 23.06.2015 - 21:43
fonte

Leggi altre domande sui tag